ReactOS 0.4.15-dev-7934-g1dc8d80
cidparse.c
Go to the documentation of this file.
1/***************************************************************************/
2/* */
3/* cidparse.c */
4/* */
5/* CID-keyed Type1 parser (body). */
6/* */
7/* Copyright 1996-2018 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 <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21#include FT_INTERNAL_OBJECTS_H
22#include FT_INTERNAL_STREAM_H
23
24#include "cidparse.h"
25
26#include "ciderrs.h"
27
28
29 /*************************************************************************/
30 /* */
31 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
32 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
33 /* messages during execution. */
34 /* */
35#undef FT_COMPONENT
36#define FT_COMPONENT trace_cidparse
37
38
39 /*************************************************************************/
40 /*************************************************************************/
41 /*************************************************************************/
42 /***** *****/
43 /***** INPUT STREAM PARSER *****/
44 /***** *****/
45 /*************************************************************************/
46 /*************************************************************************/
47 /*************************************************************************/
48
49
50#define STARTDATA "StartData"
51#define STARTDATA_LEN ( sizeof ( STARTDATA ) - 1 )
52#define SFNTS "/sfnts"
53#define SFNTS_LEN ( sizeof ( SFNTS ) - 1 )
54
55
60 PSAux_Service psaux )
61 {
63 FT_ULong base_offset, offset, ps_len;
64 FT_Byte *cur, *limit;
65 FT_Byte *arg1, *arg2;
66
67
68 FT_ZERO( parser );
69 psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
70
71 parser->stream = stream;
72
73 base_offset = FT_STREAM_POS();
74
75 /* first of all, check the font format in the header */
76 if ( FT_FRAME_ENTER( 31 ) )
77 goto Exit;
78
79 if ( ft_strncmp( (char *)stream->cursor,
80 "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
81 {
82 FT_TRACE2(( " not a CID-keyed font\n" ));
83 error = FT_THROW( Unknown_File_Format );
84 }
85
87 if ( error )
88 goto Exit;
89
90 Again:
91 /* now, read the rest of the file until we find */
92 /* `StartData' or `/sfnts' */
93 {
94 /*
95 * The algorithm is as follows (omitting the case with less than 256
96 * bytes to fill for simplicity).
97 *
98 * 1. Fill the buffer with 256 + STARTDATA_LEN bytes.
99 *
100 * 2. Search for the STARTDATA and SFNTS strings at positions
101 * buffer[0], buffer[1], ...,
102 * buffer[255 + STARTDATA_LEN - SFNTS_LEN].
103 *
104 * 3. Move the last STARTDATA_LEN bytes to buffer[0].
105 *
106 * 4. Fill the buffer with 256 bytes, starting at STARTDATA_LEN.
107 *
108 * 5. Repeat with step 2.
109 *
110 */
111 FT_Byte buffer[256 + STARTDATA_LEN + 1];
112
113 /* values for the first loop */
114 FT_ULong read_len = 256 + STARTDATA_LEN;
115 FT_ULong read_offset = 0;
116 FT_Byte* p = buffer;
117
118
119 for ( offset = FT_STREAM_POS(); ; offset += 256 )
120 {
121 FT_ULong stream_len;
122
123
124 stream_len = stream->size - FT_STREAM_POS();
125
126 read_len = FT_MIN( read_len, stream_len );
127 if ( FT_STREAM_READ( p, read_len ) )
128 goto Exit;
129
130 /* ensure that we do not compare with data beyond the buffer */
131 p[read_len] = '\0';
132
133 limit = p + read_len - SFNTS_LEN;
134
135 for ( p = buffer; p < limit; p++ )
136 {
137 if ( p[0] == 'S' &&
138 ft_strncmp( (char*)p, STARTDATA, STARTDATA_LEN ) == 0 )
139 {
140 /* save offset of binary data after `StartData' */
141 offset += (FT_ULong)( p - buffer ) + STARTDATA_LEN + 1;
142 goto Found;
143 }
144 else if ( p[1] == 's' &&
145 ft_strncmp( (char*)p, SFNTS, SFNTS_LEN ) == 0 )
146 {
147 offset += (FT_ULong)( p - buffer ) + SFNTS_LEN + 1;
148 goto Found;
149 }
150 }
151
152 if ( read_offset + read_len < STARTDATA_LEN )
153 {
154 FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
155 error = FT_THROW( Invalid_File_Format );
156 goto Exit;
157 }
158
160 buffer + read_offset + read_len - STARTDATA_LEN,
162
163 /* values for the next loop */
164 read_len = 256;
165 read_offset = STARTDATA_LEN;
166 p = buffer + read_offset;
167 }
168 }
169
170 Found:
171 /* We have found the start of the binary data or the `/sfnts' token. */
172 /* Now rewind and extract the frame corresponding to this PostScript */
173 /* section. */
174
175 ps_len = offset - base_offset;
176 if ( FT_STREAM_SEEK( base_offset ) ||
177 FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
178 goto Exit;
179
180 parser->data_offset = offset;
181 parser->postscript_len = ps_len;
182 parser->root.base = parser->postscript;
183 parser->root.cursor = parser->postscript;
184 parser->root.limit = parser->root.cursor + ps_len;
185 parser->num_dict = -1;
186
187 /* Finally, we check whether `StartData' or `/sfnts' was real -- */
188 /* it could be in a comment or string. We also get the arguments */
189 /* of `StartData' to find out whether the data is represented in */
190 /* binary or hex format. */
191
192 arg1 = parser->root.cursor;
195 arg2 = parser->root.cursor;
198
199 limit = parser->root.limit;
200 cur = parser->root.cursor;
201
202 while ( cur <= limit - SFNTS_LEN )
203 {
204 if ( parser->root.error )
205 {
206 error = parser->root.error;
207 goto Exit;
208 }
209
210 if ( cur[0] == 'S' &&
211 cur <= limit - STARTDATA_LEN &&
212 ft_strncmp( (char*)cur, STARTDATA, STARTDATA_LEN ) == 0 )
213 {
214 if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
215 {
216 FT_Long tmp = ft_strtol( (const char *)arg2, NULL, 10 );
217
218
219 if ( tmp < 0 )
220 {
221 FT_ERROR(( "cid_parser_new: invalid length of hex data\n" ));
222 error = FT_THROW( Invalid_File_Format );
223 }
224 else
225 parser->binary_length = (FT_ULong)tmp;
226 }
227
228 goto Exit;
229 }
230 else if ( cur[1] == 's' &&
231 ft_strncmp( (char*)cur, SFNTS, SFNTS_LEN ) == 0 )
232 {
233 FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
234 error = FT_THROW( Unknown_File_Format );
235 goto Exit;
236 }
237
240 arg1 = arg2;
241 arg2 = cur;
242 cur = parser->root.cursor;
243 }
244
245 /* we haven't found the correct `StartData'; go back and continue */
246 /* searching */
247 FT_FRAME_RELEASE( parser->postscript );
248 if ( !FT_STREAM_SEEK( offset ) )
249 goto Again;
250
251 Exit:
252 return error;
253 }
254
255
256#undef STARTDATA
257#undef STARTDATA_LEN
258#undef SFNTS
259#undef SFNTS_LEN
260
261
262 FT_LOCAL_DEF( void )
264 {
265 /* always free the private dictionary */
266 if ( parser->postscript )
267 {
268 FT_Stream stream = parser->stream;
269
270
271 FT_FRAME_RELEASE( parser->postscript );
272 }
273 parser->root.funcs.done( &parser->root );
274 }
275
276
277/* END */
return Found
Definition: dirsup.c:1270
#define STARTDATA_LEN
Definition: cidparse.c:51
cid_parser_new(CID_Parser *parser, FT_Stream stream, FT_Memory memory, PSAux_Service psaux)
Definition: cidparse.c:57
#define STARTDATA
Definition: cidparse.c:50
#define SFNTS
Definition: cidparse.c:52
#define SFNTS_LEN
Definition: cidparse.c:53
cid_parser_done(CID_Parser *parser)
Definition: cidparse.c:263
#define cid_parser_skip_PS_token(p)
Definition: cidparse.h:97
FT_BEGIN_HEADER struct CID_Parser_ CID_Parser
#define cid_parser_skip_spaces(p)
Definition: cidparse.h:95
#define NULL
Definition: types.h:112
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
#define FT_THROW(e)
Definition: ftdebug.h:213
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
#define FT_ZERO(p)
Definition: ftmemory.h:237
#define FT_MEM_MOVE(dest, source, count)
Definition: ftmemory.h:231
#define FT_MIN(a, b)
Definition: ftobjs.h:71
#define ft_strncmp
Definition: ftstdlib.h:89
#define ft_strtol
Definition: ftstdlib.h:145
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:512
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:526
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:489
#define FT_STREAM_POS()
Definition: ftstream.h:486
#define FT_FRAME_EXIT()
Definition: ftstream.h:517
#define FT_FRAME_EXTRACT(size, bytes)
Definition: ftstream.h:520
#define FT_STREAM_READ(buffer, count)
Definition: ftstream.h:497
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
unsigned long FT_ULong
Definition: fttypes.h:253
unsigned char FT_Byte
Definition: fttypes.h:154
int FT_Error
Definition: fttypes.h:300
signed long FT_Long
Definition: fttypes.h:242
FxCollectionEntry * cur
GLuint buffer
Definition: glext.h:5915
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLint limit
Definition: glext.h:10326
GLfloat GLfloat p
Definition: glext.h:8902
GLintptr offset
Definition: glext.h:5920
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:116
static void Exit(void)
Definition: sock.c:1330
Definition: import.c:81
unsigned int error
Definition: inffile.c:97
Definition: parse.h:23
unsigned int size
Definition: parse.h:27