1 /***************************************************************************/ 2 /* */ 3 /* gxvmort0.c */ 4 /* */ 5 /* TrueTypeGX/AAT mort table validation */ 6 /* body for type0 (Indic Script Rearrangement) subtable. */ 7 /* */ 8 /* Copyright 2005-2015 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 "gxvmort.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_gxvmort 40 41 42 static const char* GXV_Mort_IndicScript_Msg[] = 43 { 44 "no change", 45 "Ax => xA", 46 "xD => Dx", 47 "AxD => DxA", 48 "ABx => xAB", 49 "ABx => xBA", 50 "xCD => CDx", 51 "xCD => DCx", 52 "AxCD => CDxA", 53 "AxCD => DCxA", 54 "ABxD => DxAB", 55 "ABxD => DxBA", 56 "ABxCD => CDxAB", 57 "ABxCD => CDxBA", 58 "ABxCD => DCxAB", 59 "ABxCD => DCxBA", 60 61 }; 62 63 64 static void 65 gxv_mort_subtable_type0_entry_validate( 66 FT_Byte state, 67 FT_UShort flags, 68 GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, 69 FT_Bytes table, 70 FT_Bytes limit, 71 GXV_Validator gxvalid ) 72 { 73 FT_UShort markFirst; 74 FT_UShort dontAdvance; 75 FT_UShort markLast; 76 FT_UShort reserved; 77 FT_UShort verb = 0; 78 79 FT_UNUSED( state ); 80 FT_UNUSED( table ); 81 FT_UNUSED( limit ); 82 83 FT_UNUSED( GXV_Mort_IndicScript_Msg[verb] ); /* for the non-debugging */ 84 FT_UNUSED( glyphOffset_p ); /* case */ 85 86 87 markFirst = (FT_UShort)( ( flags >> 15 ) & 1 ); 88 dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); 89 markLast = (FT_UShort)( ( flags >> 13 ) & 1 ); 90 91 reserved = (FT_UShort)( flags & 0x1FF0 ); 92 verb = (FT_UShort)( flags & 0x000F ); 93 94 GXV_TRACE(( " IndicScript MorphRule for glyphOffset 0x%04x", 95 glyphOffset_p->u )); 96 GXV_TRACE(( " markFirst=%01d", markFirst )); 97 GXV_TRACE(( " dontAdvance=%01d", dontAdvance )); 98 GXV_TRACE(( " markLast=%01d", markLast )); 99 GXV_TRACE(( " %02d", verb )); 100 GXV_TRACE(( " %s\n", GXV_Mort_IndicScript_Msg[verb] )); 101 102 if ( markFirst > 0 && markLast > 0 ) 103 { 104 GXV_TRACE(( " [odd] a glyph is marked as the first and last" 105 " in Indic rearrangement\n" )); 106 GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); 107 } 108 109 if ( markFirst > 0 && dontAdvance > 0 ) 110 { 111 GXV_TRACE(( " [odd] the first glyph is marked as dontAdvance" 112 " in Indic rearrangement\n" )); 113 GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); 114 } 115 116 if ( 0 < reserved ) 117 { 118 GXV_TRACE(( " non-zero bits found in reserved range\n" )); 119 GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); 120 } 121 else 122 GXV_TRACE(( "\n" )); 123 } 124 125 126 FT_LOCAL_DEF( void ) 127 gxv_mort_subtable_type0_validate( FT_Bytes table, 128 FT_Bytes limit, 129 GXV_Validator gxvalid ) 130 { 131 FT_Bytes p = table; 132 133 134 GXV_NAME_ENTER( 135 "mort chain subtable type0 (Indic-Script Rearrangement)" ); 136 137 GXV_LIMIT_CHECK( GXV_STATETABLE_HEADER_SIZE ); 138 139 gxvalid->statetable.optdata = NULL; 140 gxvalid->statetable.optdata_load_func = NULL; 141 gxvalid->statetable.subtable_setup_func = NULL; 142 gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; 143 gxvalid->statetable.entry_validate_func = 144 gxv_mort_subtable_type0_entry_validate; 145 146 gxv_StateTable_validate( p, limit, gxvalid ); 147 148 GXV_EXIT; 149 } 150 151 152 /* END */ 153