1 /**************************************************************************** 2 * 3 * gxvmorx5.c 4 * 5 * TrueTypeGX/AAT morx table validation 6 * body for type5 (Contextual Glyph Insertion) subtable. 7 * 8 * Copyright 2005-2018 by 9 * suzuki toshiya, Masatake YAMATO, Red Hat K.K., 10 * David Turner, Robert Wilhelm, and Werner Lemberg. 11 * 12 * This file is part of the FreeType project, and may only be used, 13 * modified, and distributed under the terms of the FreeType project 14 * license, LICENSE.TXT. By continuing to use, modify, or distribute 15 * this file you indicate that you have read the license and 16 * understand and accept it fully. 17 * 18 */ 19 20 /**************************************************************************** 21 * 22 * gxvalid is derived from both gxlayout module and otvalid module. 23 * Development of gxlayout is supported by the Information-technology 24 * Promotion Agency(IPA), Japan. 25 * 26 */ 27 28 29 #include "gxvmorx.h" 30 31 32 /************************************************************************** 33 * 34 * The macro FT_COMPONENT is used in trace mode. It is an implicit 35 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log 36 * messages during execution. 37 */ 38 #undef FT_COMPONENT 39 #define FT_COMPONENT trace_gxvmorx 40 41 42 /* 43 * `morx' subtable type5 (Contextual Glyph Insertion) 44 * has format of a StateTable with insertion-glyph-list 45 * without name. However, the 32bit offset from the head 46 * of subtable to the i-g-l is given after `entryTable', 47 * without variable name specification (the existence of 48 * this offset to the table is different from mort type5). 49 */ 50 51 52 typedef struct GXV_morx_subtable_type5_StateOptRec_ 53 { 54 FT_ULong insertionGlyphList; 55 FT_ULong insertionGlyphList_length; 56 57 } GXV_morx_subtable_type5_StateOptRec, 58 *GXV_morx_subtable_type5_StateOptRecData; 59 60 61 #define GXV_MORX_SUBTABLE_TYPE5_HEADER_SIZE \ 62 ( GXV_STATETABLE_HEADER_SIZE + 4 ) 63 64 65 static void gxv_morx_subtable_type5_insertionGlyphList_load(FT_Bytes table,FT_Bytes limit,GXV_Validator gxvalid)66 gxv_morx_subtable_type5_insertionGlyphList_load( FT_Bytes table, 67 FT_Bytes limit, 68 GXV_Validator gxvalid ) 69 { 70 FT_Bytes p = table; 71 72 GXV_morx_subtable_type5_StateOptRecData optdata = 73 (GXV_morx_subtable_type5_StateOptRecData)gxvalid->xstatetable.optdata; 74 75 76 GXV_LIMIT_CHECK( 4 ); 77 optdata->insertionGlyphList = FT_NEXT_ULONG( p ); 78 } 79 80 81 static void gxv_morx_subtable_type5_subtable_setup(FT_ULong table_size,FT_ULong classTable,FT_ULong stateArray,FT_ULong entryTable,FT_ULong * classTable_length_p,FT_ULong * stateArray_length_p,FT_ULong * entryTable_length_p,GXV_Validator gxvalid)82 gxv_morx_subtable_type5_subtable_setup( FT_ULong table_size, 83 FT_ULong classTable, 84 FT_ULong stateArray, 85 FT_ULong entryTable, 86 FT_ULong* classTable_length_p, 87 FT_ULong* stateArray_length_p, 88 FT_ULong* entryTable_length_p, 89 GXV_Validator gxvalid ) 90 { 91 FT_ULong o[4]; 92 FT_ULong* l[4]; 93 FT_ULong buff[5]; 94 95 GXV_morx_subtable_type5_StateOptRecData optdata = 96 (GXV_morx_subtable_type5_StateOptRecData)gxvalid->xstatetable.optdata; 97 98 99 o[0] = classTable; 100 o[1] = stateArray; 101 o[2] = entryTable; 102 o[3] = optdata->insertionGlyphList; 103 l[0] = classTable_length_p; 104 l[1] = stateArray_length_p; 105 l[2] = entryTable_length_p; 106 l[3] = &(optdata->insertionGlyphList_length); 107 108 gxv_set_length_by_ulong_offset( o, l, buff, 4, table_size, gxvalid ); 109 } 110 111 112 static void gxv_morx_subtable_type5_InsertList_validate(FT_UShort table_index,FT_UShort count,FT_Bytes table,FT_Bytes limit,GXV_Validator gxvalid)113 gxv_morx_subtable_type5_InsertList_validate( FT_UShort table_index, 114 FT_UShort count, 115 FT_Bytes table, 116 FT_Bytes limit, 117 GXV_Validator gxvalid ) 118 { 119 FT_Bytes p = table + table_index * 2; 120 121 122 #ifndef GXV_LOAD_TRACE_VARS 123 GXV_LIMIT_CHECK( count * 2 ); 124 #else 125 while ( p < table + count * 2 + table_index * 2 ) 126 { 127 FT_UShort insert_glyphID; 128 129 130 GXV_LIMIT_CHECK( 2 ); 131 insert_glyphID = FT_NEXT_USHORT( p ); 132 GXV_TRACE(( " 0x%04x", insert_glyphID )); 133 } 134 135 GXV_TRACE(( "\n" )); 136 #endif 137 } 138 139 140 static void gxv_morx_subtable_type5_entry_validate(FT_UShort state,FT_UShort flags,GXV_StateTable_GlyphOffsetCPtr glyphOffset_p,FT_Bytes table,FT_Bytes limit,GXV_Validator gxvalid)141 gxv_morx_subtable_type5_entry_validate( 142 FT_UShort state, 143 FT_UShort flags, 144 GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, 145 FT_Bytes table, 146 FT_Bytes limit, 147 GXV_Validator gxvalid ) 148 { 149 #ifdef GXV_LOAD_UNUSED_VARS 150 FT_Bool setMark; 151 FT_Bool dontAdvance; 152 FT_Bool currentIsKashidaLike; 153 FT_Bool markedIsKashidaLike; 154 FT_Bool currentInsertBefore; 155 FT_Bool markedInsertBefore; 156 #endif 157 FT_Byte currentInsertCount; 158 FT_Byte markedInsertCount; 159 FT_Byte currentInsertList; 160 FT_UShort markedInsertList; 161 162 FT_UNUSED( state ); 163 164 165 #ifdef GXV_LOAD_UNUSED_VARS 166 setMark = FT_BOOL( ( flags >> 15 ) & 1 ); 167 dontAdvance = FT_BOOL( ( flags >> 14 ) & 1 ); 168 currentIsKashidaLike = FT_BOOL( ( flags >> 13 ) & 1 ); 169 markedIsKashidaLike = FT_BOOL( ( flags >> 12 ) & 1 ); 170 currentInsertBefore = FT_BOOL( ( flags >> 11 ) & 1 ); 171 markedInsertBefore = FT_BOOL( ( flags >> 10 ) & 1 ); 172 #endif 173 174 currentInsertCount = (FT_Byte)( ( flags >> 5 ) & 0x1F ); 175 markedInsertCount = (FT_Byte)( flags & 0x001F ); 176 177 currentInsertList = (FT_Byte) ( glyphOffset_p->ul >> 16 ); 178 markedInsertList = (FT_UShort)( glyphOffset_p->ul ); 179 180 if ( currentInsertList && 0 != currentInsertCount ) 181 gxv_morx_subtable_type5_InsertList_validate( currentInsertList, 182 currentInsertCount, 183 table, limit, 184 gxvalid ); 185 186 if ( markedInsertList && 0 != markedInsertCount ) 187 gxv_morx_subtable_type5_InsertList_validate( markedInsertList, 188 markedInsertCount, 189 table, limit, 190 gxvalid ); 191 } 192 193 194 FT_LOCAL_DEF( void ) gxv_morx_subtable_type5_validate(FT_Bytes table,FT_Bytes limit,GXV_Validator gxvalid)195 gxv_morx_subtable_type5_validate( FT_Bytes table, 196 FT_Bytes limit, 197 GXV_Validator gxvalid ) 198 { 199 FT_Bytes p = table; 200 201 GXV_morx_subtable_type5_StateOptRec et_rec; 202 GXV_morx_subtable_type5_StateOptRecData et = &et_rec; 203 204 205 GXV_NAME_ENTER( "morx chain subtable type5 (Glyph Insertion)" ); 206 207 GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE5_HEADER_SIZE ); 208 209 gxvalid->xstatetable.optdata = 210 et; 211 gxvalid->xstatetable.optdata_load_func = 212 gxv_morx_subtable_type5_insertionGlyphList_load; 213 gxvalid->xstatetable.subtable_setup_func = 214 gxv_morx_subtable_type5_subtable_setup; 215 gxvalid->xstatetable.entry_glyphoffset_fmt = 216 GXV_GLYPHOFFSET_ULONG; 217 gxvalid->xstatetable.entry_validate_func = 218 gxv_morx_subtable_type5_entry_validate; 219 220 gxv_XStateTable_validate( p, limit, gxvalid ); 221 222 GXV_EXIT; 223 } 224 225 226 /* END */ 227