/src/freetype/src/type1/t1load.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 2243 lines · 1489 code · 446 blank · 308 comment · 327 complexity · 75aa6f88e381913fe040e39a0a1d182e MD5 · raw file

Large files are truncated click here to view the full file

  1. /***************************************************************************/
  2. /* */
  3. /* t1load.c */
  4. /* */
  5. /* Type 1 font loader (body). */
  6. /* */
  7. /* Copyright 1996-2012 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. /* This is the new and improved Type 1 data loader for FreeType 2. The */
  20. /* old loader has several problems: it is slow, complex, difficult to */
  21. /* maintain, and contains incredible hacks to make it accept some */
  22. /* ill-formed Type 1 fonts without hiccup-ing. Moreover, about 5% of */
  23. /* the Type 1 fonts on my machine still aren't loaded correctly by it. */
  24. /* */
  25. /* This version is much simpler, much faster and also easier to read and */
  26. /* maintain by a great order of magnitude. The idea behind it is to */
  27. /* _not_ try to read the Type 1 token stream with a state machine (i.e. */
  28. /* a Postscript-like interpreter) but rather to perform simple pattern */
  29. /* matching. */
  30. /* */
  31. /* Indeed, nearly all data definitions follow a simple pattern like */
  32. /* */
  33. /* ... /Field <data> ... */
  34. /* */
  35. /* where <data> can be a number, a boolean, a string, or an array of */
  36. /* numbers. There are a few exceptions, namely the encoding, font name, */
  37. /* charstrings, and subrs; they are handled with a special pattern */
  38. /* matching routine. */
  39. /* */
  40. /* All other common cases are handled very simply. The matching rules */
  41. /* are defined in the file `t1tokens.h' through the use of several */
  42. /* macros calls PARSE_XXX. This file is included twice here; the first */
  43. /* time to generate parsing callback functions, the second time to */
  44. /* generate a table of keywords (with pointers to the associated */
  45. /* callback functions). */
  46. /* */
  47. /* The function `parse_dict' simply scans *linearly* a given dictionary */
  48. /* (either the top-level or private one) and calls the appropriate */
  49. /* callback when it encounters an immediate keyword. */
  50. /* */
  51. /* This is by far the fastest way one can find to parse and read all */
  52. /* data. */
  53. /* */
  54. /* This led to tremendous code size reduction. Note that later, the */
  55. /* glyph loader will also be _greatly_ simplified, and the automatic */
  56. /* hinter will replace the clumsy `t1hinter'. */
  57. /* */
  58. /*************************************************************************/
  59. #include <ft2build.h>
  60. #include FT_INTERNAL_DEBUG_H
  61. #include FT_CONFIG_CONFIG_H
  62. #include FT_MULTIPLE_MASTERS_H
  63. #include FT_INTERNAL_TYPE1_TYPES_H
  64. #include FT_INTERNAL_CALC_H
  65. #include "t1load.h"
  66. #include "t1errors.h"
  67. /*************************************************************************/
  68. /* */
  69. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  70. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  71. /* messages during execution. */
  72. /* */
  73. #undef FT_COMPONENT
  74. #define FT_COMPONENT trace_t1load
  75. #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
  76. /*************************************************************************/
  77. /*************************************************************************/
  78. /***** *****/
  79. /***** MULTIPLE MASTERS SUPPORT *****/
  80. /***** *****/
  81. /*************************************************************************/
  82. /*************************************************************************/
  83. static FT_Error
  84. t1_allocate_blend( T1_Face face,
  85. FT_UInt num_designs,
  86. FT_UInt num_axis )
  87. {
  88. PS_Blend blend;
  89. FT_Memory memory = face->root.memory;
  90. FT_Error error = T1_Err_Ok;
  91. blend = face->blend;
  92. if ( !blend )
  93. {
  94. if ( FT_NEW( blend ) )
  95. goto Exit;
  96. blend->num_default_design_vector = 0;
  97. face->blend = blend;
  98. }
  99. /* allocate design data if needed */
  100. if ( num_designs > 0 )
  101. {
  102. if ( blend->num_designs == 0 )
  103. {
  104. FT_UInt nn;
  105. /* allocate the blend `private' and `font_info' dictionaries */
  106. if ( FT_NEW_ARRAY( blend->font_infos[1], num_designs ) ||
  107. FT_NEW_ARRAY( blend->privates[1], num_designs ) ||
  108. FT_NEW_ARRAY( blend->bboxes[1], num_designs ) ||
  109. FT_NEW_ARRAY( blend->weight_vector, num_designs * 2 ) )
  110. goto Exit;
  111. blend->default_weight_vector = blend->weight_vector + num_designs;
  112. blend->font_infos[0] = &face->type1.font_info;
  113. blend->privates [0] = &face->type1.private_dict;
  114. blend->bboxes [0] = &face->type1.font_bbox;
  115. for ( nn = 2; nn <= num_designs; nn++ )
  116. {
  117. blend->privates[nn] = blend->privates [nn - 1] + 1;
  118. blend->font_infos[nn] = blend->font_infos[nn - 1] + 1;
  119. blend->bboxes[nn] = blend->bboxes [nn - 1] + 1;
  120. }
  121. blend->num_designs = num_designs;
  122. }
  123. else if ( blend->num_designs != num_designs )
  124. goto Fail;
  125. }
  126. /* allocate axis data if needed */
  127. if ( num_axis > 0 )
  128. {
  129. if ( blend->num_axis != 0 && blend->num_axis != num_axis )
  130. goto Fail;
  131. blend->num_axis = num_axis;
  132. }
  133. /* allocate the blend design pos table if needed */
  134. num_designs = blend->num_designs;
  135. num_axis = blend->num_axis;
  136. if ( num_designs && num_axis && blend->design_pos[0] == 0 )
  137. {
  138. FT_UInt n;
  139. if ( FT_NEW_ARRAY( blend->design_pos[0], num_designs * num_axis ) )
  140. goto Exit;
  141. for ( n = 1; n < num_designs; n++ )
  142. blend->design_pos[n] = blend->design_pos[0] + num_axis * n;
  143. }
  144. Exit:
  145. return error;
  146. Fail:
  147. error = T1_Err_Invalid_File_Format;
  148. goto Exit;
  149. }
  150. FT_LOCAL_DEF( FT_Error )
  151. T1_Get_Multi_Master( T1_Face face,
  152. FT_Multi_Master* master )
  153. {
  154. PS_Blend blend = face->blend;
  155. FT_UInt n;
  156. FT_Error error;
  157. error = T1_Err_Invalid_Argument;
  158. if ( blend )
  159. {
  160. master->num_axis = blend->num_axis;
  161. master->num_designs = blend->num_designs;
  162. for ( n = 0; n < blend->num_axis; n++ )
  163. {
  164. FT_MM_Axis* axis = master->axis + n;
  165. PS_DesignMap map = blend->design_map + n;
  166. axis->name = blend->axis_names[n];
  167. axis->minimum = map->design_points[0];
  168. axis->maximum = map->design_points[map->num_points - 1];
  169. }
  170. error = T1_Err_Ok;
  171. }
  172. return error;
  173. }
  174. /*************************************************************************/
  175. /* */
  176. /* Given a normalized (blend) coordinate, figure out the design */
  177. /* coordinate appropriate for that value. */
  178. /* */
  179. FT_LOCAL_DEF( FT_Fixed )
  180. mm_axis_unmap( PS_DesignMap axismap,
  181. FT_Fixed ncv )
  182. {
  183. int j;
  184. if ( ncv <= axismap->blend_points[0] )
  185. return INT_TO_FIXED( axismap->design_points[0] );
  186. for ( j = 1; j < axismap->num_points; ++j )
  187. {
  188. if ( ncv <= axismap->blend_points[j] )
  189. {
  190. FT_Fixed t = FT_MulDiv( ncv - axismap->blend_points[j - 1],
  191. 0x10000L,
  192. axismap->blend_points[j] -
  193. axismap->blend_points[j - 1] );
  194. return INT_TO_FIXED( axismap->design_points[j - 1] ) +
  195. FT_MulDiv( t,
  196. axismap->design_points[j] -
  197. axismap->design_points[j - 1],
  198. 1L );
  199. }
  200. }
  201. return INT_TO_FIXED( axismap->design_points[axismap->num_points - 1] );
  202. }
  203. /*************************************************************************/
  204. /* */
  205. /* Given a vector of weights, one for each design, figure out the */
  206. /* normalized axis coordinates which gave rise to those weights. */
  207. /* */
  208. FT_LOCAL_DEF( void )
  209. mm_weights_unmap( FT_Fixed* weights,
  210. FT_Fixed* axiscoords,
  211. FT_UInt axis_count )
  212. {
  213. FT_ASSERT( axis_count <= T1_MAX_MM_AXIS );
  214. if ( axis_count == 1 )
  215. axiscoords[0] = weights[1];
  216. else if ( axis_count == 2 )
  217. {
  218. axiscoords[0] = weights[3] + weights[1];
  219. axiscoords[1] = weights[3] + weights[2];
  220. }
  221. else if ( axis_count == 3 )
  222. {
  223. axiscoords[0] = weights[7] + weights[5] + weights[3] + weights[1];
  224. axiscoords[1] = weights[7] + weights[6] + weights[3] + weights[2];
  225. axiscoords[2] = weights[7] + weights[6] + weights[5] + weights[4];
  226. }
  227. else
  228. {
  229. axiscoords[0] = weights[15] + weights[13] + weights[11] + weights[9] +
  230. weights[7] + weights[5] + weights[3] + weights[1];
  231. axiscoords[1] = weights[15] + weights[14] + weights[11] + weights[10] +
  232. weights[7] + weights[6] + weights[3] + weights[2];
  233. axiscoords[2] = weights[15] + weights[14] + weights[13] + weights[12] +
  234. weights[7] + weights[6] + weights[5] + weights[4];
  235. axiscoords[3] = weights[15] + weights[14] + weights[13] + weights[12] +
  236. weights[11] + weights[10] + weights[9] + weights[8];
  237. }
  238. }
  239. /*************************************************************************/
  240. /* */
  241. /* Just a wrapper around T1_Get_Multi_Master to support the different */
  242. /* arguments needed by the GX var distortable fonts. */
  243. /* */
  244. FT_LOCAL_DEF( FT_Error )
  245. T1_Get_MM_Var( T1_Face face,
  246. FT_MM_Var* *master )
  247. {
  248. FT_Memory memory = face->root.memory;
  249. FT_MM_Var *mmvar = NULL;
  250. FT_Multi_Master mmaster;
  251. FT_Error error;
  252. FT_UInt i;
  253. FT_Fixed axiscoords[T1_MAX_MM_AXIS];
  254. PS_Blend blend = face->blend;
  255. error = T1_Get_Multi_Master( face, &mmaster );
  256. if ( error )
  257. goto Exit;
  258. if ( FT_ALLOC( mmvar,
  259. sizeof ( FT_MM_Var ) +
  260. mmaster.num_axis * sizeof ( FT_Var_Axis ) ) )
  261. goto Exit;
  262. mmvar->num_axis = mmaster.num_axis;
  263. mmvar->num_designs = mmaster.num_designs;
  264. mmvar->num_namedstyles = (FT_UInt)-1; /* Does not apply */
  265. mmvar->axis = (FT_Var_Axis*)&mmvar[1];
  266. /* Point to axes after MM_Var struct */
  267. mmvar->namedstyle = NULL;
  268. for ( i = 0 ; i < mmaster.num_axis; ++i )
  269. {
  270. mmvar->axis[i].name = mmaster.axis[i].name;
  271. mmvar->axis[i].minimum = INT_TO_FIXED( mmaster.axis[i].minimum);
  272. mmvar->axis[i].maximum = INT_TO_FIXED( mmaster.axis[i].maximum);
  273. mmvar->axis[i].def = ( mmvar->axis[i].minimum +
  274. mmvar->axis[i].maximum ) / 2;
  275. /* Does not apply. But this value is in range */
  276. mmvar->axis[i].strid = (FT_UInt)-1; /* Does not apply */
  277. mmvar->axis[i].tag = (FT_ULong)-1; /* Does not apply */
  278. if ( ft_strcmp( mmvar->axis[i].name, "Weight" ) == 0 )
  279. mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'g', 'h', 't' );
  280. else if ( ft_strcmp( mmvar->axis[i].name, "Width" ) == 0 )
  281. mmvar->axis[i].tag = FT_MAKE_TAG( 'w', 'd', 't', 'h' );
  282. else if ( ft_strcmp( mmvar->axis[i].name, "OpticalSize" ) == 0 )
  283. mmvar->axis[i].tag = FT_MAKE_TAG( 'o', 'p', 's', 'z' );
  284. }
  285. if ( blend->num_designs == ( 1U << blend->num_axis ) )
  286. {
  287. mm_weights_unmap( blend->default_weight_vector,
  288. axiscoords,
  289. blend->num_axis );
  290. for ( i = 0; i < mmaster.num_axis; ++i )
  291. mmvar->axis[i].def = mm_axis_unmap( &blend->design_map[i],
  292. axiscoords[i] );
  293. }
  294. *master = mmvar;
  295. Exit:
  296. return error;
  297. }
  298. FT_LOCAL_DEF( FT_Error )
  299. T1_Set_MM_Blend( T1_Face face,
  300. FT_UInt num_coords,
  301. FT_Fixed* coords )
  302. {
  303. PS_Blend blend = face->blend;
  304. FT_Error error;
  305. FT_UInt n, m;
  306. error = T1_Err_Invalid_Argument;
  307. if ( blend && blend->num_axis == num_coords )
  308. {
  309. /* recompute the weight vector from the blend coordinates */
  310. error = T1_Err_Ok;
  311. for ( n = 0; n < blend->num_designs; n++ )
  312. {
  313. FT_Fixed result = 0x10000L; /* 1.0 fixed */
  314. for ( m = 0; m < blend->num_axis; m++ )
  315. {
  316. FT_Fixed factor;
  317. /* get current blend axis position */
  318. factor = coords[m];
  319. if ( factor < 0 ) factor = 0;
  320. if ( factor > 0x10000L ) factor = 0x10000L;
  321. if ( ( n & ( 1 << m ) ) == 0 )
  322. factor = 0x10000L - factor;
  323. result = FT_MulFix( result, factor );
  324. }
  325. blend->weight_vector[n] = result;
  326. }
  327. error = T1_Err_Ok;
  328. }
  329. return error;
  330. }
  331. FT_LOCAL_DEF( FT_Error )
  332. T1_Set_MM_Design( T1_Face face,
  333. FT_UInt num_coords,
  334. FT_Long* coords )
  335. {
  336. PS_Blend blend = face->blend;
  337. FT_Error error;
  338. FT_UInt n, p;
  339. error = T1_Err_Invalid_Argument;
  340. if ( blend && blend->num_axis == num_coords )
  341. {
  342. /* compute the blend coordinates through the blend design map */
  343. FT_Fixed final_blends[T1_MAX_MM_DESIGNS];
  344. for ( n = 0; n < blend->num_axis; n++ )
  345. {
  346. FT_Long design = coords[n];
  347. FT_Fixed the_blend;
  348. PS_DesignMap map = blend->design_map + n;
  349. FT_Long* designs = map->design_points;
  350. FT_Fixed* blends = map->blend_points;
  351. FT_Int before = -1, after = -1;
  352. for ( p = 0; p < (FT_UInt)map->num_points; p++ )
  353. {
  354. FT_Long p_design = designs[p];
  355. /* exact match? */
  356. if ( design == p_design )
  357. {
  358. the_blend = blends[p];
  359. goto Found;
  360. }
  361. if ( design < p_design )
  362. {
  363. after = p;
  364. break;
  365. }
  366. before = p;
  367. }
  368. /* now interpolate if necessary */
  369. if ( before < 0 )
  370. the_blend = blends[0];
  371. else if ( after < 0 )
  372. the_blend = blends[map->num_points - 1];
  373. else
  374. the_blend = FT_MulDiv( design - designs[before],
  375. blends [after] - blends [before],
  376. designs[after] - designs[before] );
  377. Found:
  378. final_blends[n] = the_blend;
  379. }
  380. error = T1_Set_MM_Blend( face, num_coords, final_blends );
  381. }
  382. return error;
  383. }
  384. /*************************************************************************/
  385. /* */
  386. /* Just a wrapper around T1_Set_MM_Design to support the different */
  387. /* arguments needed by the GX var distortable fonts. */
  388. /* */
  389. FT_LOCAL_DEF( FT_Error )
  390. T1_Set_Var_Design( T1_Face face,
  391. FT_UInt num_coords,
  392. FT_Fixed* coords )
  393. {
  394. FT_Long lcoords[4]; /* maximum axis count is 4 */
  395. FT_UInt i;
  396. FT_Error error;
  397. error = T1_Err_Invalid_Argument;
  398. if ( num_coords <= 4 && num_coords > 0 )
  399. {
  400. for ( i = 0; i < num_coords; ++i )
  401. lcoords[i] = FIXED_TO_INT( coords[i] );
  402. error = T1_Set_MM_Design( face, num_coords, lcoords );
  403. }
  404. return error;
  405. }
  406. FT_LOCAL_DEF( void )
  407. T1_Done_Blend( T1_Face face )
  408. {
  409. FT_Memory memory = face->root.memory;
  410. PS_Blend blend = face->blend;
  411. if ( blend )
  412. {
  413. FT_UInt num_designs = blend->num_designs;
  414. FT_UInt num_axis = blend->num_axis;
  415. FT_UInt n;
  416. /* release design pos table */
  417. FT_FREE( blend->design_pos[0] );
  418. for ( n = 1; n < num_designs; n++ )
  419. blend->design_pos[n] = 0;
  420. /* release blend `private' and `font info' dictionaries */
  421. FT_FREE( blend->privates[1] );
  422. FT_FREE( blend->font_infos[1] );
  423. FT_FREE( blend->bboxes[1] );
  424. for ( n = 0; n < num_designs; n++ )
  425. {
  426. blend->privates [n] = 0;
  427. blend->font_infos[n] = 0;
  428. blend->bboxes [n] = 0;
  429. }
  430. /* release weight vectors */
  431. FT_FREE( blend->weight_vector );
  432. blend->default_weight_vector = 0;
  433. /* release axis names */
  434. for ( n = 0; n < num_axis; n++ )
  435. FT_FREE( blend->axis_names[n] );
  436. /* release design map */
  437. for ( n = 0; n < num_axis; n++ )
  438. {
  439. PS_DesignMap dmap = blend->design_map + n;
  440. FT_FREE( dmap->design_points );
  441. dmap->num_points = 0;
  442. }
  443. FT_FREE( face->blend );
  444. }
  445. }
  446. static void
  447. parse_blend_axis_types( T1_Face face,
  448. T1_Loader loader )
  449. {
  450. T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
  451. FT_Int n, num_axis;
  452. FT_Error error = T1_Err_Ok;
  453. PS_Blend blend;
  454. FT_Memory memory;
  455. /* take an array of objects */
  456. T1_ToTokenArray( &loader->parser, axis_tokens,
  457. T1_MAX_MM_AXIS, &num_axis );
  458. if ( num_axis < 0 )
  459. {
  460. error = T1_Err_Ignore;
  461. goto Exit;
  462. }
  463. if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
  464. {
  465. FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n",
  466. num_axis ));
  467. error = T1_Err_Invalid_File_Format;
  468. goto Exit;
  469. }
  470. /* allocate blend if necessary */
  471. error = t1_allocate_blend( face, 0, (FT_UInt)num_axis );
  472. if ( error )
  473. goto Exit;
  474. blend = face->blend;
  475. memory = face->root.memory;
  476. /* each token is an immediate containing the name of the axis */
  477. for ( n = 0; n < num_axis; n++ )
  478. {
  479. T1_Token token = axis_tokens + n;
  480. FT_Byte* name;
  481. FT_PtrDist len;
  482. /* skip first slash, if any */
  483. if ( token->start[0] == '/' )
  484. token->start++;
  485. len = token->limit - token->start;
  486. if ( len == 0 )
  487. {
  488. error = T1_Err_Invalid_File_Format;
  489. goto Exit;
  490. }
  491. if ( FT_ALLOC( blend->axis_names[n], len + 1 ) )
  492. goto Exit;
  493. name = (FT_Byte*)blend->axis_names[n];
  494. FT_MEM_COPY( name, token->start, len );
  495. name[len] = 0;
  496. }
  497. Exit:
  498. loader->parser.root.error = error;
  499. }
  500. static void
  501. parse_blend_design_positions( T1_Face face,
  502. T1_Loader loader )
  503. {
  504. T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
  505. FT_Int num_designs;
  506. FT_Int num_axis;
  507. T1_Parser parser = &loader->parser;
  508. FT_Error error = T1_Err_Ok;
  509. PS_Blend blend;
  510. /* get the array of design tokens -- compute number of designs */
  511. T1_ToTokenArray( parser, design_tokens,
  512. T1_MAX_MM_DESIGNS, &num_designs );
  513. if ( num_designs < 0 )
  514. {
  515. error = T1_Err_Ignore;
  516. goto Exit;
  517. }
  518. if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
  519. {
  520. FT_ERROR(( "parse_blend_design_positions:"
  521. " incorrect number of designs: %d\n",
  522. num_designs ));
  523. error = T1_Err_Invalid_File_Format;
  524. goto Exit;
  525. }
  526. {
  527. FT_Byte* old_cursor = parser->root.cursor;
  528. FT_Byte* old_limit = parser->root.limit;
  529. FT_Int n;
  530. blend = face->blend;
  531. num_axis = 0; /* make compiler happy */
  532. for ( n = 0; n < num_designs; n++ )
  533. {
  534. T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
  535. T1_Token token;
  536. FT_Int axis, n_axis;
  537. /* read axis/coordinates tokens */
  538. token = design_tokens + n;
  539. parser->root.cursor = token->start;
  540. parser->root.limit = token->limit;
  541. T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &n_axis );
  542. if ( n == 0 )
  543. {
  544. if ( n_axis <= 0 || n_axis > T1_MAX_MM_AXIS )
  545. {
  546. FT_ERROR(( "parse_blend_design_positions:"
  547. " invalid number of axes: %d\n",
  548. n_axis ));
  549. error = T1_Err_Invalid_File_Format;
  550. goto Exit;
  551. }
  552. num_axis = n_axis;
  553. error = t1_allocate_blend( face, num_designs, num_axis );
  554. if ( error )
  555. goto Exit;
  556. blend = face->blend;
  557. }
  558. else if ( n_axis != num_axis )
  559. {
  560. FT_ERROR(( "parse_blend_design_positions: incorrect table\n" ));
  561. error = T1_Err_Invalid_File_Format;
  562. goto Exit;
  563. }
  564. /* now read each axis token into the design position */
  565. for ( axis = 0; axis < n_axis; axis++ )
  566. {
  567. T1_Token token2 = axis_tokens + axis;
  568. parser->root.cursor = token2->start;
  569. parser->root.limit = token2->limit;
  570. blend->design_pos[n][axis] = T1_ToFixed( parser, 0 );
  571. }
  572. }
  573. loader->parser.root.cursor = old_cursor;
  574. loader->parser.root.limit = old_limit;
  575. }
  576. Exit:
  577. loader->parser.root.error = error;
  578. }
  579. static void
  580. parse_blend_design_map( T1_Face face,
  581. T1_Loader loader )
  582. {
  583. FT_Error error = T1_Err_Ok;
  584. T1_Parser parser = &loader->parser;
  585. PS_Blend blend;
  586. T1_TokenRec axis_tokens[T1_MAX_MM_AXIS];
  587. FT_Int n, num_axis;
  588. FT_Byte* old_cursor;
  589. FT_Byte* old_limit;
  590. FT_Memory memory = face->root.memory;
  591. T1_ToTokenArray( parser, axis_tokens,
  592. T1_MAX_MM_AXIS, &num_axis );
  593. if ( num_axis < 0 )
  594. {
  595. error = T1_Err_Ignore;
  596. goto Exit;
  597. }
  598. if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
  599. {
  600. FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n",
  601. num_axis ));
  602. error = T1_Err_Invalid_File_Format;
  603. goto Exit;
  604. }
  605. old_cursor = parser->root.cursor;
  606. old_limit = parser->root.limit;
  607. error = t1_allocate_blend( face, 0, num_axis );
  608. if ( error )
  609. goto Exit;
  610. blend = face->blend;
  611. /* now read each axis design map */
  612. for ( n = 0; n < num_axis; n++ )
  613. {
  614. PS_DesignMap map = blend->design_map + n;
  615. T1_Token axis_token;
  616. T1_TokenRec point_tokens[T1_MAX_MM_MAP_POINTS];
  617. FT_Int p, num_points;
  618. axis_token = axis_tokens + n;
  619. parser->root.cursor = axis_token->start;
  620. parser->root.limit = axis_token->limit;
  621. T1_ToTokenArray( parser, point_tokens,
  622. T1_MAX_MM_MAP_POINTS, &num_points );
  623. if ( num_points <= 0 || num_points > T1_MAX_MM_MAP_POINTS )
  624. {
  625. FT_ERROR(( "parse_blend_design_map: incorrect table\n" ));
  626. error = T1_Err_Invalid_File_Format;
  627. goto Exit;
  628. }
  629. /* allocate design map data */
  630. if ( FT_NEW_ARRAY( map->design_points, num_points * 2 ) )
  631. goto Exit;
  632. map->blend_points = map->design_points + num_points;
  633. map->num_points = (FT_Byte)num_points;
  634. for ( p = 0; p < num_points; p++ )
  635. {
  636. T1_Token point_token;
  637. point_token = point_tokens + p;
  638. /* don't include delimiting brackets */
  639. parser->root.cursor = point_token->start + 1;
  640. parser->root.limit = point_token->limit - 1;
  641. map->design_points[p] = T1_ToInt( parser );
  642. map->blend_points [p] = T1_ToFixed( parser, 0 );
  643. }
  644. }
  645. parser->root.cursor = old_cursor;
  646. parser->root.limit = old_limit;
  647. Exit:
  648. parser->root.error = error;
  649. }
  650. static void
  651. parse_weight_vector( T1_Face face,
  652. T1_Loader loader )
  653. {
  654. T1_TokenRec design_tokens[T1_MAX_MM_DESIGNS];
  655. FT_Int num_designs;
  656. FT_Error error = T1_Err_Ok;
  657. T1_Parser parser = &loader->parser;
  658. PS_Blend blend = face->blend;
  659. T1_Token token;
  660. FT_Int n;
  661. FT_Byte* old_cursor;
  662. FT_Byte* old_limit;
  663. T1_ToTokenArray( parser, design_tokens,
  664. T1_MAX_MM_DESIGNS, &num_designs );
  665. if ( num_designs < 0 )
  666. {
  667. error = T1_Err_Ignore;
  668. goto Exit;
  669. }
  670. if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
  671. {
  672. FT_ERROR(( "parse_weight_vector:"
  673. " incorrect number of designs: %d\n",
  674. num_designs ));
  675. error = T1_Err_Invalid_File_Format;
  676. goto Exit;
  677. }
  678. if ( !blend || !blend->num_designs )
  679. {
  680. error = t1_allocate_blend( face, num_designs, 0 );
  681. if ( error )
  682. goto Exit;
  683. blend = face->blend;
  684. }
  685. else if ( blend->num_designs != (FT_UInt)num_designs )
  686. {
  687. FT_ERROR(( "parse_weight_vector:"
  688. " /BlendDesignPosition and /WeightVector have\n"
  689. " "
  690. " different number of elements\n" ));
  691. error = T1_Err_Invalid_File_Format;
  692. goto Exit;
  693. }
  694. old_cursor = parser->root.cursor;
  695. old_limit = parser->root.limit;
  696. for ( n = 0; n < num_designs; n++ )
  697. {
  698. token = design_tokens + n;
  699. parser->root.cursor = token->start;
  700. parser->root.limit = token->limit;
  701. blend->default_weight_vector[n] =
  702. blend->weight_vector[n] = T1_ToFixed( parser, 0 );
  703. }
  704. parser->root.cursor = old_cursor;
  705. parser->root.limit = old_limit;
  706. Exit:
  707. parser->root.error = error;
  708. }
  709. /* e.g., /BuildCharArray [0 0 0 0 0 0 0 0] def */
  710. /* we're only interested in the number of array elements */
  711. static void
  712. parse_buildchar( T1_Face face,
  713. T1_Loader loader )
  714. {
  715. face->len_buildchar = T1_ToFixedArray( &loader->parser, 0, NULL, 0 );
  716. return;
  717. }
  718. #endif /* !T1_CONFIG_OPTION_NO_MM_SUPPORT */
  719. /*************************************************************************/
  720. /*************************************************************************/
  721. /***** *****/
  722. /***** TYPE 1 SYMBOL PARSING *****/
  723. /***** *****/
  724. /*************************************************************************/
  725. /*************************************************************************/
  726. static FT_Error
  727. t1_load_keyword( T1_Face face,
  728. T1_Loader loader,
  729. const T1_Field field )
  730. {
  731. FT_Error error;
  732. void* dummy_object;
  733. void** objects;
  734. FT_UInt max_objects;
  735. PS_Blend blend = face->blend;
  736. if ( blend && blend->num_designs == 0 )
  737. blend = NULL;
  738. /* if the keyword has a dedicated callback, call it */
  739. if ( field->type == T1_FIELD_TYPE_CALLBACK )
  740. {
  741. field->reader( (FT_Face)face, loader );
  742. error = loader->parser.root.error;
  743. goto Exit;
  744. }
  745. /* now, the keyword is either a simple field, or a table of fields; */
  746. /* we are now going to take care of it */
  747. switch ( field->location )
  748. {
  749. case T1_FIELD_LOCATION_FONT_INFO:
  750. dummy_object = &face->type1.font_info;
  751. objects = &dummy_object;
  752. max_objects = 0;
  753. if ( blend )
  754. {
  755. objects = (void**)blend->font_infos;
  756. max_objects = blend->num_designs;
  757. }
  758. break;
  759. case T1_FIELD_LOCATION_FONT_EXTRA:
  760. dummy_object = &face->type1.font_extra;
  761. objects = &dummy_object;
  762. max_objects = 0;
  763. break;
  764. case T1_FIELD_LOCATION_PRIVATE:
  765. dummy_object = &face->type1.private_dict;
  766. objects = &dummy_object;
  767. max_objects = 0;
  768. if ( blend )
  769. {
  770. objects = (void**)blend->privates;
  771. max_objects = blend->num_designs;
  772. }
  773. break;
  774. case T1_FIELD_LOCATION_BBOX:
  775. dummy_object = &face->type1.font_bbox;
  776. objects = &dummy_object;
  777. max_objects = 0;
  778. if ( blend )
  779. {
  780. objects = (void**)blend->bboxes;
  781. max_objects = blend->num_designs;
  782. }
  783. break;
  784. case T1_FIELD_LOCATION_LOADER:
  785. dummy_object = loader;
  786. objects = &dummy_object;
  787. max_objects = 0;
  788. break;
  789. case T1_FIELD_LOCATION_FACE:
  790. dummy_object = face;
  791. objects = &dummy_object;
  792. max_objects = 0;
  793. break;
  794. #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
  795. case T1_FIELD_LOCATION_BLEND:
  796. dummy_object = face->blend;
  797. objects = &dummy_object;
  798. max_objects = 0;
  799. break;
  800. #endif
  801. default:
  802. dummy_object = &face->type1;
  803. objects = &dummy_object;
  804. max_objects = 0;
  805. }
  806. if ( field->type == T1_FIELD_TYPE_INTEGER_ARRAY ||
  807. field->type == T1_FIELD_TYPE_FIXED_ARRAY )
  808. error = T1_Load_Field_Table( &loader->parser, field,
  809. objects, max_objects, 0 );
  810. else
  811. error = T1_Load_Field( &loader->parser, field,
  812. objects, max_objects, 0 );
  813. Exit:
  814. return error;
  815. }
  816. static void
  817. parse_private( T1_Face face,
  818. T1_Loader loader )
  819. {
  820. FT_UNUSED( face );
  821. loader->keywords_encountered |= T1_PRIVATE;
  822. }
  823. static int
  824. read_binary_data( T1_Parser parser,
  825. FT_Long* size,
  826. FT_Byte** base )
  827. {
  828. FT_Byte* cur;
  829. FT_Byte* limit = parser->root.limit;
  830. /* the binary data has one of the following formats */
  831. /* */
  832. /* `size' [white*] RD white ....... ND */
  833. /* `size' [white*] -| white ....... |- */
  834. /* */
  835. T1_Skip_Spaces( parser );
  836. cur = parser->root.cursor;
  837. if ( cur < limit && ft_isdigit( *cur ) )
  838. {
  839. FT_Long s = T1_ToInt( parser );
  840. T1_Skip_PS_Token( parser ); /* `RD' or `-|' or something else */
  841. /* there is only one whitespace char after the */
  842. /* `RD' or `-|' token */
  843. *base = parser->root.cursor + 1;
  844. if ( s >= 0 && s < limit - *base )
  845. {
  846. parser->root.cursor += s + 1;
  847. *size = s;
  848. return !parser->root.error;
  849. }
  850. }
  851. FT_ERROR(( "read_binary_data: invalid size field\n" ));
  852. parser->root.error = T1_Err_Invalid_File_Format;
  853. return 0;
  854. }
  855. /* We now define the routines to handle the `/Encoding', `/Subrs', */
  856. /* and `/CharStrings' dictionaries. */
  857. static void
  858. t1_parse_font_matrix( T1_Face face,
  859. T1_Loader loader )
  860. {
  861. T1_Parser parser = &loader->parser;
  862. FT_Matrix* matrix = &face->type1.font_matrix;
  863. FT_Vector* offset = &face->type1.font_offset;
  864. FT_Face root = (FT_Face)&face->root;
  865. FT_Fixed temp[6];
  866. FT_Fixed temp_scale;
  867. FT_Int result;
  868. result = T1_ToFixedArray( parser, 6, temp, 3 );
  869. if ( result < 0 )
  870. {
  871. parser->root.error = T1_Err_Invalid_File_Format;
  872. return;
  873. }
  874. temp_scale = FT_ABS( temp[3] );
  875. if ( temp_scale == 0 )
  876. {
  877. FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" ));
  878. parser->root.error = T1_Err_Invalid_File_Format;
  879. return;
  880. }
  881. /* Set Units per EM based on FontMatrix values. We set the value to */
  882. /* 1000 / temp_scale, because temp_scale was already multiplied by */
  883. /* 1000 (in t1_tofixed, from psobjs.c). */
  884. root->units_per_EM = (FT_UShort)( FT_DivFix( 1000 * 0x10000L,
  885. temp_scale ) >> 16 );
  886. /* we need to scale the values by 1.0/temp_scale */
  887. if ( temp_scale != 0x10000L )
  888. {
  889. temp[0] = FT_DivFix( temp[0], temp_scale );
  890. temp[1] = FT_DivFix( temp[1], temp_scale );
  891. temp[2] = FT_DivFix( temp[2], temp_scale );
  892. temp[4] = FT_DivFix( temp[4], temp_scale );
  893. temp[5] = FT_DivFix( temp[5], temp_scale );
  894. temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
  895. }
  896. matrix->xx = temp[0];
  897. matrix->yx = temp[1];
  898. matrix->xy = temp[2];
  899. matrix->yy = temp[3];
  900. /* note that the offsets must be expressed in integer font units */
  901. offset->x = temp[4] >> 16;
  902. offset->y = temp[5] >> 16;
  903. }
  904. static void
  905. parse_encoding( T1_Face face,
  906. T1_Loader loader )
  907. {
  908. T1_Parser parser = &loader->parser;
  909. FT_Byte* cur;
  910. FT_Byte* limit = parser->root.limit;
  911. PSAux_Service psaux = (PSAux_Service)face->psaux;
  912. T1_Skip_Spaces( parser );
  913. cur = parser->root.cursor;
  914. if ( cur >= limit )
  915. {
  916. FT_ERROR(( "parse_encoding: out of bounds\n" ));
  917. parser->root.error = T1_Err_Invalid_File_Format;
  918. return;
  919. }
  920. /* if we have a number or `[', the encoding is an array, */
  921. /* and we must load it now */
  922. if ( ft_isdigit( *cur ) || *cur == '[' )
  923. {
  924. T1_Encoding encode = &face->type1.encoding;
  925. FT_Int count, n;
  926. PS_Table char_table = &loader->encoding_table;
  927. FT_Memory memory = parser->root.memory;
  928. FT_Error error;
  929. FT_Bool only_immediates = 0;
  930. /* read the number of entries in the encoding; should be 256 */
  931. if ( *cur == '[' )
  932. {
  933. count = 256;
  934. only_immediates = 1;
  935. parser->root.cursor++;
  936. }
  937. else
  938. count = (FT_Int)T1_ToInt( parser );
  939. T1_Skip_Spaces( parser );
  940. if ( parser->root.cursor >= limit )
  941. return;
  942. /* we use a T1_Table to store our charnames */
  943. loader->num_chars = encode->num_chars = count;
  944. if ( FT_NEW_ARRAY( encode->char_index, count ) ||
  945. FT_NEW_ARRAY( encode->char_name, count ) ||
  946. FT_SET_ERROR( psaux->ps_table_funcs->init(
  947. char_table, count, memory ) ) )
  948. {
  949. parser->root.error = error;
  950. return;
  951. }
  952. /* We need to `zero' out encoding_table.elements */
  953. for ( n = 0; n < count; n++ )
  954. {
  955. char* notdef = (char *)".notdef";
  956. T1_Add_Table( char_table, n, notdef, 8 );
  957. }
  958. /* Now we need to read records of the form */
  959. /* */
  960. /* ... charcode /charname ... */
  961. /* */
  962. /* for each entry in our table. */
  963. /* */
  964. /* We simply look for a number followed by an immediate */
  965. /* name. Note that this ignores correctly the sequence */
  966. /* that is often seen in type1 fonts: */
  967. /* */
  968. /* 0 1 255 { 1 index exch /.notdef put } for dup */
  969. /* */
  970. /* used to clean the encoding array before anything else. */
  971. /* */
  972. /* Alternatively, if the array is directly given as */
  973. /* */
  974. /* /Encoding [ ... ] */
  975. /* */
  976. /* we only read immediates. */
  977. n = 0;
  978. T1_Skip_Spaces( parser );
  979. while ( parser->root.cursor < limit )
  980. {
  981. cur = parser->root.cursor;
  982. /* we stop when we encounter a `def' or `]' */
  983. if ( *cur == 'd' && cur + 3 < limit )
  984. {
  985. if ( cur[1] == 'e' &&
  986. cur[2] == 'f' &&
  987. IS_PS_DELIM( cur[3] ) )
  988. {
  989. FT_TRACE6(( "encoding end\n" ));
  990. cur += 3;
  991. break;
  992. }
  993. }
  994. if ( *cur == ']' )
  995. {
  996. FT_TRACE6(( "encoding end\n" ));
  997. cur++;
  998. break;
  999. }
  1000. /* check whether we've found an entry */
  1001. if ( ft_isdigit( *cur ) || only_immediates )
  1002. {
  1003. FT_Int charcode;
  1004. if ( only_immediates )
  1005. charcode = n;
  1006. else
  1007. {
  1008. charcode = (FT_Int)T1_ToInt( parser );
  1009. T1_Skip_Spaces( parser );
  1010. }
  1011. cur = parser->root.cursor;
  1012. if ( *cur == '/' && cur + 2 < limit && n < count )
  1013. {
  1014. FT_PtrDist len;
  1015. cur++;
  1016. parser->root.cursor = cur;
  1017. T1_Skip_PS_Token( parser );
  1018. if ( parser->root.error )
  1019. return;
  1020. len = parser->root.cursor - cur;
  1021. parser->root.error = T1_Add_Table( char_table, charcode,
  1022. cur, len + 1 );
  1023. if ( parser->root.error )
  1024. return;
  1025. char_table->elements[charcode][len] = '\0';
  1026. n++;
  1027. }
  1028. else if ( only_immediates )
  1029. {
  1030. /* Since the current position is not updated for */
  1031. /* immediates-only mode we would get an infinite loop if */
  1032. /* we don't do anything here. */
  1033. /* */
  1034. /* This encoding array is not valid according to the type1 */
  1035. /* specification (it might be an encoding for a CID type1 */
  1036. /* font, however), so we conclude that this font is NOT a */
  1037. /* type1 font. */
  1038. parser->root.error = FT_Err_Unknown_File_Format;
  1039. return;
  1040. }
  1041. }
  1042. else
  1043. {
  1044. T1_Skip_PS_Token( parser );
  1045. if ( parser->root.error )
  1046. return;
  1047. }
  1048. T1_Skip_Spaces( parser );
  1049. }
  1050. face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
  1051. parser->root.cursor = cur;
  1052. }
  1053. /* Otherwise, we should have either `StandardEncoding', */
  1054. /* `ExpertEncoding', or `ISOLatin1Encoding' */
  1055. else
  1056. {
  1057. if ( cur + 17 < limit &&
  1058. ft_strncmp( (const char*)cur, "StandardEncoding", 16 ) == 0 )
  1059. face->type1.encoding_type = T1_ENCODING_TYPE_STANDARD;
  1060. else if ( cur + 15 < limit &&
  1061. ft_strncmp( (const char*)cur, "ExpertEncoding", 14 ) == 0 )
  1062. face->type1.encoding_type = T1_ENCODING_TYPE_EXPERT;
  1063. else if ( cur + 18 < limit &&
  1064. ft_strncmp( (const char*)cur, "ISOLatin1Encoding", 17 ) == 0 )
  1065. face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
  1066. else
  1067. parser->root.error = T1_Err_Ignore;
  1068. }
  1069. }
  1070. static void
  1071. parse_subrs( T1_Face face,
  1072. T1_Loader loader )
  1073. {
  1074. T1_Parser parser = &loader->parser;
  1075. PS_Table table = &loader->subrs;
  1076. FT_Memory memory = parser->root.memory;
  1077. FT_Error error;
  1078. FT_Int num_subrs;
  1079. PSAux_Service psaux = (PSAux_Service)face->psaux;
  1080. T1_Skip_Spaces( parser );
  1081. /* test for empty array */
  1082. if ( parser->root.cursor < parser->root.limit &&
  1083. *parser->root.cursor == '[' )
  1084. {
  1085. T1_Skip_PS_Token( parser );
  1086. T1_Skip_Spaces ( parser );
  1087. if ( parser->root.cursor >= parser->root.limit ||
  1088. *parser->root.cursor != ']' )
  1089. parser->root.error = T1_Err_Invalid_File_Format;
  1090. return;
  1091. }
  1092. num_subrs = (FT_Int)T1_ToInt( parser );
  1093. /* position the parser right before the `dup' of the first subr */
  1094. T1_Skip_PS_Token( parser ); /* `array' */
  1095. if ( parser->root.error )
  1096. return;
  1097. T1_Skip_Spaces( parser );
  1098. /* initialize subrs array -- with synthetic fonts it is possible */
  1099. /* we get here twice */
  1100. if ( !loader->num_subrs )
  1101. {
  1102. error = psaux->ps_table_funcs->init( table, num_subrs, memory );
  1103. if ( error )
  1104. goto Fail;
  1105. }
  1106. /* the format is simple: */
  1107. /* */
  1108. /* `index' + binary data */
  1109. /* */
  1110. for (;;)
  1111. {
  1112. FT_Long idx, size;
  1113. FT_Byte* base;
  1114. /* If the next token isn't `dup' we are done. */
  1115. if ( parser->root.cursor + 4 < parser->root.limit &&
  1116. ft_strncmp( (char*)parser->root.cursor, "dup", 3 ) != 0 )
  1117. break;
  1118. T1_Skip_PS_Token( parser ); /* `dup' */
  1119. idx = T1_ToInt( parser );
  1120. if ( !read_binary_data( parser, &size, &base ) )
  1121. return;
  1122. /* The binary string is followed by one token, e.g. `NP' */
  1123. /* (bound to `noaccess put') or by two separate tokens: */
  1124. /* `noaccess' & `put'. We position the parser right */
  1125. /* before the next `dup', if any. */
  1126. T1_Skip_PS_Token( parser ); /* `NP' or `|' or `noaccess' */
  1127. if ( parser->root.error )
  1128. return;
  1129. T1_Skip_Spaces ( parser );
  1130. if ( parser->root.cursor + 4 < parser->root.limit &&
  1131. ft_strncmp( (char*)parser->root.cursor, "put", 3 ) == 0 )
  1132. {
  1133. T1_Skip_PS_Token( parser ); /* skip `put' */
  1134. T1_Skip_Spaces ( parser );
  1135. }
  1136. /* with synthetic fonts it is possible we get here twice */
  1137. if ( loader->num_subrs )
  1138. continue;
  1139. /* some fonts use a value of -1 for lenIV to indicate that */
  1140. /* the charstrings are unencoded */
  1141. /* */
  1142. /* thanks to Tom Kacvinsky for pointing this out */
  1143. /* */
  1144. if ( face->type1.private_dict.lenIV >= 0 )
  1145. {
  1146. FT_Byte* temp;
  1147. /* some fonts define empty subr records -- this is not totally */
  1148. /* compliant to the specification (which says they should at */
  1149. /* least contain a `return'), but we support them anyway */
  1150. if ( size < face->type1.private_dict.lenIV )
  1151. {
  1152. error = T1_Err_Invalid_File_Format;
  1153. goto Fail;
  1154. }
  1155. /* t1_decrypt() shouldn't write to base -- make temporary copy */
  1156. if ( FT_ALLOC( temp, size ) )
  1157. goto Fail;
  1158. FT_MEM_COPY( temp, base, size );
  1159. psaux->t1_decrypt( temp, size, 4330 );
  1160. size -= face->type1.private_dict.lenIV;
  1161. error = T1_Add_Table( table, (FT_Int)idx,
  1162. temp + face->type1.private_dict.lenIV, size );
  1163. FT_FREE( temp );
  1164. }
  1165. else
  1166. error = T1_Add_Table( table, (FT_Int)idx, base, size );
  1167. if ( error )
  1168. goto Fail;
  1169. }
  1170. if ( !loader->num_subrs )
  1171. loader->num_subrs = num_subrs;
  1172. return;
  1173. Fail:
  1174. parser->root.error = error;
  1175. }
  1176. #define TABLE_EXTEND 5
  1177. static void
  1178. parse_charstrings( T1_Face face,
  1179. T1_Loader loader )
  1180. {
  1181. T1_Parser parser = &loader->parser;
  1182. PS_Table code_table = &loader->charstrings;
  1183. PS_Table name_table = &loader->glyph_names;
  1184. PS_Table swap_table = &loader->swap_table;
  1185. FT_Memory memory = parser->root.memory;
  1186. FT_Error error;
  1187. PSAux_Service psaux = (PSAux_Service)face->psaux;
  1188. FT_Byte* cur;
  1189. FT_Byte* limit = parser->root.limit;
  1190. FT_Int n, num_glyphs;
  1191. FT_UInt notdef_index = 0;
  1192. FT_Byte notdef_found = 0;
  1193. num_glyphs = (FT_Int)T1_ToInt( parser );
  1194. /* some fonts like Optima-Oblique not only define the /CharStrings */
  1195. /* array but access it also */
  1196. if ( num_glyphs == 0 || parser->root.error )
  1197. return;
  1198. /* initialize tables, leaving space for addition of .notdef, */
  1199. /* if necessary, and a few other glyphs to handle buggy */
  1200. /* fonts which have more glyphs than specified. */
  1201. /* for some non-standard fonts like `Optima' which provides */
  1202. /* different outlines depending on the resolution it is */
  1203. /* possible to get here twice */
  1204. if ( !loader->num_glyphs )
  1205. {
  1206. error = psaux->ps_table_funcs->init(
  1207. code_table, num_glyphs + 1 + TABLE_EXTEND, memory );
  1208. if ( error )
  1209. goto Fail;
  1210. error = psaux->ps_table_funcs->init(
  1211. name_table, num_glyphs + 1 + TABLE_EXTEND, memory );
  1212. if ( error )
  1213. goto Fail;
  1214. /* Initialize table for swapping index notdef_index and */
  1215. /* index 0 names and codes (if necessary). */
  1216. error = psaux->ps_table_funcs->init( swap_table, 4, memory );
  1217. if ( error )
  1218. goto Fail;
  1219. }
  1220. n = 0;
  1221. for (;;)
  1222. {
  1223. FT_Long size;
  1224. FT_Byte* base;
  1225. /* the format is simple: */
  1226. /* `/glyphname' + binary data */
  1227. T1_Skip_Spaces( parser );
  1228. cur = parser->root.cursor;
  1229. if ( cur >= limit )
  1230. break;
  1231. /* we stop when we find a `def' or `end' keyword */
  1232. if ( cur + 3 < limit && IS_PS_DELIM( cur[3] ) )
  1233. {
  1234. if ( cur[0] == 'd' &&
  1235. cur[1] == 'e' &&
  1236. cur[2] == 'f' )
  1237. {
  1238. /* There are fonts which have this: */
  1239. /* */
  1240. /* /CharStrings 118 dict def */
  1241. /* Private begin */
  1242. /* CharStrings begin */
  1243. /* ... */
  1244. /* */
  1245. /* To catch this we ignore `def' if */
  1246. /* no charstring has actually been */
  1247. /* seen. */
  1248. if ( n )
  1249. break;
  1250. }
  1251. if ( cur[0] == 'e' &&
  1252. cur[1] == 'n' &&
  1253. cur[2] == 'd' )
  1254. break;
  1255. }
  1256. T1_Skip_PS_Token( parser );
  1257. if ( parser->root.error )
  1258. return;
  1259. if ( *cur == '/' )
  1260. {
  1261. FT_PtrDist len;
  1262. if ( cur + 1 >= limit )
  1263. {
  1264. error = T1_Err_Invalid_File_Format;
  1265. goto Fail;
  1266. }
  1267. cur++; /* skip `/' */
  1268. len = parser->root.cursor - cur;
  1269. if ( !read_binary_data( parser, &size, &base ) )
  1270. return;
  1271. /* for some non-standard fonts like `Optima' which provides */
  1272. /* different outlines depending on the resolution it is */
  1273. /* possible to get here twice */
  1274. if ( loader->num_glyphs )
  1275. continue;
  1276. error = T1_Add_Table( name_table, n, cur, len + 1 );
  1277. if ( error )
  1278. goto Fail;
  1279. /* add a trailing zero to the name table */
  1280. name_table->elements[n][len] = '\0';
  1281. /* record index of /.notdef */
  1282. if ( *cur == '.' &&
  1283. ft_strcmp( ".notdef",
  1284. (const char*)(name_table->elements[n]) ) == 0 )
  1285. {
  1286. notdef_index = n;
  1287. notdef_found = 1;
  1288. }