Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /***************************************************************************/ |
2 | /* */ |
||
3 | /* cidparse.c */ |
||
4 | /* */ |
||
5 | /* CID-keyed Type1 parser (body). */ |
||
6 | /* */ |
||
7 | /* Copyright 1996-2007, 2009, 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 |
||
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 | FT_LOCAL_DEF( FT_Error ) |
||
51 | cid_parser_new( CID_Parser* parser, |
||
52 | FT_Stream stream, |
||
53 | FT_Memory memory, |
||
54 | PSAux_Service psaux ) |
||
55 | { |
||
56 | FT_Error error; |
||
57 | FT_ULong base_offset, offset, ps_len; |
||
58 | FT_Byte *cur, *limit; |
||
59 | FT_Byte *arg1, *arg2; |
||
60 | |||
61 | |||
62 | FT_MEM_ZERO( parser, sizeof ( *parser ) ); |
||
63 | psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory ); |
||
64 | |||
65 | parser->stream = stream; |
||
66 | |||
67 | base_offset = FT_STREAM_POS(); |
||
68 | |||
69 | /* first of all, check the font format in the header */ |
||
70 | if ( FT_FRAME_ENTER( 31 ) ) |
||
71 | goto Exit; |
||
72 | |||
73 | if ( ft_strncmp( (char *)stream->cursor, |
||
74 | "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) |
||
75 | { |
||
76 | FT_TRACE2(( " not a CID-keyed font\n" )); |
||
77 | error = FT_THROW( Unknown_File_Format ); |
||
78 | } |
||
79 | |||
80 | FT_FRAME_EXIT(); |
||
81 | if ( error ) |
||
82 | goto Exit; |
||
83 | |||
84 | Again: |
||
85 | /* now, read the rest of the file until we find */ |
||
86 | /* `StartData' or `/sfnts' */ |
||
87 | { |
||
88 | FT_Byte buffer[256 + 10]; |
||
89 | FT_Long read_len = 256 + 10; /* same as signed FT_Stream->size */ |
||
90 | FT_Byte* p = buffer; |
||
91 | |||
92 | |||
93 | for ( offset = FT_STREAM_POS(); ; offset += 256 ) |
||
94 | { |
||
95 | FT_Long stream_len; /* same as signed FT_Stream->size */ |
||
96 | |||
97 | |||
98 | stream_len = stream->size - FT_STREAM_POS(); |
||
99 | if ( stream_len == 0 ) |
||
100 | { |
||
101 | FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" )); |
||
102 | error = FT_THROW( Invalid_File_Format ); |
||
103 | goto Exit; |
||
104 | } |
||
105 | |||
106 | read_len = FT_MIN( read_len, stream_len ); |
||
107 | if ( FT_STREAM_READ( p, read_len ) ) |
||
108 | goto Exit; |
||
109 | |||
110 | if ( read_len < 256 ) |
||
111 | p[read_len] = '\0'; |
||
112 | |||
113 | limit = p + read_len - 10; |
||
114 | |||
115 | for ( p = buffer; p < limit; p++ ) |
||
116 | { |
||
117 | if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 ) |
||
118 | { |
||
119 | /* save offset of binary data after `StartData' */ |
||
120 | offset += (FT_ULong)( p - buffer + 10 ); |
||
121 | goto Found; |
||
122 | } |
||
123 | else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 ) |
||
124 | { |
||
125 | offset += (FT_ULong)( p - buffer + 7 ); |
||
126 | goto Found; |
||
127 | } |
||
128 | } |
||
129 | |||
130 | FT_MEM_MOVE( buffer, p, 10 ); |
||
131 | read_len = 256; |
||
132 | p = buffer + 10; |
||
133 | } |
||
134 | } |
||
135 | |||
136 | Found: |
||
137 | /* We have found the start of the binary data or the `/sfnts' token. */ |
||
138 | /* Now rewind and extract the frame corresponding to this PostScript */ |
||
139 | /* section. */ |
||
140 | |||
141 | ps_len = offset - base_offset; |
||
142 | if ( FT_STREAM_SEEK( base_offset ) || |
||
143 | FT_FRAME_EXTRACT( ps_len, parser->postscript ) ) |
||
144 | goto Exit; |
||
145 | |||
146 | parser->data_offset = offset; |
||
147 | parser->postscript_len = ps_len; |
||
148 | parser->root.base = parser->postscript; |
||
149 | parser->root.cursor = parser->postscript; |
||
150 | parser->root.limit = parser->root.cursor + ps_len; |
||
151 | parser->num_dict = -1; |
||
152 | |||
153 | /* Finally, we check whether `StartData' or `/sfnts' was real -- */ |
||
154 | /* it could be in a comment or string. We also get the arguments */ |
||
155 | /* of `StartData' to find out whether the data is represented in */ |
||
156 | /* binary or hex format. */ |
||
157 | |||
158 | arg1 = parser->root.cursor; |
||
159 | cid_parser_skip_PS_token( parser ); |
||
160 | cid_parser_skip_spaces ( parser ); |
||
161 | arg2 = parser->root.cursor; |
||
162 | cid_parser_skip_PS_token( parser ); |
||
163 | cid_parser_skip_spaces ( parser ); |
||
164 | |||
165 | limit = parser->root.limit; |
||
166 | cur = parser->root.cursor; |
||
167 | |||
168 | while ( cur < limit ) |
||
169 | { |
||
170 | if ( parser->root.error ) |
||
171 | { |
||
172 | error = parser->root.error; |
||
173 | goto Exit; |
||
174 | } |
||
175 | |||
176 | if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 ) |
||
177 | { |
||
178 | if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 ) |
||
179 | parser->binary_length = ft_atol( (const char *)arg2 ); |
||
180 | |||
181 | limit = parser->root.limit; |
||
182 | cur = parser->root.cursor; |
||
183 | goto Exit; |
||
184 | } |
||
185 | else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 ) |
||
186 | { |
||
187 | FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" )); |
||
188 | error = FT_THROW( Unknown_File_Format ); |
||
189 | goto Exit; |
||
190 | } |
||
191 | |||
192 | cid_parser_skip_PS_token( parser ); |
||
193 | cid_parser_skip_spaces ( parser ); |
||
194 | arg1 = arg2; |
||
195 | arg2 = cur; |
||
196 | cur = parser->root.cursor; |
||
197 | } |
||
198 | |||
199 | /* we haven't found the correct `StartData'; go back and continue */ |
||
200 | /* searching */ |
||
201 | FT_FRAME_RELEASE( parser->postscript ); |
||
202 | if ( !FT_STREAM_SEEK( offset ) ) |
||
203 | goto Again; |
||
204 | |||
205 | Exit: |
||
206 | return error; |
||
207 | } |
||
208 | |||
209 | |||
210 | FT_LOCAL_DEF( void ) |
||
211 | cid_parser_done( CID_Parser* parser ) |
||
212 | { |
||
213 | /* always free the private dictionary */ |
||
214 | if ( parser->postscript ) |
||
215 | { |
||
216 | FT_Stream stream = parser->stream; |
||
217 | |||
218 | |||
219 | FT_FRAME_RELEASE( parser->postscript ); |
||
220 | } |
||
221 | parser->root.funcs.done( &parser->root ); |
||
222 | } |
||
223 | |||
224 | |||
225 | /* END */>>> |