/modules/freetype2/src/psaux/afmparse.c

http://github.com/zpao/v8monkey · C · 964 lines · 718 code · 197 blank · 49 comment · 124 complexity · d16e233056495797643b21e9257f802f MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* afmparse.c */
  4. /* */
  5. /* AFM parser (body). */
  6. /* */
  7. /* Copyright 2006, 2007, 2008, 2009, 2010 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. #include <ft2build.h>
  18. #include FT_FREETYPE_H
  19. #include FT_INTERNAL_POSTSCRIPT_AUX_H
  20. #include "afmparse.h"
  21. #include "psconv.h"
  22. #include "psauxerr.h"
  23. /***************************************************************************/
  24. /* */
  25. /* AFM_Stream */
  26. /* */
  27. /* The use of AFM_Stream is largely inspired by parseAFM.[ch] from t1lib. */
  28. /* */
  29. /* */
  30. enum
  31. {
  32. AFM_STREAM_STATUS_NORMAL,
  33. AFM_STREAM_STATUS_EOC,
  34. AFM_STREAM_STATUS_EOL,
  35. AFM_STREAM_STATUS_EOF
  36. };
  37. typedef struct AFM_StreamRec_
  38. {
  39. FT_Byte* cursor;
  40. FT_Byte* base;
  41. FT_Byte* limit;
  42. FT_Int status;
  43. } AFM_StreamRec;
  44. #ifndef EOF
  45. #define EOF -1
  46. #endif
  47. /* this works because empty lines are ignored */
  48. #define AFM_IS_NEWLINE( ch ) ( (ch) == '\r' || (ch) == '\n' )
  49. #define AFM_IS_EOF( ch ) ( (ch) == EOF || (ch) == '\x1a' )
  50. #define AFM_IS_SPACE( ch ) ( (ch) == ' ' || (ch) == '\t' )
  51. /* column separator; there is no `column' in the spec actually */
  52. #define AFM_IS_SEP( ch ) ( (ch) == ';' )
  53. #define AFM_GETC() \
  54. ( ( (stream)->cursor < (stream)->limit ) ? *(stream)->cursor++ \
  55. : EOF )
  56. #define AFM_STREAM_KEY_BEGIN( stream ) \
  57. (char*)( (stream)->cursor - 1 )
  58. #define AFM_STREAM_KEY_LEN( stream, key ) \
  59. ( (char*)(stream)->cursor - key - 1 )
  60. #define AFM_STATUS_EOC( stream ) \
  61. ( (stream)->status >= AFM_STREAM_STATUS_EOC )
  62. #define AFM_STATUS_EOL( stream ) \
  63. ( (stream)->status >= AFM_STREAM_STATUS_EOL )
  64. #define AFM_STATUS_EOF( stream ) \
  65. ( (stream)->status >= AFM_STREAM_STATUS_EOF )
  66. static int
  67. afm_stream_skip_spaces( AFM_Stream stream )
  68. {
  69. int ch = 0; /* make stupid compiler happy */
  70. if ( AFM_STATUS_EOC( stream ) )
  71. return ';';
  72. while ( 1 )
  73. {
  74. ch = AFM_GETC();
  75. if ( !AFM_IS_SPACE( ch ) )
  76. break;
  77. }
  78. if ( AFM_IS_NEWLINE( ch ) )
  79. stream->status = AFM_STREAM_STATUS_EOL;
  80. else if ( AFM_IS_SEP( ch ) )
  81. stream->status = AFM_STREAM_STATUS_EOC;
  82. else if ( AFM_IS_EOF( ch ) )
  83. stream->status = AFM_STREAM_STATUS_EOF;
  84. return ch;
  85. }
  86. /* read a key or value in current column */
  87. static char*
  88. afm_stream_read_one( AFM_Stream stream )
  89. {
  90. char* str;
  91. int ch;
  92. afm_stream_skip_spaces( stream );
  93. if ( AFM_STATUS_EOC( stream ) )
  94. return NULL;
  95. str = AFM_STREAM_KEY_BEGIN( stream );
  96. while ( 1 )
  97. {
  98. ch = AFM_GETC();
  99. if ( AFM_IS_SPACE( ch ) )
  100. break;
  101. else if ( AFM_IS_NEWLINE( ch ) )
  102. {
  103. stream->status = AFM_STREAM_STATUS_EOL;
  104. break;
  105. }
  106. else if ( AFM_IS_SEP( ch ) )
  107. {
  108. stream->status = AFM_STREAM_STATUS_EOC;
  109. break;
  110. }
  111. else if ( AFM_IS_EOF( ch ) )
  112. {
  113. stream->status = AFM_STREAM_STATUS_EOF;
  114. break;
  115. }
  116. }
  117. return str;
  118. }
  119. /* read a string (i.e., read to EOL) */
  120. static char*
  121. afm_stream_read_string( AFM_Stream stream )
  122. {
  123. char* str;
  124. int ch;
  125. afm_stream_skip_spaces( stream );
  126. if ( AFM_STATUS_EOL( stream ) )
  127. return NULL;
  128. str = AFM_STREAM_KEY_BEGIN( stream );
  129. /* scan to eol */
  130. while ( 1 )
  131. {
  132. ch = AFM_GETC();
  133. if ( AFM_IS_NEWLINE( ch ) )
  134. {
  135. stream->status = AFM_STREAM_STATUS_EOL;
  136. break;
  137. }
  138. else if ( AFM_IS_EOF( ch ) )
  139. {
  140. stream->status = AFM_STREAM_STATUS_EOF;
  141. break;
  142. }
  143. }
  144. return str;
  145. }
  146. /*************************************************************************/
  147. /* */
  148. /* AFM_Parser */
  149. /* */
  150. /* */
  151. /* all keys defined in Ch. 7-10 of 5004.AFM_Spec.pdf */
  152. typedef enum AFM_Token_
  153. {
  154. AFM_TOKEN_ASCENDER,
  155. AFM_TOKEN_AXISLABEL,
  156. AFM_TOKEN_AXISTYPE,
  157. AFM_TOKEN_B,
  158. AFM_TOKEN_BLENDAXISTYPES,
  159. AFM_TOKEN_BLENDDESIGNMAP,
  160. AFM_TOKEN_BLENDDESIGNPOSITIONS,
  161. AFM_TOKEN_C,
  162. AFM_TOKEN_CC,
  163. AFM_TOKEN_CH,
  164. AFM_TOKEN_CAPHEIGHT,
  165. AFM_TOKEN_CHARWIDTH,
  166. AFM_TOKEN_CHARACTERSET,
  167. AFM_TOKEN_CHARACTERS,
  168. AFM_TOKEN_DESCENDER,
  169. AFM_TOKEN_ENCODINGSCHEME,
  170. AFM_TOKEN_ENDAXIS,
  171. AFM_TOKEN_ENDCHARMETRICS,
  172. AFM_TOKEN_ENDCOMPOSITES,
  173. AFM_TOKEN_ENDDIRECTION,
  174. AFM_TOKEN_ENDFONTMETRICS,
  175. AFM_TOKEN_ENDKERNDATA,
  176. AFM_TOKEN_ENDKERNPAIRS,
  177. AFM_TOKEN_ENDTRACKKERN,
  178. AFM_TOKEN_ESCCHAR,
  179. AFM_TOKEN_FAMILYNAME,
  180. AFM_TOKEN_FONTBBOX,
  181. AFM_TOKEN_FONTNAME,
  182. AFM_TOKEN_FULLNAME,
  183. AFM_TOKEN_ISBASEFONT,
  184. AFM_TOKEN_ISCIDFONT,
  185. AFM_TOKEN_ISFIXEDPITCH,
  186. AFM_TOKEN_ISFIXEDV,
  187. AFM_TOKEN_ITALICANGLE,
  188. AFM_TOKEN_KP,
  189. AFM_TOKEN_KPH,
  190. AFM_TOKEN_KPX,
  191. AFM_TOKEN_KPY,
  192. AFM_TOKEN_L,
  193. AFM_TOKEN_MAPPINGSCHEME,
  194. AFM_TOKEN_METRICSSETS,
  195. AFM_TOKEN_N,
  196. AFM_TOKEN_NOTICE,
  197. AFM_TOKEN_PCC,
  198. AFM_TOKEN_STARTAXIS,
  199. AFM_TOKEN_STARTCHARMETRICS,
  200. AFM_TOKEN_STARTCOMPOSITES,
  201. AFM_TOKEN_STARTDIRECTION,
  202. AFM_TOKEN_STARTFONTMETRICS,
  203. AFM_TOKEN_STARTKERNDATA,
  204. AFM_TOKEN_STARTKERNPAIRS,
  205. AFM_TOKEN_STARTKERNPAIRS0,
  206. AFM_TOKEN_STARTKERNPAIRS1,
  207. AFM_TOKEN_STARTTRACKKERN,
  208. AFM_TOKEN_STDHW,
  209. AFM_TOKEN_STDVW,
  210. AFM_TOKEN_TRACKKERN,
  211. AFM_TOKEN_UNDERLINEPOSITION,
  212. AFM_TOKEN_UNDERLINETHICKNESS,
  213. AFM_TOKEN_VV,
  214. AFM_TOKEN_VVECTOR,
  215. AFM_TOKEN_VERSION,
  216. AFM_TOKEN_W,
  217. AFM_TOKEN_W0,
  218. AFM_TOKEN_W0X,
  219. AFM_TOKEN_W0Y,
  220. AFM_TOKEN_W1,
  221. AFM_TOKEN_W1X,
  222. AFM_TOKEN_W1Y,
  223. AFM_TOKEN_WX,
  224. AFM_TOKEN_WY,
  225. AFM_TOKEN_WEIGHT,
  226. AFM_TOKEN_WEIGHTVECTOR,
  227. AFM_TOKEN_XHEIGHT,
  228. N_AFM_TOKENS,
  229. AFM_TOKEN_UNKNOWN
  230. } AFM_Token;
  231. static const char* const afm_key_table[N_AFM_TOKENS] =
  232. {
  233. "Ascender",
  234. "AxisLabel",
  235. "AxisType",
  236. "B",
  237. "BlendAxisTypes",
  238. "BlendDesignMap",
  239. "BlendDesignPositions",
  240. "C",
  241. "CC",
  242. "CH",
  243. "CapHeight",
  244. "CharWidth",
  245. "CharacterSet",
  246. "Characters",
  247. "Descender",
  248. "EncodingScheme",
  249. "EndAxis",
  250. "EndCharMetrics",
  251. "EndComposites",
  252. "EndDirection",
  253. "EndFontMetrics",
  254. "EndKernData",
  255. "EndKernPairs",
  256. "EndTrackKern",
  257. "EscChar",
  258. "FamilyName",
  259. "FontBBox",
  260. "FontName",
  261. "FullName",
  262. "IsBaseFont",
  263. "IsCIDFont",
  264. "IsFixedPitch",
  265. "IsFixedV",
  266. "ItalicAngle",
  267. "KP",
  268. "KPH",
  269. "KPX",
  270. "KPY",
  271. "L",
  272. "MappingScheme",
  273. "MetricsSets",
  274. "N",
  275. "Notice",
  276. "PCC",
  277. "StartAxis",
  278. "StartCharMetrics",
  279. "StartComposites",
  280. "StartDirection",
  281. "StartFontMetrics",
  282. "StartKernData",
  283. "StartKernPairs",
  284. "StartKernPairs0",
  285. "StartKernPairs1",
  286. "StartTrackKern",
  287. "StdHW",
  288. "StdVW",
  289. "TrackKern",
  290. "UnderlinePosition",
  291. "UnderlineThickness",
  292. "VV",
  293. "VVector",
  294. "Version",
  295. "W",
  296. "W0",
  297. "W0X",
  298. "W0Y",
  299. "W1",
  300. "W1X",
  301. "W1Y",
  302. "WX",
  303. "WY",
  304. "Weight",
  305. "WeightVector",
  306. "XHeight"
  307. };
  308. /*
  309. * `afm_parser_read_vals' and `afm_parser_next_key' provide
  310. * high-level operations to an AFM_Stream. The rest of the
  311. * parser functions should use them without accessing the
  312. * AFM_Stream directly.
  313. */
  314. FT_LOCAL_DEF( FT_Int )
  315. afm_parser_read_vals( AFM_Parser parser,
  316. AFM_Value vals,
  317. FT_UInt n )
  318. {
  319. AFM_Stream stream = parser->stream;
  320. char* str;
  321. FT_UInt i;
  322. if ( n > AFM_MAX_ARGUMENTS )
  323. return 0;
  324. for ( i = 0; i < n; i++ )
  325. {
  326. FT_Offset len;
  327. AFM_Value val = vals + i;
  328. if ( val->type == AFM_VALUE_TYPE_STRING )
  329. str = afm_stream_read_string( stream );
  330. else
  331. str = afm_stream_read_one( stream );
  332. if ( !str )
  333. break;
  334. len = AFM_STREAM_KEY_LEN( stream, str );
  335. switch ( val->type )
  336. {
  337. case AFM_VALUE_TYPE_STRING:
  338. case AFM_VALUE_TYPE_NAME:
  339. {
  340. FT_Memory memory = parser->memory;
  341. FT_Error error;
  342. if ( !FT_QALLOC( val->u.s, len + 1 ) )
  343. {
  344. ft_memcpy( val->u.s, str, len );
  345. val->u.s[len] = '\0';
  346. }
  347. }
  348. break;
  349. case AFM_VALUE_TYPE_FIXED:
  350. val->u.f = PS_Conv_ToFixed( (FT_Byte**)(void*)&str,
  351. (FT_Byte*)str + len, 0 );
  352. break;
  353. case AFM_VALUE_TYPE_INTEGER:
  354. val->u.i = PS_Conv_ToInt( (FT_Byte**)(void*)&str,
  355. (FT_Byte*)str + len );
  356. break;
  357. case AFM_VALUE_TYPE_BOOL:
  358. val->u.b = FT_BOOL( len == 4 &&
  359. !ft_strncmp( str, "true", 4 ) );
  360. break;
  361. case AFM_VALUE_TYPE_INDEX:
  362. if ( parser->get_index )
  363. val->u.i = parser->get_index( str, len, parser->user_data );
  364. else
  365. val->u.i = 0;
  366. break;
  367. }
  368. }
  369. return i;
  370. }
  371. FT_LOCAL_DEF( char* )
  372. afm_parser_next_key( AFM_Parser parser,
  373. FT_Bool line,
  374. FT_Offset* len )
  375. {
  376. AFM_Stream stream = parser->stream;
  377. char* key = 0; /* make stupid compiler happy */
  378. if ( line )
  379. {
  380. while ( 1 )
  381. {
  382. /* skip current line */
  383. if ( !AFM_STATUS_EOL( stream ) )
  384. afm_stream_read_string( stream );
  385. stream->status = AFM_STREAM_STATUS_NORMAL;
  386. key = afm_stream_read_one( stream );
  387. /* skip empty line */
  388. if ( !key &&
  389. !AFM_STATUS_EOF( stream ) &&
  390. AFM_STATUS_EOL( stream ) )
  391. continue;
  392. break;
  393. }
  394. }
  395. else
  396. {
  397. while ( 1 )
  398. {
  399. /* skip current column */
  400. while ( !AFM_STATUS_EOC( stream ) )
  401. afm_stream_read_one( stream );
  402. stream->status = AFM_STREAM_STATUS_NORMAL;
  403. key = afm_stream_read_one( stream );
  404. /* skip empty column */
  405. if ( !key &&
  406. !AFM_STATUS_EOF( stream ) &&
  407. AFM_STATUS_EOC( stream ) )
  408. continue;
  409. break;
  410. }
  411. }
  412. if ( len )
  413. *len = ( key ) ? (FT_Offset)AFM_STREAM_KEY_LEN( stream, key )
  414. : 0;
  415. return key;
  416. }
  417. static AFM_Token
  418. afm_tokenize( const char* key,
  419. FT_Offset len )
  420. {
  421. int n;
  422. for ( n = 0; n < N_AFM_TOKENS; n++ )
  423. {
  424. if ( *( afm_key_table[n] ) == *key )
  425. {
  426. for ( ; n < N_AFM_TOKENS; n++ )
  427. {
  428. if ( *( afm_key_table[n] ) != *key )
  429. return AFM_TOKEN_UNKNOWN;
  430. if ( ft_strncmp( afm_key_table[n], key, len ) == 0 )
  431. return (AFM_Token) n;
  432. }
  433. }
  434. }
  435. return AFM_TOKEN_UNKNOWN;
  436. }
  437. FT_LOCAL_DEF( FT_Error )
  438. afm_parser_init( AFM_Parser parser,
  439. FT_Memory memory,
  440. FT_Byte* base,
  441. FT_Byte* limit )
  442. {
  443. AFM_Stream stream = NULL;
  444. FT_Error error;
  445. if ( FT_NEW( stream ) )
  446. return error;
  447. stream->cursor = stream->base = base;
  448. stream->limit = limit;
  449. /* don't skip the first line during the first call */
  450. stream->status = AFM_STREAM_STATUS_EOL;
  451. parser->memory = memory;
  452. parser->stream = stream;
  453. parser->FontInfo = NULL;
  454. parser->get_index = NULL;
  455. return PSaux_Err_Ok;
  456. }
  457. FT_LOCAL( void )
  458. afm_parser_done( AFM_Parser parser )
  459. {
  460. FT_Memory memory = parser->memory;
  461. FT_FREE( parser->stream );
  462. }
  463. FT_LOCAL_DEF( FT_Error )
  464. afm_parser_read_int( AFM_Parser parser,
  465. FT_Int* aint )
  466. {
  467. AFM_ValueRec val;
  468. val.type = AFM_VALUE_TYPE_INTEGER;
  469. if ( afm_parser_read_vals( parser, &val, 1 ) == 1 )
  470. {
  471. *aint = val.u.i;
  472. return PSaux_Err_Ok;
  473. }
  474. else
  475. return PSaux_Err_Syntax_Error;
  476. }
  477. static FT_Error
  478. afm_parse_track_kern( AFM_Parser parser )
  479. {
  480. AFM_FontInfo fi = parser->FontInfo;
  481. AFM_TrackKern tk;
  482. char* key;
  483. FT_Offset len;
  484. int n = -1;
  485. if ( afm_parser_read_int( parser, &fi->NumTrackKern ) )
  486. goto Fail;
  487. if ( fi->NumTrackKern )
  488. {
  489. FT_Memory memory = parser->memory;
  490. FT_Error error;
  491. if ( FT_QNEW_ARRAY( fi->TrackKerns, fi->NumTrackKern ) )
  492. return error;
  493. }
  494. while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
  495. {
  496. AFM_ValueRec shared_vals[5];
  497. switch ( afm_tokenize( key, len ) )
  498. {
  499. case AFM_TOKEN_TRACKKERN:
  500. n++;
  501. if ( n >= fi->NumTrackKern )
  502. goto Fail;
  503. tk = fi->TrackKerns + n;
  504. shared_vals[0].type = AFM_VALUE_TYPE_INTEGER;
  505. shared_vals[1].type = AFM_VALUE_TYPE_FIXED;
  506. shared_vals[2].type = AFM_VALUE_TYPE_FIXED;
  507. shared_vals[3].type = AFM_VALUE_TYPE_FIXED;
  508. shared_vals[4].type = AFM_VALUE_TYPE_FIXED;
  509. if ( afm_parser_read_vals( parser, shared_vals, 5 ) != 5 )
  510. goto Fail;
  511. tk->degree = shared_vals[0].u.i;
  512. tk->min_ptsize = shared_vals[1].u.f;
  513. tk->min_kern = shared_vals[2].u.f;
  514. tk->max_ptsize = shared_vals[3].u.f;
  515. tk->max_kern = shared_vals[4].u.f;
  516. /* is this correct? */
  517. if ( tk->degree < 0 && tk->min_kern > 0 )
  518. tk->min_kern = -tk->min_kern;
  519. break;
  520. case AFM_TOKEN_ENDTRACKKERN:
  521. case AFM_TOKEN_ENDKERNDATA:
  522. case AFM_TOKEN_ENDFONTMETRICS:
  523. fi->NumTrackKern = n + 1;
  524. return PSaux_Err_Ok;
  525. case AFM_TOKEN_UNKNOWN:
  526. break;
  527. default:
  528. goto Fail;
  529. }
  530. }
  531. Fail:
  532. return PSaux_Err_Syntax_Error;
  533. }
  534. #undef KERN_INDEX
  535. #define KERN_INDEX( g1, g2 ) ( ( (FT_ULong)g1 << 16 ) | g2 )
  536. /* compare two kerning pairs */
  537. FT_CALLBACK_DEF( int )
  538. afm_compare_kern_pairs( const void* a,
  539. const void* b )
  540. {
  541. AFM_KernPair kp1 = (AFM_KernPair)a;
  542. AFM_KernPair kp2 = (AFM_KernPair)b;
  543. FT_ULong index1 = KERN_INDEX( kp1->index1, kp1->index2 );
  544. FT_ULong index2 = KERN_INDEX( kp2->index1, kp2->index2 );
  545. if ( index1 > index2 )
  546. return 1;
  547. else if ( index1 < index2 )
  548. return -1;
  549. else
  550. return 0;
  551. }
  552. static FT_Error
  553. afm_parse_kern_pairs( AFM_Parser parser )
  554. {
  555. AFM_FontInfo fi = parser->FontInfo;
  556. AFM_KernPair kp;
  557. char* key;
  558. FT_Offset len;
  559. int n = -1;
  560. if ( afm_parser_read_int( parser, &fi->NumKernPair ) )
  561. goto Fail;
  562. if ( fi->NumKernPair )
  563. {
  564. FT_Memory memory = parser->memory;
  565. FT_Error error;
  566. if ( FT_QNEW_ARRAY( fi->KernPairs, fi->NumKernPair ) )
  567. return error;
  568. }
  569. while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
  570. {
  571. AFM_Token token = afm_tokenize( key, len );
  572. switch ( token )
  573. {
  574. case AFM_TOKEN_KP:
  575. case AFM_TOKEN_KPX:
  576. case AFM_TOKEN_KPY:
  577. {
  578. FT_Int r;
  579. AFM_ValueRec shared_vals[4];
  580. n++;
  581. if ( n >= fi->NumKernPair )
  582. goto Fail;
  583. kp = fi->KernPairs + n;
  584. shared_vals[0].type = AFM_VALUE_TYPE_INDEX;
  585. shared_vals[1].type = AFM_VALUE_TYPE_INDEX;
  586. shared_vals[2].type = AFM_VALUE_TYPE_INTEGER;
  587. shared_vals[3].type = AFM_VALUE_TYPE_INTEGER;
  588. r = afm_parser_read_vals( parser, shared_vals, 4 );
  589. if ( r < 3 )
  590. goto Fail;
  591. kp->index1 = shared_vals[0].u.i;
  592. kp->index2 = shared_vals[1].u.i;
  593. if ( token == AFM_TOKEN_KPY )
  594. {
  595. kp->x = 0;
  596. kp->y = shared_vals[2].u.i;
  597. }
  598. else
  599. {
  600. kp->x = shared_vals[2].u.i;
  601. kp->y = ( token == AFM_TOKEN_KP && r == 4 )
  602. ? shared_vals[3].u.i : 0;
  603. }
  604. }
  605. break;
  606. case AFM_TOKEN_ENDKERNPAIRS:
  607. case AFM_TOKEN_ENDKERNDATA:
  608. case AFM_TOKEN_ENDFONTMETRICS:
  609. fi->NumKernPair = n + 1;
  610. ft_qsort( fi->KernPairs, fi->NumKernPair,
  611. sizeof( AFM_KernPairRec ),
  612. afm_compare_kern_pairs );
  613. return PSaux_Err_Ok;
  614. case AFM_TOKEN_UNKNOWN:
  615. break;
  616. default:
  617. goto Fail;
  618. }
  619. }
  620. Fail:
  621. return PSaux_Err_Syntax_Error;
  622. }
  623. static FT_Error
  624. afm_parse_kern_data( AFM_Parser parser )
  625. {
  626. FT_Error error;
  627. char* key;
  628. FT_Offset len;
  629. while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
  630. {
  631. switch ( afm_tokenize( key, len ) )
  632. {
  633. case AFM_TOKEN_STARTTRACKKERN:
  634. error = afm_parse_track_kern( parser );
  635. if ( error )
  636. return error;
  637. break;
  638. case AFM_TOKEN_STARTKERNPAIRS:
  639. case AFM_TOKEN_STARTKERNPAIRS0:
  640. error = afm_parse_kern_pairs( parser );
  641. if ( error )
  642. return error;
  643. break;
  644. case AFM_TOKEN_ENDKERNDATA:
  645. case AFM_TOKEN_ENDFONTMETRICS:
  646. return PSaux_Err_Ok;
  647. case AFM_TOKEN_UNKNOWN:
  648. break;
  649. default:
  650. goto Fail;
  651. }
  652. }
  653. Fail:
  654. return PSaux_Err_Syntax_Error;
  655. }
  656. static FT_Error
  657. afm_parser_skip_section( AFM_Parser parser,
  658. FT_UInt n,
  659. AFM_Token end_section )
  660. {
  661. char* key;
  662. FT_Offset len;
  663. while ( n-- > 0 )
  664. {
  665. key = afm_parser_next_key( parser, 1, NULL );
  666. if ( !key )
  667. goto Fail;
  668. }
  669. while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
  670. {
  671. AFM_Token token = afm_tokenize( key, len );
  672. if ( token == end_section || token == AFM_TOKEN_ENDFONTMETRICS )
  673. return PSaux_Err_Ok;
  674. }
  675. Fail:
  676. return PSaux_Err_Syntax_Error;
  677. }
  678. FT_LOCAL_DEF( FT_Error )
  679. afm_parser_parse( AFM_Parser parser )
  680. {
  681. FT_Memory memory = parser->memory;
  682. AFM_FontInfo fi = parser->FontInfo;
  683. FT_Error error = PSaux_Err_Syntax_Error;
  684. char* key;
  685. FT_Offset len;
  686. FT_Int metrics_sets = 0;
  687. if ( !fi )
  688. return PSaux_Err_Invalid_Argument;
  689. key = afm_parser_next_key( parser, 1, &len );
  690. if ( !key || len != 16 ||
  691. ft_strncmp( key, "StartFontMetrics", 16 ) != 0 )
  692. return PSaux_Err_Unknown_File_Format;
  693. while ( ( key = afm_parser_next_key( parser, 1, &len ) ) != 0 )
  694. {
  695. AFM_ValueRec shared_vals[4];
  696. switch ( afm_tokenize( key, len ) )
  697. {
  698. case AFM_TOKEN_METRICSSETS:
  699. if ( afm_parser_read_int( parser, &metrics_sets ) )
  700. goto Fail;
  701. if ( metrics_sets != 0 && metrics_sets != 2 )
  702. {
  703. error = PSaux_Err_Unimplemented_Feature;
  704. goto Fail;
  705. }
  706. break;
  707. case AFM_TOKEN_ISCIDFONT:
  708. shared_vals[0].type = AFM_VALUE_TYPE_BOOL;
  709. if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
  710. goto Fail;
  711. fi->IsCIDFont = shared_vals[0].u.b;
  712. break;
  713. case AFM_TOKEN_FONTBBOX:
  714. shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
  715. shared_vals[1].type = AFM_VALUE_TYPE_FIXED;
  716. shared_vals[2].type = AFM_VALUE_TYPE_FIXED;
  717. shared_vals[3].type = AFM_VALUE_TYPE_FIXED;
  718. if ( afm_parser_read_vals( parser, shared_vals, 4 ) != 4 )
  719. goto Fail;
  720. fi->FontBBox.xMin = shared_vals[0].u.f;
  721. fi->FontBBox.yMin = shared_vals[1].u.f;
  722. fi->FontBBox.xMax = shared_vals[2].u.f;
  723. fi->FontBBox.yMax = shared_vals[3].u.f;
  724. break;
  725. case AFM_TOKEN_ASCENDER:
  726. shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
  727. if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
  728. goto Fail;
  729. fi->Ascender = shared_vals[0].u.f;
  730. break;
  731. case AFM_TOKEN_DESCENDER:
  732. shared_vals[0].type = AFM_VALUE_TYPE_FIXED;
  733. if ( afm_parser_read_vals( parser, shared_vals, 1 ) != 1 )
  734. goto Fail;
  735. fi->Descender = shared_vals[0].u.f;
  736. break;
  737. case AFM_TOKEN_STARTCHARMETRICS:
  738. {
  739. FT_Int n = 0;
  740. if ( afm_parser_read_int( parser, &n ) )
  741. goto Fail;
  742. error = afm_parser_skip_section( parser, n,
  743. AFM_TOKEN_ENDCHARMETRICS );
  744. if ( error )
  745. return error;
  746. }
  747. break;
  748. case AFM_TOKEN_STARTKERNDATA:
  749. error = afm_parse_kern_data( parser );
  750. if ( error )
  751. goto Fail;
  752. /* fall through since we only support kern data */
  753. case AFM_TOKEN_ENDFONTMETRICS:
  754. return PSaux_Err_Ok;
  755. default:
  756. break;
  757. }
  758. }
  759. Fail:
  760. FT_FREE( fi->TrackKerns );
  761. fi->NumTrackKern = 0;
  762. FT_FREE( fi->KernPairs );
  763. fi->NumKernPair = 0;
  764. fi->IsCIDFont = 0;
  765. return error;
  766. }
  767. /* END */