ReactOS  0.4.14-dev-115-g4576127
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 
86  FT_FRAME_EXIT();
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,
161  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 */
cid_parser_done(CID_Parser *parser)
Definition: cidparse.c:263
#define SFNTS
Definition: cidparse.c:52
int FT_Error
Definition: fttypes.h:300
signed long FT_Long
Definition: fttypes.h:242
#define ft_strncmp
Definition: ftstdlib.h:89
unsigned long FT_ULong
Definition: fttypes.h:253
cid_parser_new(CID_Parser *parser, FT_Stream stream, FT_Memory memory, PSAux_Service psaux)
Definition: cidparse.c:57
#define error(str)
Definition: mkdosfs.c:1605
GLintptr offset
Definition: glext.h:5920
#define FT_MIN(a, b)
Definition: ftobjs.h:71
GLuint buffer
Definition: glext.h:5915
static char memory[1024 *256]
Definition: process.c:116
FT_BEGIN_HEADER struct CID_Parser_ CID_Parser
GLint limit
Definition: glext.h:10326
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
unsigned char FT_Byte
Definition: fttypes.h:154
#define FT_THROW(e)
Definition: ftdebug.h:213
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
smooth NULL
Definition: ftsmooth.c:416
return Found
Definition: dirsup.c:1270
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
#define STARTDATA_LEN
Definition: cidparse.c:51
#define cid_parser_skip_spaces(p)
Definition: cidparse.h:95
#define FT_ZERO(p)
Definition: ftmemory.h:237
static void Exit(void)
Definition: sock.c:1331
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
unsigned int error
Definition: inffile.c:97
unsigned int size
Definition: parse.h:27
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
#define FT_FRAME_EXIT()
Definition: ftstream.h:517
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:489
#define FT_FRAME_RELEASE(bytes)
Definition: ftstream.h:526
#define SFNTS_LEN
Definition: cidparse.c:53
#define FT_STREAM_POS()
Definition: ftstream.h:486
#define STARTDATA
Definition: cidparse.c:50
#define FT_FRAME_EXTRACT(size, bytes)
Definition: ftstream.h:520
Definition: import.c:86
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:512
#define cid_parser_skip_PS_token(p)
Definition: cidparse.h:97
GLfloat GLfloat p
Definition: glext.h:8902
#define FT_MEM_MOVE(dest, source, count)
Definition: ftmemory.h:231
#define FT_STREAM_READ(buffer, count)
Definition: ftstream.h:497
#define ft_strtol
Definition: ftstdlib.h:145