OLD | NEW |
| (Empty) |
1 /***************************************************************************/ | |
2 /* */ | |
3 /* ttbdf.c */ | |
4 /* */ | |
5 /* TrueType and OpenType embedded BDF properties (body). */ | |
6 /* */ | |
7 /* Copyright 2005, 2006, 2010, 2013 by */ | |
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ | |
9 /* */ | |
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. */ | |
15 /* */ | |
16 /***************************************************************************/ | |
17 | |
18 | |
19 #include "../../include/ft2build.h" | |
20 #include "../../include/freetype/internal/ftdebug.h" | |
21 #include "../../include/freetype/internal/ftstream.h" | |
22 #include "../../include/freetype/tttags.h" | |
23 #include "ttbdf.h" | |
24 | |
25 #include "sferrors.h" | |
26 | |
27 | |
28 #ifdef TT_CONFIG_OPTION_BDF | |
29 | |
30 /*************************************************************************/ | |
31 /* */ | |
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. */ | |
35 /* */ | |
36 #undef FT_COMPONENT | |
37 #define FT_COMPONENT trace_ttbdf | |
38 | |
39 | |
40 FT_LOCAL_DEF( void ) | |
41 tt_face_free_bdf_props( TT_Face face ) | |
42 { | |
43 TT_BDF bdf = &face->bdf; | |
44 | |
45 | |
46 if ( bdf->loaded ) | |
47 { | |
48 FT_Stream stream = FT_FACE(face)->stream; | |
49 | |
50 | |
51 if ( bdf->table != NULL ) | |
52 FT_FRAME_RELEASE( bdf->table ); | |
53 | |
54 bdf->table_end = NULL; | |
55 bdf->strings = NULL; | |
56 bdf->strings_size = 0; | |
57 } | |
58 } | |
59 | |
60 | |
61 static FT_Error | |
62 tt_face_load_bdf_props( TT_Face face, | |
63 FT_Stream stream ) | |
64 { | |
65 TT_BDF bdf = &face->bdf; | |
66 FT_ULong length; | |
67 FT_Error error; | |
68 | |
69 | |
70 FT_ZERO( bdf ); | |
71 | |
72 error = tt_face_goto_table( face, TTAG_BDF, stream, &length ); | |
73 if ( error || | |
74 length < 8 || | |
75 FT_FRAME_EXTRACT( length, bdf->table ) ) | |
76 { | |
77 error = FT_THROW( Invalid_Table ); | |
78 goto Exit; | |
79 } | |
80 | |
81 bdf->table_end = bdf->table + length; | |
82 | |
83 { | |
84 FT_Byte* p = bdf->table; | |
85 FT_UInt version = FT_NEXT_USHORT( p ); | |
86 FT_UInt num_strikes = FT_NEXT_USHORT( p ); | |
87 FT_ULong strings = FT_NEXT_ULONG ( p ); | |
88 FT_UInt count; | |
89 FT_Byte* strike; | |
90 | |
91 | |
92 if ( version != 0x0001 || | |
93 strings < 8 || | |
94 ( strings - 8 ) / 4 < num_strikes || | |
95 strings + 1 > length ) | |
96 { | |
97 goto BadTable; | |
98 } | |
99 | |
100 bdf->num_strikes = num_strikes; | |
101 bdf->strings = bdf->table + strings; | |
102 bdf->strings_size = length - strings; | |
103 | |
104 count = bdf->num_strikes; | |
105 p = bdf->table + 8; | |
106 strike = p + count * 4; | |
107 | |
108 | |
109 for ( ; count > 0; count-- ) | |
110 { | |
111 FT_UInt num_items = FT_PEEK_USHORT( p + 2 ); | |
112 | |
113 /* | |
114 * We don't need to check the value sets themselves, since this | |
115 * is done later. | |
116 */ | |
117 strike += 10 * num_items; | |
118 | |
119 p += 4; | |
120 } | |
121 | |
122 if ( strike > bdf->strings ) | |
123 goto BadTable; | |
124 } | |
125 | |
126 bdf->loaded = 1; | |
127 | |
128 Exit: | |
129 return error; | |
130 | |
131 BadTable: | |
132 FT_FRAME_RELEASE( bdf->table ); | |
133 FT_ZERO( bdf ); | |
134 error = FT_THROW( Invalid_Table ); | |
135 goto Exit; | |
136 } | |
137 | |
138 | |
139 FT_LOCAL_DEF( FT_Error ) | |
140 tt_face_find_bdf_prop( TT_Face face, | |
141 const char* property_name, | |
142 BDF_PropertyRec *aprop ) | |
143 { | |
144 TT_BDF bdf = &face->bdf; | |
145 FT_Size size = FT_FACE(face)->size; | |
146 FT_Error error = FT_Err_Ok; | |
147 FT_Byte* p; | |
148 FT_UInt count; | |
149 FT_Byte* strike; | |
150 FT_Offset property_len; | |
151 | |
152 | |
153 aprop->type = BDF_PROPERTY_TYPE_NONE; | |
154 | |
155 if ( bdf->loaded == 0 ) | |
156 { | |
157 error = tt_face_load_bdf_props( face, FT_FACE( face )->stream ); | |
158 if ( error ) | |
159 goto Exit; | |
160 } | |
161 | |
162 count = bdf->num_strikes; | |
163 p = bdf->table + 8; | |
164 strike = p + 4 * count; | |
165 | |
166 error = FT_ERR( Invalid_Argument ); | |
167 | |
168 if ( size == NULL || property_name == NULL ) | |
169 goto Exit; | |
170 | |
171 property_len = ft_strlen( property_name ); | |
172 if ( property_len == 0 ) | |
173 goto Exit; | |
174 | |
175 for ( ; count > 0; count-- ) | |
176 { | |
177 FT_UInt _ppem = FT_NEXT_USHORT( p ); | |
178 FT_UInt _count = FT_NEXT_USHORT( p ); | |
179 | |
180 if ( _ppem == size->metrics.y_ppem ) | |
181 { | |
182 count = _count; | |
183 goto FoundStrike; | |
184 } | |
185 | |
186 strike += 10 * _count; | |
187 } | |
188 goto Exit; | |
189 | |
190 FoundStrike: | |
191 p = strike; | |
192 for ( ; count > 0; count-- ) | |
193 { | |
194 FT_UInt type = FT_PEEK_USHORT( p + 4 ); | |
195 | |
196 if ( ( type & 0x10 ) != 0 ) | |
197 { | |
198 FT_UInt32 name_offset = FT_PEEK_ULONG( p ); | |
199 FT_UInt32 value = FT_PEEK_ULONG( p + 6 ); | |
200 | |
201 /* be a bit paranoid for invalid entries here */ | |
202 if ( name_offset < bdf->strings_size && | |
203 property_len < bdf->strings_size - name_offset && | |
204 ft_strncmp( property_name, | |
205 (const char*)bdf->strings + name_offset, | |
206 bdf->strings_size - name_offset ) == 0 ) | |
207 { | |
208 switch ( type & 0x0F ) | |
209 { | |
210 case 0x00: /* string */ | |
211 case 0x01: /* atoms */ | |
212 /* check that the content is really 0-terminated */ | |
213 if ( value < bdf->strings_size && | |
214 ft_memchr( bdf->strings + value, 0, bdf->strings_size ) ) | |
215 { | |
216 aprop->type = BDF_PROPERTY_TYPE_ATOM; | |
217 aprop->u.atom = (const char*)bdf->strings + value; | |
218 error = FT_Err_Ok; | |
219 goto Exit; | |
220 } | |
221 break; | |
222 | |
223 case 0x02: | |
224 aprop->type = BDF_PROPERTY_TYPE_INTEGER; | |
225 aprop->u.integer = (FT_Int32)value; | |
226 error = FT_Err_Ok; | |
227 goto Exit; | |
228 | |
229 case 0x03: | |
230 aprop->type = BDF_PROPERTY_TYPE_CARDINAL; | |
231 aprop->u.cardinal = value; | |
232 error = FT_Err_Ok; | |
233 goto Exit; | |
234 | |
235 default: | |
236 ; | |
237 } | |
238 } | |
239 } | |
240 p += 10; | |
241 } | |
242 | |
243 Exit: | |
244 return error; | |
245 } | |
246 | |
247 #endif /* TT_CONFIG_OPTION_BDF */ | |
248 | |
249 | |
250 /* END */ | |
OLD | NEW |