1 | /**************************************************************************** |
2 | * |
3 | * gxvlcar.c |
4 | * |
5 | * TrueTypeGX/AAT lcar table validation (body). |
6 | * |
7 | * Copyright (C) 2004-2023 by |
8 | * suzuki toshiya, Masatake YAMATO, Red Hat K.K., |
9 | * David Turner, Robert Wilhelm, and Werner Lemberg. |
10 | * |
11 | * This file is part of the FreeType project, and may only be used, |
12 | * modified, and distributed under the terms of the FreeType project |
13 | * license, LICENSE.TXT. By continuing to use, modify, or distribute |
14 | * this file you indicate that you have read the license and |
15 | * understand and accept it fully. |
16 | * |
17 | */ |
18 | |
19 | /**************************************************************************** |
20 | * |
21 | * gxvalid is derived from both gxlayout module and otvalid module. |
22 | * Development of gxlayout is supported by the Information-technology |
23 | * Promotion Agency(IPA), Japan. |
24 | * |
25 | */ |
26 | |
27 | |
28 | #include "gxvalid.h" |
29 | #include "gxvcommn.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 gxvlcar |
40 | |
41 | |
42 | /*************************************************************************/ |
43 | /*************************************************************************/ |
44 | /***** *****/ |
45 | /***** Data and Types *****/ |
46 | /***** *****/ |
47 | /*************************************************************************/ |
48 | /*************************************************************************/ |
49 | |
50 | typedef struct GXV_lcar_DataRec_ |
51 | { |
52 | FT_UShort format; |
53 | |
54 | } GXV_lcar_DataRec, *GXV_lcar_Data; |
55 | |
56 | |
57 | #define GXV_LCAR_DATA( FIELD ) GXV_TABLE_DATA( lcar, FIELD ) |
58 | |
59 | |
60 | /*************************************************************************/ |
61 | /*************************************************************************/ |
62 | /***** *****/ |
63 | /***** UTILITY FUNCTIONS *****/ |
64 | /***** *****/ |
65 | /*************************************************************************/ |
66 | /*************************************************************************/ |
67 | |
68 | static void |
69 | gxv_lcar_partial_validate( FT_Short partial, |
70 | FT_UShort glyph, |
71 | GXV_Validator gxvalid ) |
72 | { |
73 | GXV_NAME_ENTER( "partial" ); |
74 | |
75 | if ( GXV_LCAR_DATA( format ) != 1 ) |
76 | goto Exit; |
77 | |
78 | gxv_ctlPoint_validate( glyph, (FT_UShort)partial, gxvalid ); |
79 | |
80 | Exit: |
81 | GXV_EXIT; |
82 | } |
83 | |
84 | |
85 | static void |
86 | gxv_lcar_LookupValue_validate( FT_UShort glyph, |
87 | GXV_LookupValueCPtr value_p, |
88 | GXV_Validator gxvalid ) |
89 | { |
90 | FT_Bytes p = gxvalid->root->base + value_p->u; |
91 | FT_Bytes limit = gxvalid->root->limit; |
92 | FT_UShort count; |
93 | FT_Short partial; |
94 | FT_UShort i; |
95 | |
96 | |
97 | GXV_NAME_ENTER( "element in lookupTable" ); |
98 | |
99 | GXV_LIMIT_CHECK( 2 ); |
100 | count = FT_NEXT_USHORT( p ); |
101 | |
102 | GXV_LIMIT_CHECK( 2 * count ); |
103 | for ( i = 0; i < count; i++ ) |
104 | { |
105 | partial = FT_NEXT_SHORT( p ); |
106 | gxv_lcar_partial_validate( partial, glyph, gxvalid ); |
107 | } |
108 | |
109 | GXV_EXIT; |
110 | } |
111 | |
112 | |
113 | /* |
114 | +------ lcar --------------------+ |
115 | | | |
116 | | +===============+ | |
117 | | | lookup header | | |
118 | | +===============+ | |
119 | | | BinSrchHeader | | |
120 | | +===============+ | |
121 | | | lastGlyph[0] | | |
122 | | +---------------+ | |
123 | | | firstGlyph[0] | | head of lcar sfnt table |
124 | | +---------------+ | + |
125 | | | offset[0] | -> | offset [byte] |
126 | | +===============+ | + |
127 | | | lastGlyph[1] | | (glyphID - firstGlyph) * 2 [byte] |
128 | | +---------------+ | |
129 | | | firstGlyph[1] | | |
130 | | +---------------+ | |
131 | | | offset[1] | | |
132 | | +===============+ | |
133 | | | |
134 | | .... | |
135 | | | |
136 | | 16bit value array | |
137 | | +===============+ | |
138 | +------| value | <-------+ |
139 | | .... |
140 | | |
141 | | |
142 | | |
143 | | |
144 | | |
145 | +----> lcar values...handled by lcar callback function |
146 | */ |
147 | |
148 | static GXV_LookupValueDesc |
149 | gxv_lcar_LookupFmt4_transit( FT_UShort relative_gindex, |
150 | GXV_LookupValueCPtr base_value_p, |
151 | FT_Bytes lookuptbl_limit, |
152 | GXV_Validator gxvalid ) |
153 | { |
154 | FT_Bytes p; |
155 | FT_Bytes limit; |
156 | FT_UShort offset; |
157 | GXV_LookupValueDesc value; |
158 | |
159 | FT_UNUSED( lookuptbl_limit ); |
160 | |
161 | /* XXX: check range? */ |
162 | offset = (FT_UShort)( base_value_p->u + |
163 | relative_gindex * sizeof ( FT_UShort ) ); |
164 | p = gxvalid->root->base + offset; |
165 | limit = gxvalid->root->limit; |
166 | |
167 | GXV_LIMIT_CHECK ( 2 ); |
168 | value.u = FT_NEXT_USHORT( p ); |
169 | |
170 | return value; |
171 | } |
172 | |
173 | |
174 | /*************************************************************************/ |
175 | /*************************************************************************/ |
176 | /***** *****/ |
177 | /***** lcar TABLE *****/ |
178 | /***** *****/ |
179 | /*************************************************************************/ |
180 | /*************************************************************************/ |
181 | |
182 | FT_LOCAL_DEF( void ) |
183 | gxv_lcar_validate( FT_Bytes table, |
184 | FT_Face face, |
185 | FT_Validator ftvalid ) |
186 | { |
187 | FT_Bytes p = table; |
188 | FT_Bytes limit = 0; |
189 | GXV_ValidatorRec gxvalidrec; |
190 | GXV_Validator gxvalid = &gxvalidrec; |
191 | |
192 | GXV_lcar_DataRec lcarrec; |
193 | GXV_lcar_Data lcar = &lcarrec; |
194 | |
195 | FT_Fixed version; |
196 | |
197 | |
198 | gxvalid->root = ftvalid; |
199 | gxvalid->table_data = lcar; |
200 | gxvalid->face = face; |
201 | |
202 | FT_TRACE3(( "validating `lcar' table\n" )); |
203 | GXV_INIT; |
204 | |
205 | GXV_LIMIT_CHECK( 4 + 2 ); |
206 | version = FT_NEXT_LONG( p ); |
207 | GXV_LCAR_DATA( format ) = FT_NEXT_USHORT( p ); |
208 | |
209 | if ( version != 0x00010000UL) |
210 | FT_INVALID_FORMAT; |
211 | |
212 | if ( GXV_LCAR_DATA( format ) > 1 ) |
213 | FT_INVALID_FORMAT; |
214 | |
215 | gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; |
216 | gxvalid->lookupval_func = gxv_lcar_LookupValue_validate; |
217 | gxvalid->lookupfmt4_trans = gxv_lcar_LookupFmt4_transit; |
218 | gxv_LookupTable_validate( p, limit, gxvalid ); |
219 | |
220 | FT_TRACE4(( "\n" )); |
221 | } |
222 | |
223 | |
224 | /* END */ |
225 | |