blob: 7b0aba6af9ff58502edc36d61ec805ab7563fce7 [file] [log] [blame]
Werner Lemberge3c11d72000-06-16 06:49:56 +00001/***************************************************************************/
2/* */
3/* cidload.c */
4/* */
5/* CID-keyed Type1 font loader (body). */
6/* */
Werner Lemberg1f8f4672003-05-07 10:39:45 +00007/* Copyright 1996-2001, 2002, 2003 by */
Werner Lemberge3c11d72000-06-16 06:49:56 +00008/* 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
Werner Lembergcc069be2000-12-08 16:17:16 +000018
19#include <ft2build.h>
20#include FT_INTERNAL_DEBUG_H
21#include FT_CONFIG_CONFIG_H
22#include FT_MULTIPLE_MASTERS_H
23#include FT_INTERNAL_TYPE1_TYPES_H
Werner Lemberg1f7f0e82001-06-06 17:30:41 +000024
David Turner8d3a4012001-03-20 11:14:24 +000025#include "cidload.h"
Werner Lembergcc069be2000-12-08 16:17:16 +000026
Werner Lemberg1f7f0e82001-06-06 17:30:41 +000027#include "ciderrs.h"
28
Werner Lemberge3c11d72000-06-16 06:49:56 +000029
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 /* */
David Turner04aa8002000-06-01 03:27:48 +000036#undef FT_COMPONENT
Werner Lemberge3c11d72000-06-16 06:49:56 +000037#define FT_COMPONENT trace_cidload
David Turner04aa8002000-06-01 03:27:48 +000038
Werner Lemberge3c11d72000-06-16 06:49:56 +000039
Werner Lembergac39ecd2000-06-30 22:24:36 +000040 /* read a single offset */
David Turnerbc82f1b2002-03-01 02:26:22 +000041 FT_LOCAL_DEF( FT_Long )
Werner Lemberg93616ec2001-06-27 19:46:12 +000042 cid_get_offset( FT_Byte** start,
43 FT_Byte offsize )
David Turner04aa8002000-06-01 03:27:48 +000044 {
David Turnerf9b8dec2000-06-16 19:34:52 +000045 FT_Long result;
46 FT_Byte* p = *start;
Werner Lemberge3c11d72000-06-16 06:49:56 +000047
48
David Turner04aa8002000-06-01 03:27:48 +000049 for ( result = 0; offsize > 0; offsize-- )
Werner Lembergac39ecd2000-06-30 22:24:36 +000050 {
51 result <<= 8;
52 result |= *p++;
53 }
Werner Lemberge3c11d72000-06-16 06:49:56 +000054
David Turner04aa8002000-06-01 03:27:48 +000055 *start = p;
56 return result;
57 }
58
59
Werner Lemberge3c11d72000-06-16 06:49:56 +000060 /*************************************************************************/
61 /*************************************************************************/
62 /***** *****/
63 /***** TYPE 1 SYMBOL PARSING *****/
64 /***** *****/
65 /*************************************************************************/
66 /*************************************************************************/
David Turner04aa8002000-06-01 03:27:48 +000067
68
Werner Lemberg93616ec2001-06-27 19:46:12 +000069 static FT_Error
Werner Lemberg44be4d52002-03-30 17:08:04 +000070 cid_load_keyword( CID_Face face,
71 CID_Loader* loader,
David Turner4e7eeee2002-02-28 16:10:29 +000072 const T1_Field keyword )
David Turner04aa8002000-06-01 03:27:48 +000073 {
Werner Lemberg44be4d52002-03-30 17:08:04 +000074 FT_Error error;
75 CID_Parser* parser = &loader->parser;
76 FT_Byte* object;
77 void* dummy_object;
78 CID_FaceInfo cid = &face->cid;
David Turner04aa8002000-06-01 03:27:48 +000079
Werner Lemberge3c11d72000-06-16 06:49:56 +000080
David Turner04aa8002000-06-01 03:27:48 +000081 /* if the keyword has a dedicated callback, call it */
David Turner4e7eeee2002-02-28 16:10:29 +000082 if ( keyword->type == T1_FIELD_TYPE_CALLBACK )
David Turner04aa8002000-06-01 03:27:48 +000083 {
David Turner34f1c2f2000-08-23 22:47:44 +000084 keyword->reader( (FT_Face)face, parser );
85 error = parser->root.error;
David Turner04aa8002000-06-01 03:27:48 +000086 goto Exit;
87 }
88
89 /* we must now compute the address of our target object */
Werner Lemberge3c11d72000-06-16 06:49:56 +000090 switch ( keyword->location )
David Turner04aa8002000-06-01 03:27:48 +000091 {
David Turner429978b2002-03-14 10:09:35 +000092 case T1_FIELD_LOCATION_CID_INFO:
David Turnerf9b8dec2000-06-16 19:34:52 +000093 object = (FT_Byte*)cid;
Werner Lemberge3c11d72000-06-16 06:49:56 +000094 break;
95
David Turner429978b2002-03-14 10:09:35 +000096 case T1_FIELD_LOCATION_FONT_INFO:
David Turnerf9b8dec2000-06-16 19:34:52 +000097 object = (FT_Byte*)&cid->font_info;
Werner Lemberge3c11d72000-06-16 06:49:56 +000098 break;
99
Werner Lembergfdc042b2003-06-12 04:59:07 +0000100 case T1_FIELD_LOCATION_BBOX:
101 object = (FT_Byte*)&cid->font_bbox;
102 break;
103
Werner Lemberge3c11d72000-06-16 06:49:56 +0000104 default:
105 {
David Turner29644172002-02-28 18:59:37 +0000106 CID_FaceDict dict;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000107
108
109 if ( parser->num_dict < 0 )
David Turner04aa8002000-06-01 03:27:48 +0000110 {
Werner Lemberge3c11d72000-06-16 06:49:56 +0000111 FT_ERROR(( "cid_load_keyword: invalid use of `%s'!\n",
112 keyword->ident ));
Werner Lemberg1f7f0e82001-06-06 17:30:41 +0000113 error = CID_Err_Syntax_Error;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000114 goto Exit;
David Turner04aa8002000-06-01 03:27:48 +0000115 }
Werner Lemberge3c11d72000-06-16 06:49:56 +0000116
117 dict = cid->font_dicts + parser->num_dict;
118 switch ( keyword->location )
119 {
David Turner429978b2002-03-14 10:09:35 +0000120 case T1_FIELD_LOCATION_PRIVATE:
David Turnerf9b8dec2000-06-16 19:34:52 +0000121 object = (FT_Byte*)&dict->private_dict;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000122 break;
123
124 default:
David Turnerf9b8dec2000-06-16 19:34:52 +0000125 object = (FT_Byte*)dict;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000126 }
127 }
David Turner04aa8002000-06-01 03:27:48 +0000128 }
Werner Lemberge3c11d72000-06-16 06:49:56 +0000129
David Turner34f1c2f2000-08-23 22:47:44 +0000130 dummy_object = object;
Werner Lemberge4b32a52000-10-31 20:42:18 +0000131
David Turner04aa8002000-06-01 03:27:48 +0000132 /* now, load the keyword data in the object's field(s) */
David Turner4e7eeee2002-02-28 16:10:29 +0000133 if ( keyword->type == T1_FIELD_TYPE_INTEGER_ARRAY ||
134 keyword->type == T1_FIELD_TYPE_FIXED_ARRAY )
David Turnerb08fe2d2002-08-27 20:20:29 +0000135 error = cid_parser_load_field_table( &loader->parser, keyword,
Werner Lembergbf7c8322003-06-06 05:07:53 +0000136 &dummy_object );
David Turner04aa8002000-06-01 03:27:48 +0000137 else
Werner Lembergbf7c8322003-06-06 05:07:53 +0000138 error = cid_parser_load_field( &loader->parser,
139 keyword, &dummy_object );
David Turner04aa8002000-06-01 03:27:48 +0000140 Exit:
141 return error;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000142 }
David Turner04aa8002000-06-01 03:27:48 +0000143
144
Werner Lemberg93616ec2001-06-27 19:46:12 +0000145 FT_CALLBACK_DEF( FT_Error )
David Turnerdee78132001-06-27 09:26:46 +0000146 parse_font_matrix( CID_Face face,
147 CID_Parser* parser )
David Turner04aa8002000-06-01 03:27:48 +0000148 {
Werner Lemberg44be4d52002-03-30 17:08:04 +0000149 FT_Matrix* matrix;
150 FT_Vector* offset;
David Turner29644172002-02-28 18:59:37 +0000151 CID_FaceDict dict;
Werner Lemberg44be4d52002-03-30 17:08:04 +0000152 FT_Face root = (FT_Face)&face->root;
153 FT_Fixed temp[6];
154 FT_Fixed temp_scale;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000155
Werner Lemberg29bac132001-03-11 11:28:39 +0000156
Werner Lemberge3c11d72000-06-16 06:49:56 +0000157 if ( parser->num_dict >= 0 )
David Turner04aa8002000-06-01 03:27:48 +0000158 {
159 dict = face->cid.font_dicts + parser->num_dict;
160 matrix = &dict->font_matrix;
David Turner34f1c2f2000-08-23 22:47:44 +0000161 offset = &dict->font_offset;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000162
David Turnerb08fe2d2002-08-27 20:20:29 +0000163 (void)cid_parser_to_fixed_array( parser, 6, temp, 3 );
David Turner34f1c2f2000-08-23 22:47:44 +0000164
Tom Kacvinsky025c2f32001-03-10 19:04:41 +0000165 temp_scale = ABS( temp[3] );
166
Werner Lemberg29bac132001-03-11 11:28:39 +0000167 /* Set Units per EM based on FontMatrix values. We set the value to */
168 /* `1000/temp_scale', because temp_scale was already multiplied by */
169 /* 1000 (in t1_tofixed(), from psobjs.c). */
David Turner37981102001-03-19 11:34:49 +0000170 root->units_per_EM = (FT_UShort)( FT_DivFix( 0x10000L,
David Turner09d55ce2001-05-11 18:08:58 +0000171 FT_DivFix( temp_scale, 1000 ) ) );
Tom Kacvinsky025c2f32001-03-10 19:04:41 +0000172
David Turner34f1c2f2000-08-23 22:47:44 +0000173 /* we need to scale the values by 1.0/temp[3] */
Tom Kacvinsky025c2f32001-03-10 19:04:41 +0000174 if ( temp_scale != 0x10000L )
David Turner34f1c2f2000-08-23 22:47:44 +0000175 {
Tom Kacvinsky025c2f32001-03-10 19:04:41 +0000176 temp[0] = FT_DivFix( temp[0], temp_scale );
177 temp[1] = FT_DivFix( temp[1], temp_scale );
178 temp[2] = FT_DivFix( temp[2], temp_scale );
179 temp[4] = FT_DivFix( temp[4], temp_scale );
180 temp[5] = FT_DivFix( temp[5], temp_scale );
David Turner34f1c2f2000-08-23 22:47:44 +0000181 temp[3] = 0x10000L;
182 }
183
David Turner04aa8002000-06-01 03:27:48 +0000184 matrix->xx = temp[0];
185 matrix->yx = temp[1];
186 matrix->xy = temp[2];
187 matrix->yy = temp[3];
Werner Lemberge4b32a52000-10-31 20:42:18 +0000188
Werner Lemberg6fbe4db2000-10-05 04:53:31 +0000189 /* note that the font offsets are expressed in integer font units */
David Turnerf00a4de2000-10-03 22:03:09 +0000190 offset->x = temp[4] >> 16;
191 offset->y = temp[5] >> 16;
David Turner04aa8002000-06-01 03:27:48 +0000192 }
Werner Lemberge3c11d72000-06-16 06:49:56 +0000193
Werner Lemberg1f7f0e82001-06-06 17:30:41 +0000194 return CID_Err_Ok; /* this is a callback function; */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000195 /* we must return an error code */
David Turner04aa8002000-06-01 03:27:48 +0000196 }
197
Werner Lemberge3c11d72000-06-16 06:49:56 +0000198
Werner Lemberg93616ec2001-06-27 19:46:12 +0000199 FT_CALLBACK_DEF( FT_Error )
David Turnerdee78132001-06-27 09:26:46 +0000200 parse_fd_array( CID_Face face,
201 CID_Parser* parser )
David Turner04aa8002000-06-01 03:27:48 +0000202 {
David Turner29644172002-02-28 18:59:37 +0000203 CID_FaceInfo cid = &face->cid;
Werner Lemberg44be4d52002-03-30 17:08:04 +0000204 FT_Memory memory = face->root.memory;
205 FT_Error error = CID_Err_Ok;
206 FT_Long num_dicts;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000207
208
David Turnerb08fe2d2002-08-27 20:20:29 +0000209 num_dicts = cid_parser_to_int( parser );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000210
David Turner04aa8002000-06-01 03:27:48 +0000211 if ( !cid->font_dicts )
212 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000213 FT_Int n;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000214
215
David Turnere459d742002-03-22 13:52:37 +0000216 if ( FT_NEW_ARRAY( cid->font_dicts, num_dicts ) )
David Turner04aa8002000-06-01 03:27:48 +0000217 goto Exit;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000218
David Turnerf9b8dec2000-06-16 19:34:52 +0000219 cid->num_dicts = (FT_UInt)num_dicts;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000220
221 /* don't forget to set a few defaults */
David Turner04aa8002000-06-01 03:27:48 +0000222 for ( n = 0; n < cid->num_dicts; n++ )
223 {
David Turner29644172002-02-28 18:59:37 +0000224 CID_FaceDict dict = cid->font_dicts + n;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000225
226
227 /* default value for lenIV */
David Turner04aa8002000-06-01 03:27:48 +0000228 dict->private_dict.lenIV = 4;
229 }
230 }
Werner Lemberge3c11d72000-06-16 06:49:56 +0000231
David Turner04aa8002000-06-01 03:27:48 +0000232 Exit:
233 return error;
234 }
235
236
David Turner04aa8002000-06-01 03:27:48 +0000237 static
David Turner4e7eeee2002-02-28 16:10:29 +0000238 const T1_FieldRec cid_field_records[] =
David Turner04aa8002000-06-01 03:27:48 +0000239 {
Werner Lemberg7fa51b52000-07-08 19:51:42 +0000240
Werner Lemberg1f7f0e82001-06-06 17:30:41 +0000241#include "cidtoken.h"
Werner Lemberg7fa51b52000-07-08 19:51:42 +0000242
Werner Lemberga959c3c2003-06-14 07:40:09 +0000243 T1_FIELD_CALLBACK( "FDArray", parse_fd_array )
David Turner34f1c2f2000-08-23 22:47:44 +0000244 T1_FIELD_CALLBACK( "FontMatrix", parse_font_matrix )
Werner Lembergfdc042b2003-06-12 04:59:07 +0000245
David Turner429978b2002-03-14 10:09:35 +0000246 { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 }
David Turner04aa8002000-06-01 03:27:48 +0000247 };
248
249
Werner Lemberg93616ec2001-06-27 19:46:12 +0000250 static FT_Error
251 cid_parse_dict( CID_Face face,
252 CID_Loader* loader,
253 FT_Byte* base,
254 FT_Long size )
David Turner04aa8002000-06-01 03:27:48 +0000255 {
Werner Lemberge3c11d72000-06-16 06:49:56 +0000256 CID_Parser* parser = &loader->parser;
257
David Turner04aa8002000-06-01 03:27:48 +0000258
David Turner34f1c2f2000-08-23 22:47:44 +0000259 parser->root.cursor = base;
260 parser->root.limit = base + size;
261 parser->root.error = 0;
David Turner04aa8002000-06-01 03:27:48 +0000262
263 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000264 FT_Byte* cur = base;
265 FT_Byte* limit = cur + size;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000266
David Turner04aa8002000-06-01 03:27:48 +0000267
268 for ( ;cur < limit; cur++ )
269 {
Werner Lemberge3c11d72000-06-16 06:49:56 +0000270 /* look for `%ADOBeginFontDict' */
David Turner04aa8002000-06-01 03:27:48 +0000271 if ( *cur == '%' && cur + 20 < limit &&
David Turnerd15bc0d2002-04-12 09:31:48 +0000272 ft_strncmp( (char*)cur, "%ADOBeginFontDict", 17 ) == 0 )
David Turner04aa8002000-06-01 03:27:48 +0000273 {
274 cur += 17;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000275
David Turner04aa8002000-06-01 03:27:48 +0000276 /* if /FDArray was found, then cid->num_dicts is > 0, and */
277 /* we can start increasing parser->num_dict */
278 if ( face->cid.num_dicts > 0 )
279 parser->num_dict++;
280 }
281 /* look for immediates */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000282 else if ( *cur == '/' && cur + 2 < limit )
David Turner04aa8002000-06-01 03:27:48 +0000283 {
Werner Lemberg1f8f4672003-05-07 10:39:45 +0000284 FT_Int len;
David Turner04aa8002000-06-01 03:27:48 +0000285
Werner Lemberge3c11d72000-06-16 06:49:56 +0000286
287 cur++;
288
Werner Lemberg1f8f4672003-05-07 10:39:45 +0000289 parser->root.cursor = cur;
290 cid_parser_skip_alpha( parser );
David Turner04aa8002000-06-01 03:27:48 +0000291
Werner Lemberg1f8f4672003-05-07 10:39:45 +0000292 len = (FT_Int)( parser->root.cursor - cur );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000293 if ( len > 0 && len < 22 )
David Turner04aa8002000-06-01 03:27:48 +0000294 {
Werner Lembergac39ecd2000-06-30 22:24:36 +0000295 /* now compare the immediate name to the keyword table */
David Turner4e7eeee2002-02-28 16:10:29 +0000296 T1_Field keyword = (T1_Field) cid_field_records;
David Turner04aa8002000-06-01 03:27:48 +0000297
Werner Lemberge3c11d72000-06-16 06:49:56 +0000298
David Turner04aa8002000-06-01 03:27:48 +0000299 for (;;)
300 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000301 FT_Byte* name;
David Turner04aa8002000-06-01 03:27:48 +0000302
David Turner04aa8002000-06-01 03:27:48 +0000303
David Turnerf9b8dec2000-06-16 19:34:52 +0000304 name = (FT_Byte*)keyword->ident;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000305 if ( !name )
306 break;
307
308 if ( cur[0] == name[0] &&
David Turnerd15bc0d2002-04-12 09:31:48 +0000309 len == (FT_Int)ft_strlen( (const char*)name ) )
David Turner04aa8002000-06-01 03:27:48 +0000310 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000311 FT_Int n;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000312
313
David Turner04aa8002000-06-01 03:27:48 +0000314 for ( n = 1; n < len; n++ )
Werner Lemberge3c11d72000-06-16 06:49:56 +0000315 if ( cur[n] != name[n] )
David Turner04aa8002000-06-01 03:27:48 +0000316 break;
317
Werner Lemberge3c11d72000-06-16 06:49:56 +0000318 if ( n >= len )
David Turner04aa8002000-06-01 03:27:48 +0000319 {
Werner Lemberge3c11d72000-06-16 06:49:56 +0000320 /* we found it - run the parsing callback */
David Turnerb08fe2d2002-08-27 20:20:29 +0000321 cid_parser_skip_spaces( parser );
Werner Lembergd1b74752000-08-24 16:29:15 +0000322 parser->root.error = cid_load_keyword( face,
323 loader,
324 keyword );
David Turner34f1c2f2000-08-23 22:47:44 +0000325 if ( parser->root.error )
326 return parser->root.error;
David Turner04aa8002000-06-01 03:27:48 +0000327
David Turner34f1c2f2000-08-23 22:47:44 +0000328 cur = parser->root.cursor;
David Turner04aa8002000-06-01 03:27:48 +0000329 break;
330 }
331 }
332 keyword++;
333 }
334 }
335 }
336 }
337 }
David Turner34f1c2f2000-08-23 22:47:44 +0000338 return parser->root.error;
David Turner04aa8002000-06-01 03:27:48 +0000339 }
340
341
David Turner04aa8002000-06-01 03:27:48 +0000342 /* read the subrmap and the subrs of each font dict */
Werner Lemberg93616ec2001-06-27 19:46:12 +0000343 static FT_Error
344 cid_read_subrs( CID_Face face )
David Turner04aa8002000-06-01 03:27:48 +0000345 {
Werner Lemberg75aae7d2003-06-12 07:11:05 +0000346 CID_FaceInfo cid = &face->cid;
347 FT_Memory memory = face->root.memory;
348 FT_Stream stream = face->root.stream;
349 FT_Error error;
350 FT_Int n;
351 CID_Subrs subr;
352 FT_UInt max_offsets = 0;
353 FT_ULong* offsets = 0;
354 PSAux_Service psaux = (PSAux_Service)face->psaux;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000355
356
David Turnere459d742002-03-22 13:52:37 +0000357 if ( FT_NEW_ARRAY( face->subrs, cid->num_dicts ) )
David Turner04aa8002000-06-01 03:27:48 +0000358 goto Exit;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000359
David Turner04aa8002000-06-01 03:27:48 +0000360 subr = face->subrs;
361 for ( n = 0; n < cid->num_dicts; n++, subr++ )
362 {
David Turner29644172002-02-28 18:59:37 +0000363 CID_FaceDict dict = cid->font_dicts + n;
Werner Lemberg44be4d52002-03-30 17:08:04 +0000364 FT_Int lenIV = dict->private_dict.lenIV;
365 FT_UInt count, num_subrs = dict->num_subrs;
366 FT_ULong data_len;
367 FT_Byte* p;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000368
369
David Turner04aa8002000-06-01 03:27:48 +0000370 /* reallocate offsets array if needed */
Werner Lemberge3c11d72000-06-16 06:49:56 +0000371 if ( num_subrs + 1 > max_offsets )
David Turner04aa8002000-06-01 03:27:48 +0000372 {
David Turnerf9b8dec2000-06-16 19:34:52 +0000373 FT_UInt new_max = ( num_subrs + 1 + 3 ) & -4;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000374
375
David Turnere459d742002-03-22 13:52:37 +0000376 if ( FT_RENEW_ARRAY( offsets, max_offsets, new_max ) )
David Turner04aa8002000-06-01 03:27:48 +0000377 goto Fail;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000378
David Turner04aa8002000-06-01 03:27:48 +0000379 max_offsets = new_max;
380 }
Werner Lemberge3c11d72000-06-16 06:49:56 +0000381
David Turner04aa8002000-06-01 03:27:48 +0000382 /* read the subrmap's offsets */
David Turner7d3a2642002-03-20 10:49:31 +0000383 if ( FT_STREAM_SEEK( cid->data_offset + dict->subrmap_offset ) ||
384 FT_FRAME_ENTER( ( num_subrs + 1 ) * dict->sd_bytes ) )
David Turner04aa8002000-06-01 03:27:48 +0000385 goto Fail;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000386
David Turner04aa8002000-06-01 03:27:48 +0000387 p = (FT_Byte*)stream->cursor;
388 for ( count = 0; count <= num_subrs; count++ )
David Turner81bb4ad2000-06-28 04:19:49 +0000389 offsets[count] = cid_get_offset( &p, (FT_Byte)dict->sd_bytes );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000390
David Turner7d3a2642002-03-20 10:49:31 +0000391 FT_FRAME_EXIT();
Werner Lemberge3c11d72000-06-16 06:49:56 +0000392
393 /* now, compute the size of subrs charstrings, */
394 /* allocate, and read them */
David Turner04aa8002000-06-01 03:27:48 +0000395 data_len = offsets[num_subrs] - offsets[0];
Werner Lemberge3c11d72000-06-16 06:49:56 +0000396
David Turnere459d742002-03-22 13:52:37 +0000397 if ( FT_NEW_ARRAY( subr->code, num_subrs + 1 ) ||
398 FT_ALLOC( subr->code[0], data_len ) )
David Turner04aa8002000-06-01 03:27:48 +0000399 goto Fail;
400
David Turner7d3a2642002-03-20 10:49:31 +0000401 if ( FT_STREAM_SEEK( cid->data_offset + offsets[0] ) ||
402 FT_STREAM_READ( subr->code[0], data_len ) )
David Turner3a664fc2001-12-21 15:26:19 +0000403 goto Fail;
David Turner04aa8002000-06-01 03:27:48 +0000404
405 /* set up pointers */
406 for ( count = 1; count <= num_subrs; count++ )
407 {
Werner Lemberg68e9f922002-09-27 11:09:23 +0000408 FT_ULong len;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000409
410
411 len = offsets[count] - offsets[count - 1];
412 subr->code[count] = subr->code[count - 1] + len;
David Turner04aa8002000-06-01 03:27:48 +0000413 }
414
Werner Lemberg9a8b5362001-03-12 22:33:52 +0000415 /* decrypt subroutines, but only if lenIV >= 0 */
Tom Kacvinsky68621132001-03-12 02:17:50 +0000416 if ( lenIV >= 0 )
David Turner04aa8002000-06-01 03:27:48 +0000417 {
Tom Kacvinsky68621132001-03-12 02:17:50 +0000418 for ( count = 0; count < num_subrs; count++ )
419 {
Werner Lemberg68e9f922002-09-27 11:09:23 +0000420 FT_ULong len;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000421
422
Tom Kacvinsky68621132001-03-12 02:17:50 +0000423 len = offsets[count + 1] - offsets[count];
Werner Lemberg75aae7d2003-06-12 07:11:05 +0000424 psaux->t1_decrypt( subr->code[count], len, 4330 );
Tom Kacvinsky68621132001-03-12 02:17:50 +0000425 }
David Turner04aa8002000-06-01 03:27:48 +0000426 }
427
428 subr->num_subrs = num_subrs;
429 }
430
431 Exit:
David Turnere459d742002-03-22 13:52:37 +0000432 FT_FREE( offsets );
David Turner04aa8002000-06-01 03:27:48 +0000433 return error;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000434
David Turner04aa8002000-06-01 03:27:48 +0000435 Fail:
Werner Lemberge3c11d72000-06-16 06:49:56 +0000436 if ( face->subrs )
David Turner04aa8002000-06-01 03:27:48 +0000437 {
438 for ( n = 0; n < cid->num_dicts; n++ )
439 {
Werner Lemberge3c11d72000-06-16 06:49:56 +0000440 if ( face->subrs[n].code )
David Turnere459d742002-03-22 13:52:37 +0000441 FT_FREE( face->subrs[n].code[0] );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000442
David Turnere459d742002-03-22 13:52:37 +0000443 FT_FREE( face->subrs[n].code );
David Turner04aa8002000-06-01 03:27:48 +0000444 }
David Turnere459d742002-03-22 13:52:37 +0000445 FT_FREE( face->subrs );
David Turner04aa8002000-06-01 03:27:48 +0000446 }
447 goto Exit;
448 }
449
Werner Lemberge3c11d72000-06-16 06:49:56 +0000450
Werner Lemberg93616ec2001-06-27 19:46:12 +0000451 static void
452 t1_init_loader( CID_Loader* loader,
453 CID_Face face )
David Turner04aa8002000-06-01 03:27:48 +0000454 {
David Turnerc6a92202000-07-04 18:12:13 +0000455 FT_UNUSED( face );
David Turner04aa8002000-06-01 03:27:48 +0000456
Werner Lembergb3d5e9c2002-07-28 05:05:24 +0000457 FT_MEM_ZERO( loader, sizeof ( *loader ) );
David Turner04aa8002000-06-01 03:27:48 +0000458 }
459
Werner Lemberge3c11d72000-06-16 06:49:56 +0000460
Werner Lemberg93616ec2001-06-27 19:46:12 +0000461 static void
462 t1_done_loader( CID_Loader* loader )
David Turner04aa8002000-06-01 03:27:48 +0000463 {
464 CID_Parser* parser = &loader->parser;
465
Werner Lemberge3c11d72000-06-16 06:49:56 +0000466
David Turner04aa8002000-06-01 03:27:48 +0000467 /* finalize parser */
David Turnerb08fe2d2002-08-27 20:20:29 +0000468 cid_parser_done( parser );
David Turner04aa8002000-06-01 03:27:48 +0000469 }
470
Werner Lemberge3c11d72000-06-16 06:49:56 +0000471
David Turnerbc82f1b2002-03-01 02:26:22 +0000472 FT_LOCAL_DEF( FT_Error )
David Turnerb08fe2d2002-08-27 20:20:29 +0000473 cid_face_open( CID_Face face )
David Turner04aa8002000-06-01 03:27:48 +0000474 {
Werner Lemberg44be4d52002-03-30 17:08:04 +0000475 CID_Loader loader;
476 CID_Parser* parser;
477 FT_Error error;
Werner Lemberge3c11d72000-06-16 06:49:56 +0000478
David Turner04aa8002000-06-01 03:27:48 +0000479
480 t1_init_loader( &loader, face );
481
482 parser = &loader.parser;
David Turnerb08fe2d2002-08-27 20:20:29 +0000483 error = cid_parser_new( parser, face->root.stream, face->root.memory,
David Turner4e7eeee2002-02-28 16:10:29 +0000484 (PSAux_Service)face->psaux );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000485 if ( error )
486 goto Exit;
David Turner04aa8002000-06-01 03:27:48 +0000487
David Turner34f1c2f2000-08-23 22:47:44 +0000488 error = cid_parse_dict( face, &loader,
489 parser->postscript,
490 parser->postscript_len );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000491 if ( error )
492 goto Exit;
David Turner04aa8002000-06-01 03:27:48 +0000493
494 face->cid.data_offset = loader.parser.data_offset;
495 error = cid_read_subrs( face );
Werner Lemberge3c11d72000-06-16 06:49:56 +0000496
David Turner04aa8002000-06-01 03:27:48 +0000497 Exit:
498 t1_done_loader( &loader );
499 return error;
500 }
Werner Lemberge3c11d72000-06-16 06:49:56 +0000501
502
503/* END */