/src/compiler/android-ndk/jni/freetype/src/psaux/psobjs.c

http://ftk.googlecode.com/ · C · 1703 lines · 1087 code · 352 blank · 264 comment · 239 complexity · 719282cdc91110757039b342c1d64261 MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* psobjs.c */
  4. /* */
  5. /* Auxiliary functions for PostScript fonts (body). */
  6. /* */
  7. /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 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_INTERNAL_POSTSCRIPT_AUX_H
  19. #include FT_INTERNAL_DEBUG_H
  20. #include FT_INTERNAL_CALC_H
  21. #include "psobjs.h"
  22. #include "psconv.h"
  23. #include "psauxerr.h"
  24. /*************************************************************************/
  25. /* */
  26. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  27. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  28. /* messages during execution. */
  29. /* */
  30. #undef FT_COMPONENT
  31. #define FT_COMPONENT trace_psobjs
  32. /*************************************************************************/
  33. /*************************************************************************/
  34. /***** *****/
  35. /***** PS_TABLE *****/
  36. /***** *****/
  37. /*************************************************************************/
  38. /*************************************************************************/
  39. /*************************************************************************/
  40. /* */
  41. /* <Function> */
  42. /* ps_table_new */
  43. /* */
  44. /* <Description> */
  45. /* Initializes a PS_Table. */
  46. /* */
  47. /* <InOut> */
  48. /* table :: The address of the target table. */
  49. /* */
  50. /* <Input> */
  51. /* count :: The table size = the maximum number of elements. */
  52. /* */
  53. /* memory :: The memory object to use for all subsequent */
  54. /* reallocations. */
  55. /* */
  56. /* <Return> */
  57. /* FreeType error code. 0 means success. */
  58. /* */
  59. FT_LOCAL_DEF( FT_Error )
  60. ps_table_new( PS_Table table,
  61. FT_Int count,
  62. FT_Memory memory )
  63. {
  64. FT_Error error;
  65. table->memory = memory;
  66. if ( FT_NEW_ARRAY( table->elements, count ) ||
  67. FT_NEW_ARRAY( table->lengths, count ) )
  68. goto Exit;
  69. table->max_elems = count;
  70. table->init = 0xDEADBEEFUL;
  71. table->num_elems = 0;
  72. table->block = 0;
  73. table->capacity = 0;
  74. table->cursor = 0;
  75. *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs;
  76. Exit:
  77. if ( error )
  78. FT_FREE( table->elements );
  79. return error;
  80. }
  81. static void
  82. shift_elements( PS_Table table,
  83. FT_Byte* old_base )
  84. {
  85. FT_PtrDist delta = table->block - old_base;
  86. FT_Byte** offset = table->elements;
  87. FT_Byte** limit = offset + table->max_elems;
  88. for ( ; offset < limit; offset++ )
  89. {
  90. if ( offset[0] )
  91. offset[0] += delta;
  92. }
  93. }
  94. static FT_Error
  95. reallocate_t1_table( PS_Table table,
  96. FT_Long new_size )
  97. {
  98. FT_Memory memory = table->memory;
  99. FT_Byte* old_base = table->block;
  100. FT_Error error;
  101. /* allocate new base block */
  102. if ( FT_ALLOC( table->block, new_size ) )
  103. {
  104. table->block = old_base;
  105. return error;
  106. }
  107. /* copy elements and shift offsets */
  108. if ( old_base )
  109. {
  110. FT_MEM_COPY( table->block, old_base, table->capacity );
  111. shift_elements( table, old_base );
  112. FT_FREE( old_base );
  113. }
  114. table->capacity = new_size;
  115. return PSaux_Err_Ok;
  116. }
  117. /*************************************************************************/
  118. /* */
  119. /* <Function> */
  120. /* ps_table_add */
  121. /* */
  122. /* <Description> */
  123. /* Adds an object to a PS_Table, possibly growing its memory block. */
  124. /* */
  125. /* <InOut> */
  126. /* table :: The target table. */
  127. /* */
  128. /* <Input> */
  129. /* idx :: The index of the object in the table. */
  130. /* */
  131. /* object :: The address of the object to copy in memory. */
  132. /* */
  133. /* length :: The length in bytes of the source object. */
  134. /* */
  135. /* <Return> */
  136. /* FreeType error code. 0 means success. An error is returned if a */
  137. /* reallocation fails. */
  138. /* */
  139. FT_LOCAL_DEF( FT_Error )
  140. ps_table_add( PS_Table table,
  141. FT_Int idx,
  142. void* object,
  143. FT_PtrDist length )
  144. {
  145. if ( idx < 0 || idx >= table->max_elems )
  146. {
  147. FT_ERROR(( "ps_table_add: invalid index\n" ));
  148. return PSaux_Err_Invalid_Argument;
  149. }
  150. if ( length < 0 )
  151. {
  152. FT_ERROR(( "ps_table_add: invalid length\n" ));
  153. return PSaux_Err_Invalid_Argument;
  154. }
  155. /* grow the base block if needed */
  156. if ( table->cursor + length > table->capacity )
  157. {
  158. FT_Error error;
  159. FT_Offset new_size = table->capacity;
  160. FT_Long in_offset;
  161. in_offset = (FT_Long)((FT_Byte*)object - table->block);
  162. if ( (FT_ULong)in_offset >= table->capacity )
  163. in_offset = -1;
  164. while ( new_size < table->cursor + length )
  165. {
  166. /* increase size by 25% and round up to the nearest multiple
  167. of 1024 */
  168. new_size += ( new_size >> 2 ) + 1;
  169. new_size = FT_PAD_CEIL( new_size, 1024 );
  170. }
  171. error = reallocate_t1_table( table, new_size );
  172. if ( error )
  173. return error;
  174. if ( in_offset >= 0 )
  175. object = table->block + in_offset;
  176. }
  177. /* add the object to the base block and adjust offset */
  178. table->elements[idx] = table->block + table->cursor;
  179. table->lengths [idx] = length;
  180. FT_MEM_COPY( table->block + table->cursor, object, length );
  181. table->cursor += length;
  182. return PSaux_Err_Ok;
  183. }
  184. /*************************************************************************/
  185. /* */
  186. /* <Function> */
  187. /* ps_table_done */
  188. /* */
  189. /* <Description> */
  190. /* Finalizes a PS_TableRec (i.e., reallocate it to its current */
  191. /* cursor). */
  192. /* */
  193. /* <InOut> */
  194. /* table :: The target table. */
  195. /* */
  196. /* <Note> */
  197. /* This function does NOT release the heap's memory block. It is up */
  198. /* to the caller to clean it, or reference it in its own structures. */
  199. /* */
  200. FT_LOCAL_DEF( void )
  201. ps_table_done( PS_Table table )
  202. {
  203. FT_Memory memory = table->memory;
  204. FT_Error error;
  205. FT_Byte* old_base = table->block;
  206. /* should never fail, because rec.cursor <= rec.size */
  207. if ( !old_base )
  208. return;
  209. if ( FT_ALLOC( table->block, table->cursor ) )
  210. return;
  211. FT_MEM_COPY( table->block, old_base, table->cursor );
  212. shift_elements( table, old_base );
  213. table->capacity = table->cursor;
  214. FT_FREE( old_base );
  215. FT_UNUSED( error );
  216. }
  217. FT_LOCAL_DEF( void )
  218. ps_table_release( PS_Table table )
  219. {
  220. FT_Memory memory = table->memory;
  221. if ( (FT_ULong)table->init == 0xDEADBEEFUL )
  222. {
  223. FT_FREE( table->block );
  224. FT_FREE( table->elements );
  225. FT_FREE( table->lengths );
  226. table->init = 0;
  227. }
  228. }
  229. /*************************************************************************/
  230. /*************************************************************************/
  231. /***** *****/
  232. /***** T1 PARSER *****/
  233. /***** *****/
  234. /*************************************************************************/
  235. /*************************************************************************/
  236. /* first character must be already part of the comment */
  237. static void
  238. skip_comment( FT_Byte* *acur,
  239. FT_Byte* limit )
  240. {
  241. FT_Byte* cur = *acur;
  242. while ( cur < limit )
  243. {
  244. if ( IS_PS_NEWLINE( *cur ) )
  245. break;
  246. cur++;
  247. }
  248. *acur = cur;
  249. }
  250. static void
  251. skip_spaces( FT_Byte* *acur,
  252. FT_Byte* limit )
  253. {
  254. FT_Byte* cur = *acur;
  255. while ( cur < limit )
  256. {
  257. if ( !IS_PS_SPACE( *cur ) )
  258. {
  259. if ( *cur == '%' )
  260. /* According to the PLRM, a comment is equal to a space. */
  261. skip_comment( &cur, limit );
  262. else
  263. break;
  264. }
  265. cur++;
  266. }
  267. *acur = cur;
  268. }
  269. #define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' )
  270. /* first character must be `('; */
  271. /* *acur is positioned at the character after the closing `)' */
  272. static FT_Error
  273. skip_literal_string( FT_Byte* *acur,
  274. FT_Byte* limit )
  275. {
  276. FT_Byte* cur = *acur;
  277. FT_Int embed = 0;
  278. FT_Error error = PSaux_Err_Invalid_File_Format;
  279. unsigned int i;
  280. while ( cur < limit )
  281. {
  282. FT_Byte c = *cur;
  283. ++cur;
  284. if ( c == '\\' )
  285. {
  286. /* Red Book 3rd ed., section `Literal Text Strings', p. 29: */
  287. /* A backslash can introduce three different types */
  288. /* of escape sequences: */
  289. /* - a special escaped char like \r, \n, etc. */
  290. /* - a one-, two-, or three-digit octal number */
  291. /* - none of the above in which case the backslash is ignored */
  292. if ( cur == limit )
  293. /* error (or to be ignored?) */
  294. break;
  295. switch ( *cur )
  296. {
  297. /* skip `special' escape */
  298. case 'n':
  299. case 'r':
  300. case 't':
  301. case 'b':
  302. case 'f':
  303. case '\\':
  304. case '(':
  305. case ')':
  306. ++cur;
  307. break;
  308. default:
  309. /* skip octal escape or ignore backslash */
  310. for ( i = 0; i < 3 && cur < limit; ++i )
  311. {
  312. if ( !IS_OCTAL_DIGIT( *cur ) )
  313. break;
  314. ++cur;
  315. }
  316. }
  317. }
  318. else if ( c == '(' )
  319. embed++;
  320. else if ( c == ')' )
  321. {
  322. embed--;
  323. if ( embed == 0 )
  324. {
  325. error = PSaux_Err_Ok;
  326. break;
  327. }
  328. }
  329. }
  330. *acur = cur;
  331. return error;
  332. }
  333. /* first character must be `<' */
  334. static FT_Error
  335. skip_string( FT_Byte* *acur,
  336. FT_Byte* limit )
  337. {
  338. FT_Byte* cur = *acur;
  339. FT_Error err = PSaux_Err_Ok;
  340. while ( ++cur < limit )
  341. {
  342. /* All whitespace characters are ignored. */
  343. skip_spaces( &cur, limit );
  344. if ( cur >= limit )
  345. break;
  346. if ( !IS_PS_XDIGIT( *cur ) )
  347. break;
  348. }
  349. if ( cur < limit && *cur != '>' )
  350. {
  351. FT_ERROR(( "skip_string: missing closing delimiter `>'\n" ));
  352. err = PSaux_Err_Invalid_File_Format;
  353. }
  354. else
  355. cur++;
  356. *acur = cur;
  357. return err;
  358. }
  359. /* first character must be the opening brace that */
  360. /* starts the procedure */
  361. /* NB: [ and ] need not match: */
  362. /* `/foo {[} def' is a valid PostScript fragment, */
  363. /* even within a Type1 font */
  364. static FT_Error
  365. skip_procedure( FT_Byte* *acur,
  366. FT_Byte* limit )
  367. {
  368. FT_Byte* cur;
  369. FT_Int embed = 0;
  370. FT_Error error = PSaux_Err_Ok;
  371. FT_ASSERT( **acur == '{' );
  372. for ( cur = *acur; cur < limit && error == PSaux_Err_Ok; ++cur )
  373. {
  374. switch ( *cur )
  375. {
  376. case '{':
  377. ++embed;
  378. break;
  379. case '}':
  380. --embed;
  381. if ( embed == 0 )
  382. {
  383. ++cur;
  384. goto end;
  385. }
  386. break;
  387. case '(':
  388. error = skip_literal_string( &cur, limit );
  389. break;
  390. case '<':
  391. error = skip_string( &cur, limit );
  392. break;
  393. case '%':
  394. skip_comment( &cur, limit );
  395. break;
  396. }
  397. }
  398. end:
  399. if ( embed != 0 )
  400. error = PSaux_Err_Invalid_File_Format;
  401. *acur = cur;
  402. return error;
  403. }
  404. /***********************************************************************/
  405. /* */
  406. /* All exported parsing routines handle leading whitespace and stop at */
  407. /* the first character which isn't part of the just handled token. */
  408. /* */
  409. /***********************************************************************/
  410. FT_LOCAL_DEF( void )
  411. ps_parser_skip_PS_token( PS_Parser parser )
  412. {
  413. /* Note: PostScript allows any non-delimiting, non-whitespace */
  414. /* character in a name (PS Ref Manual, 3rd ed, p31). */
  415. /* PostScript delimiters are (, ), <, >, [, ], {, }, /, and %. */
  416. FT_Byte* cur = parser->cursor;
  417. FT_Byte* limit = parser->limit;
  418. FT_Error error = PSaux_Err_Ok;
  419. skip_spaces( &cur, limit ); /* this also skips comments */
  420. if ( cur >= limit )
  421. goto Exit;
  422. /* self-delimiting, single-character tokens */
  423. if ( *cur == '[' || *cur == ']' )
  424. {
  425. cur++;
  426. goto Exit;
  427. }
  428. /* skip balanced expressions (procedures and strings) */
  429. if ( *cur == '{' ) /* {...} */
  430. {
  431. error = skip_procedure( &cur, limit );
  432. goto Exit;
  433. }
  434. if ( *cur == '(' ) /* (...) */
  435. {
  436. error = skip_literal_string( &cur, limit );
  437. goto Exit;
  438. }
  439. if ( *cur == '<' ) /* <...> */
  440. {
  441. if ( cur + 1 < limit && *(cur + 1) == '<' ) /* << */
  442. {
  443. cur++;
  444. cur++;
  445. }
  446. else
  447. error = skip_string( &cur, limit );
  448. goto Exit;
  449. }
  450. if ( *cur == '>' )
  451. {
  452. cur++;
  453. if ( cur >= limit || *cur != '>' ) /* >> */
  454. {
  455. FT_ERROR(( "ps_parser_skip_PS_token:"
  456. " unexpected closing delimiter `>'\n" ));
  457. error = PSaux_Err_Invalid_File_Format;
  458. goto Exit;
  459. }
  460. cur++;
  461. goto Exit;
  462. }
  463. if ( *cur == '/' )
  464. cur++;
  465. /* anything else */
  466. while ( cur < limit )
  467. {
  468. /* *cur might be invalid (e.g., ')' or '}'), but this */
  469. /* is handled by the test `cur == parser->cursor' below */
  470. if ( IS_PS_DELIM( *cur ) )
  471. break;
  472. cur++;
  473. }
  474. Exit:
  475. if ( cur == parser->cursor )
  476. {
  477. FT_ERROR(( "ps_parser_skip_PS_token:"
  478. " current token is `%c' which is self-delimiting\n"
  479. " "
  480. " but invalid at this point\n",
  481. *cur ));
  482. error = PSaux_Err_Invalid_File_Format;
  483. }
  484. parser->error = error;
  485. parser->cursor = cur;
  486. }
  487. FT_LOCAL_DEF( void )
  488. ps_parser_skip_spaces( PS_Parser parser )
  489. {
  490. skip_spaces( &parser->cursor, parser->limit );
  491. }
  492. /* `token' here means either something between balanced delimiters */
  493. /* or the next token; the delimiters are not removed. */
  494. FT_LOCAL_DEF( void )
  495. ps_parser_to_token( PS_Parser parser,
  496. T1_Token token )
  497. {
  498. FT_Byte* cur;
  499. FT_Byte* limit;
  500. FT_Int embed;
  501. token->type = T1_TOKEN_TYPE_NONE;
  502. token->start = 0;
  503. token->limit = 0;
  504. /* first of all, skip leading whitespace */
  505. ps_parser_skip_spaces( parser );
  506. cur = parser->cursor;
  507. limit = parser->limit;
  508. if ( cur >= limit )
  509. return;
  510. switch ( *cur )
  511. {
  512. /************* check for literal string *****************/
  513. case '(':
  514. token->type = T1_TOKEN_TYPE_STRING;
  515. token->start = cur;
  516. if ( skip_literal_string( &cur, limit ) == PSaux_Err_Ok )
  517. token->limit = cur;
  518. break;
  519. /************* check for programs/array *****************/
  520. case '{':
  521. token->type = T1_TOKEN_TYPE_ARRAY;
  522. token->start = cur;
  523. if ( skip_procedure( &cur, limit ) == PSaux_Err_Ok )
  524. token->limit = cur;
  525. break;
  526. /************* check for table/array ********************/
  527. /* XXX: in theory we should also look for "<<" */
  528. /* since this is semantically equivalent to "["; */
  529. /* in practice it doesn't matter (?) */
  530. case '[':
  531. token->type = T1_TOKEN_TYPE_ARRAY;
  532. embed = 1;
  533. token->start = cur++;
  534. /* we need this to catch `[ ]' */
  535. parser->cursor = cur;
  536. ps_parser_skip_spaces( parser );
  537. cur = parser->cursor;
  538. while ( cur < limit && !parser->error )
  539. {
  540. /* XXX: this is wrong because it does not */
  541. /* skip comments, procedures, and strings */
  542. if ( *cur == '[' )
  543. embed++;
  544. else if ( *cur == ']' )
  545. {
  546. embed--;
  547. if ( embed <= 0 )
  548. {
  549. token->limit = ++cur;
  550. break;
  551. }
  552. }
  553. parser->cursor = cur;
  554. ps_parser_skip_PS_token( parser );
  555. /* we need this to catch `[XXX ]' */
  556. ps_parser_skip_spaces ( parser );
  557. cur = parser->cursor;
  558. }
  559. break;
  560. /* ************ otherwise, it is any token **************/
  561. default:
  562. token->start = cur;
  563. token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY );
  564. ps_parser_skip_PS_token( parser );
  565. cur = parser->cursor;
  566. if ( !parser->error )
  567. token->limit = cur;
  568. }
  569. if ( !token->limit )
  570. {
  571. token->start = 0;
  572. token->type = T1_TOKEN_TYPE_NONE;
  573. }
  574. parser->cursor = cur;
  575. }
  576. /* NB: `tokens' can be NULL if we only want to count */
  577. /* the number of array elements */
  578. FT_LOCAL_DEF( void )
  579. ps_parser_to_token_array( PS_Parser parser,
  580. T1_Token tokens,
  581. FT_UInt max_tokens,
  582. FT_Int* pnum_tokens )
  583. {
  584. T1_TokenRec master;
  585. *pnum_tokens = -1;
  586. /* this also handles leading whitespace */
  587. ps_parser_to_token( parser, &master );
  588. if ( master.type == T1_TOKEN_TYPE_ARRAY )
  589. {
  590. FT_Byte* old_cursor = parser->cursor;
  591. FT_Byte* old_limit = parser->limit;
  592. T1_Token cur = tokens;
  593. T1_Token limit = cur + max_tokens;
  594. /* don't include outermost delimiters */
  595. parser->cursor = master.start + 1;
  596. parser->limit = master.limit - 1;
  597. while ( parser->cursor < parser->limit )
  598. {
  599. T1_TokenRec token;
  600. ps_parser_to_token( parser, &token );
  601. if ( !token.type )
  602. break;
  603. if ( tokens != NULL && cur < limit )
  604. *cur = token;
  605. cur++;
  606. }
  607. *pnum_tokens = (FT_Int)( cur - tokens );
  608. parser->cursor = old_cursor;
  609. parser->limit = old_limit;
  610. }
  611. }
  612. /* first character must be a delimiter or a part of a number */
  613. /* NB: `coords' can be NULL if we just want to skip the */
  614. /* array; in this case we ignore `max_coords' */
  615. static FT_Int
  616. ps_tocoordarray( FT_Byte* *acur,
  617. FT_Byte* limit,
  618. FT_Int max_coords,
  619. FT_Short* coords )
  620. {
  621. FT_Byte* cur = *acur;
  622. FT_Int count = 0;
  623. FT_Byte c, ender;
  624. if ( cur >= limit )
  625. goto Exit;
  626. /* check for the beginning of an array; otherwise, only one number */
  627. /* will be read */
  628. c = *cur;
  629. ender = 0;
  630. if ( c == '[' )
  631. ender = ']';
  632. else if ( c == '{' )
  633. ender = '}';
  634. if ( ender )
  635. cur++;
  636. /* now, read the coordinates */
  637. while ( cur < limit )
  638. {
  639. FT_Short dummy;
  640. FT_Byte* old_cur;
  641. /* skip whitespace in front of data */
  642. skip_spaces( &cur, limit );
  643. if ( cur >= limit )
  644. goto Exit;
  645. if ( *cur == ender )
  646. {
  647. cur++;
  648. break;
  649. }
  650. old_cur = cur;
  651. if ( coords != NULL && count >= max_coords )
  652. break;
  653. /* call PS_Conv_ToFixed() even if coords == NULL */
  654. /* to properly parse number at `cur' */
  655. *( coords != NULL ? &coords[count] : &dummy ) =
  656. (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
  657. if ( old_cur == cur )
  658. {
  659. count = -1;
  660. goto Exit;
  661. }
  662. else
  663. count++;
  664. if ( !ender )
  665. break;
  666. }
  667. Exit:
  668. *acur = cur;
  669. return count;
  670. }
  671. /* first character must be a delimiter or a part of a number */
  672. /* NB: `values' can be NULL if we just want to skip the */
  673. /* array; in this case we ignore `max_values' */
  674. static FT_Int
  675. ps_tofixedarray( FT_Byte* *acur,
  676. FT_Byte* limit,
  677. FT_Int max_values,
  678. FT_Fixed* values,
  679. FT_Int power_ten )
  680. {
  681. FT_Byte* cur = *acur;
  682. FT_Int count = 0;
  683. FT_Byte c, ender;
  684. if ( cur >= limit )
  685. goto Exit;
  686. /* Check for the beginning of an array. Otherwise, only one number */
  687. /* will be read. */
  688. c = *cur;
  689. ender = 0;
  690. if ( c == '[' )
  691. ender = ']';
  692. else if ( c == '{' )
  693. ender = '}';
  694. if ( ender )
  695. cur++;
  696. /* now, read the values */
  697. while ( cur < limit )
  698. {
  699. FT_Fixed dummy;
  700. FT_Byte* old_cur;
  701. /* skip whitespace in front of data */
  702. skip_spaces( &cur, limit );
  703. if ( cur >= limit )
  704. goto Exit;
  705. if ( *cur == ender )
  706. {
  707. cur++;
  708. break;
  709. }
  710. old_cur = cur;
  711. if ( values != NULL && count >= max_values )
  712. break;
  713. /* call PS_Conv_ToFixed() even if coords == NULL */
  714. /* to properly parse number at `cur' */
  715. *( values != NULL ? &values[count] : &dummy ) =
  716. PS_Conv_ToFixed( &cur, limit, power_ten );
  717. if ( old_cur == cur )
  718. {
  719. count = -1;
  720. goto Exit;
  721. }
  722. else
  723. count++;
  724. if ( !ender )
  725. break;
  726. }
  727. Exit:
  728. *acur = cur;
  729. return count;
  730. }
  731. #if 0
  732. static FT_String*
  733. ps_tostring( FT_Byte** cursor,
  734. FT_Byte* limit,
  735. FT_Memory memory )
  736. {
  737. FT_Byte* cur = *cursor;
  738. FT_PtrDist len = 0;
  739. FT_Int count;
  740. FT_String* result;
  741. FT_Error error;
  742. /* XXX: some stupid fonts have a `Notice' or `Copyright' string */
  743. /* that simply doesn't begin with an opening parenthesis, even */
  744. /* though they have a closing one! E.g. "amuncial.pfb" */
  745. /* */
  746. /* We must deal with these ill-fated cases there. Note that */
  747. /* these fonts didn't work with the old Type 1 driver as the */
  748. /* notice/copyright was not recognized as a valid string token */
  749. /* and made the old token parser commit errors. */
  750. while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) )
  751. cur++;
  752. if ( cur + 1 >= limit )
  753. return 0;
  754. if ( *cur == '(' )
  755. cur++; /* skip the opening parenthesis, if there is one */
  756. *cursor = cur;
  757. count = 0;
  758. /* then, count its length */
  759. for ( ; cur < limit; cur++ )
  760. {
  761. if ( *cur == '(' )
  762. count++;
  763. else if ( *cur == ')' )
  764. {
  765. count--;
  766. if ( count < 0 )
  767. break;
  768. }
  769. }
  770. len = cur - *cursor;
  771. if ( cur >= limit || FT_ALLOC( result, len + 1 ) )
  772. return 0;
  773. /* now copy the string */
  774. FT_MEM_COPY( result, *cursor, len );
  775. result[len] = '\0';
  776. *cursor = cur;
  777. return result;
  778. }
  779. #endif /* 0 */
  780. static int
  781. ps_tobool( FT_Byte* *acur,
  782. FT_Byte* limit )
  783. {
  784. FT_Byte* cur = *acur;
  785. FT_Bool result = 0;
  786. /* return 1 if we find `true', 0 otherwise */
  787. if ( cur + 3 < limit &&
  788. cur[0] == 't' &&
  789. cur[1] == 'r' &&
  790. cur[2] == 'u' &&
  791. cur[3] == 'e' )
  792. {
  793. result = 1;
  794. cur += 5;
  795. }
  796. else if ( cur + 4 < limit &&
  797. cur[0] == 'f' &&
  798. cur[1] == 'a' &&
  799. cur[2] == 'l' &&
  800. cur[3] == 's' &&
  801. cur[4] == 'e' )
  802. {
  803. result = 0;
  804. cur += 6;
  805. }
  806. *acur = cur;
  807. return result;
  808. }
  809. /* load a simple field (i.e. non-table) into the current list of objects */
  810. FT_LOCAL_DEF( FT_Error )
  811. ps_parser_load_field( PS_Parser parser,
  812. const T1_Field field,
  813. void** objects,
  814. FT_UInt max_objects,
  815. FT_ULong* pflags )
  816. {
  817. T1_TokenRec token;
  818. FT_Byte* cur;
  819. FT_Byte* limit;
  820. FT_UInt count;
  821. FT_UInt idx;
  822. FT_Error error;
  823. /* this also skips leading whitespace */
  824. ps_parser_to_token( parser, &token );
  825. if ( !token.type )
  826. goto Fail;
  827. count = 1;
  828. idx = 0;
  829. cur = token.start;
  830. limit = token.limit;
  831. /* we must detect arrays in /FontBBox */
  832. if ( field->type == T1_FIELD_TYPE_BBOX )
  833. {
  834. T1_TokenRec token2;
  835. FT_Byte* old_cur = parser->cursor;
  836. FT_Byte* old_limit = parser->limit;
  837. /* don't include delimiters */
  838. parser->cursor = token.start + 1;
  839. parser->limit = token.limit - 1;
  840. ps_parser_to_token( parser, &token2 );
  841. parser->cursor = old_cur;
  842. parser->limit = old_limit;
  843. if ( token2.type == T1_TOKEN_TYPE_ARRAY )
  844. goto FieldArray;
  845. }
  846. else if ( token.type == T1_TOKEN_TYPE_ARRAY )
  847. {
  848. FieldArray:
  849. /* if this is an array and we have no blend, an error occurs */
  850. if ( max_objects == 0 )
  851. goto Fail;
  852. count = max_objects;
  853. idx = 1;
  854. /* don't include delimiters */
  855. cur++;
  856. limit--;
  857. }
  858. for ( ; count > 0; count--, idx++ )
  859. {
  860. FT_Byte* q = (FT_Byte*)objects[idx] + field->offset;
  861. FT_Long val;
  862. FT_String* string;
  863. skip_spaces( &cur, limit );
  864. switch ( field->type )
  865. {
  866. case T1_FIELD_TYPE_BOOL:
  867. val = ps_tobool( &cur, limit );
  868. goto Store_Integer;
  869. case T1_FIELD_TYPE_FIXED:
  870. val = PS_Conv_ToFixed( &cur, limit, 0 );
  871. goto Store_Integer;
  872. case T1_FIELD_TYPE_FIXED_1000:
  873. val = PS_Conv_ToFixed( &cur, limit, 3 );
  874. goto Store_Integer;
  875. case T1_FIELD_TYPE_INTEGER:
  876. val = PS_Conv_ToInt( &cur, limit );
  877. /* fall through */
  878. Store_Integer:
  879. switch ( field->size )
  880. {
  881. case (8 / FT_CHAR_BIT):
  882. *(FT_Byte*)q = (FT_Byte)val;
  883. break;
  884. case (16 / FT_CHAR_BIT):
  885. *(FT_UShort*)q = (FT_UShort)val;
  886. break;
  887. case (32 / FT_CHAR_BIT):
  888. *(FT_UInt32*)q = (FT_UInt32)val;
  889. break;
  890. default: /* for 64-bit systems */
  891. *(FT_Long*)q = val;
  892. }
  893. break;
  894. case T1_FIELD_TYPE_STRING:
  895. case T1_FIELD_TYPE_KEY:
  896. {
  897. FT_Memory memory = parser->memory;
  898. FT_UInt len = (FT_UInt)( limit - cur );
  899. if ( cur >= limit )
  900. break;
  901. /* we allow both a string or a name */
  902. /* for cases like /FontName (foo) def */
  903. if ( token.type == T1_TOKEN_TYPE_KEY )
  904. {
  905. /* don't include leading `/' */
  906. len--;
  907. cur++;
  908. }
  909. else if ( token.type == T1_TOKEN_TYPE_STRING )
  910. {
  911. /* don't include delimiting parentheses */
  912. /* XXX we don't handle <<...>> here */
  913. /* XXX should we convert octal escapes? */
  914. /* if so, what encoding should we use? */
  915. cur++;
  916. len -= 2;
  917. }
  918. else
  919. {
  920. FT_ERROR(( "ps_parser_load_field:"
  921. " expected a name or string\n"
  922. " "
  923. " but found token of type %d instead\n",
  924. token.type ));
  925. error = PSaux_Err_Invalid_File_Format;
  926. goto Exit;
  927. }
  928. /* for this to work (FT_String**)q must have been */
  929. /* initialized to NULL */
  930. if ( *(FT_String**)q != NULL )
  931. {
  932. FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n",
  933. field->ident ));
  934. FT_FREE( *(FT_String**)q );
  935. *(FT_String**)q = NULL;
  936. }
  937. if ( FT_ALLOC( string, len + 1 ) )
  938. goto Exit;
  939. FT_MEM_COPY( string, cur, len );
  940. string[len] = 0;
  941. *(FT_String**)q = string;
  942. }
  943. break;
  944. case T1_FIELD_TYPE_BBOX:
  945. {
  946. FT_Fixed temp[4];
  947. FT_BBox* bbox = (FT_BBox*)q;
  948. FT_Int result;
  949. result = ps_tofixedarray( &cur, limit, 4, temp, 0 );
  950. if ( result < 0 )
  951. {
  952. FT_ERROR(( "ps_parser_load_field:"
  953. " expected four integers in bounding box\n" ));
  954. error = PSaux_Err_Invalid_File_Format;
  955. goto Exit;
  956. }
  957. bbox->xMin = FT_RoundFix( temp[0] );
  958. bbox->yMin = FT_RoundFix( temp[1] );
  959. bbox->xMax = FT_RoundFix( temp[2] );
  960. bbox->yMax = FT_RoundFix( temp[3] );
  961. }
  962. break;
  963. default:
  964. /* an error occurred */
  965. goto Fail;
  966. }
  967. }
  968. #if 0 /* obsolete -- keep for reference */
  969. if ( pflags )
  970. *pflags |= 1L << field->flag_bit;
  971. #else
  972. FT_UNUSED( pflags );
  973. #endif
  974. error = PSaux_Err_Ok;
  975. Exit:
  976. return error;
  977. Fail:
  978. error = PSaux_Err_Invalid_File_Format;
  979. goto Exit;
  980. }
  981. #define T1_MAX_TABLE_ELEMENTS 32
  982. FT_LOCAL_DEF( FT_Error )
  983. ps_parser_load_field_table( PS_Parser parser,
  984. const T1_Field field,
  985. void** objects,
  986. FT_UInt max_objects,
  987. FT_ULong* pflags )
  988. {
  989. T1_TokenRec elements[T1_MAX_TABLE_ELEMENTS];
  990. T1_Token token;
  991. FT_Int num_elements;
  992. FT_Error error = PSaux_Err_Ok;
  993. FT_Byte* old_cursor;
  994. FT_Byte* old_limit;
  995. T1_FieldRec fieldrec = *(T1_Field)field;
  996. fieldrec.type = T1_FIELD_TYPE_INTEGER;
  997. if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY ||
  998. field->type == T1_FIELD_TYPE_BBOX )
  999. fieldrec.type = T1_FIELD_TYPE_FIXED;
  1000. ps_parser_to_token_array( parser, elements,
  1001. T1_MAX_TABLE_ELEMENTS, &num_elements );
  1002. if ( num_elements < 0 )
  1003. {
  1004. error = PSaux_Err_Ignore;
  1005. goto Exit;
  1006. }
  1007. if ( (FT_UInt)num_elements > field->array_max )
  1008. num_elements = field->array_max;
  1009. old_cursor = parser->cursor;
  1010. old_limit = parser->limit;
  1011. /* we store the elements count if necessary; */
  1012. /* we further assume that `count_offset' can't be zero */
  1013. if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 )
  1014. *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
  1015. (FT_Byte)num_elements;
  1016. /* we now load each element, adjusting the field.offset on each one */
  1017. token = elements;
  1018. for ( ; num_elements > 0; num_elements--, token++ )
  1019. {
  1020. parser->cursor = token->start;
  1021. parser->limit = token->limit;
  1022. ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 );
  1023. fieldrec.offset += fieldrec.size;
  1024. }
  1025. #if 0 /* obsolete -- keep for reference */
  1026. if ( pflags )
  1027. *pflags |= 1L << field->flag_bit;
  1028. #else
  1029. FT_UNUSED( pflags );
  1030. #endif
  1031. parser->cursor = old_cursor;
  1032. parser->limit = old_limit;
  1033. Exit:
  1034. return error;
  1035. }
  1036. FT_LOCAL_DEF( FT_Long )
  1037. ps_parser_to_int( PS_Parser parser )
  1038. {
  1039. ps_parser_skip_spaces( parser );
  1040. return PS_Conv_ToInt( &parser->cursor, parser->limit );
  1041. }
  1042. /* first character must be `<' if `delimiters' is non-zero */
  1043. FT_LOCAL_DEF( FT_Error )
  1044. ps_parser_to_bytes( PS_Parser parser,
  1045. FT_Byte* bytes,
  1046. FT_Offset max_bytes,
  1047. FT_Long* pnum_bytes,
  1048. FT_Bool delimiters )
  1049. {
  1050. FT_Error error = PSaux_Err_Ok;
  1051. FT_Byte* cur;
  1052. ps_parser_skip_spaces( parser );
  1053. cur = parser->cursor;
  1054. if ( cur >= parser->limit )
  1055. goto Exit;
  1056. if ( delimiters )
  1057. {
  1058. if ( *cur != '<' )
  1059. {
  1060. FT_ERROR(( "ps_parser_to_bytes: Missing starting delimiter `<'\n" ));
  1061. error = PSaux_Err_Invalid_File_Format;
  1062. goto Exit;
  1063. }
  1064. cur++;
  1065. }
  1066. *pnum_bytes = PS_Conv_ASCIIHexDecode( &cur,
  1067. parser->limit,
  1068. bytes,
  1069. max_bytes );
  1070. if ( delimiters )
  1071. {
  1072. if ( cur < parser->limit && *cur != '>' )
  1073. {
  1074. FT_ERROR(( "ps_parser_to_bytes: Missing closing delimiter `>'\n" ));
  1075. error = PSaux_Err_Invalid_File_Format;
  1076. goto Exit;
  1077. }
  1078. cur++;
  1079. }
  1080. parser->cursor = cur;
  1081. Exit:
  1082. return error;
  1083. }
  1084. FT_LOCAL_DEF( FT_Fixed )
  1085. ps_parser_to_fixed( PS_Parser parser,
  1086. FT_Int power_ten )
  1087. {
  1088. ps_parser_skip_spaces( parser );
  1089. return PS_Conv_ToFixed( &parser->cursor, parser->limit, power_ten );
  1090. }
  1091. FT_LOCAL_DEF( FT_Int )
  1092. ps_parser_to_coord_array( PS_Parser parser,
  1093. FT_Int max_coords,
  1094. FT_Short* coords )
  1095. {
  1096. ps_parser_skip_spaces( parser );
  1097. return ps_tocoordarray( &parser->cursor, parser->limit,
  1098. max_coords, coords );
  1099. }
  1100. FT_LOCAL_DEF( FT_Int )
  1101. ps_parser_to_fixed_array( PS_Parser parser,
  1102. FT_Int max_values,
  1103. FT_Fixed* values,
  1104. FT_Int power_ten )
  1105. {
  1106. ps_parser_skip_spaces( parser );
  1107. return ps_tofixedarray( &parser->cursor, parser->limit,
  1108. max_values, values, power_ten );
  1109. }
  1110. #if 0
  1111. FT_LOCAL_DEF( FT_String* )
  1112. T1_ToString( PS_Parser parser )
  1113. {
  1114. return ps_tostring( &parser->cursor, parser->limit, parser->memory );
  1115. }
  1116. FT_LOCAL_DEF( FT_Bool )
  1117. T1_ToBool( PS_Parser parser )
  1118. {
  1119. return ps_tobool( &parser->cursor, parser->limit );
  1120. }
  1121. #endif /* 0 */
  1122. FT_LOCAL_DEF( void )
  1123. ps_parser_init( PS_Parser parser,
  1124. FT_Byte* base,
  1125. FT_Byte* limit,
  1126. FT_Memory memory )
  1127. {
  1128. parser->error = PSaux_Err_Ok;
  1129. parser->base = base;
  1130. parser->limit = limit;
  1131. parser->cursor = base;
  1132. parser->memory = memory;
  1133. parser->funcs = ps_parser_funcs;
  1134. }
  1135. FT_LOCAL_DEF( void )
  1136. ps_parser_done( PS_Parser parser )
  1137. {
  1138. FT_UNUSED( parser );
  1139. }
  1140. /*************************************************************************/
  1141. /*************************************************************************/
  1142. /***** *****/
  1143. /***** T1 BUILDER *****/
  1144. /***** *****/
  1145. /*************************************************************************/
  1146. /*************************************************************************/
  1147. /*************************************************************************/
  1148. /* */
  1149. /* <Function> */
  1150. /* t1_builder_init */
  1151. /* */
  1152. /* <Description> */
  1153. /* Initializes a given glyph builder. */
  1154. /* */
  1155. /* <InOut> */
  1156. /* builder :: A pointer to the glyph builder to initialize. */
  1157. /* */
  1158. /* <Input> */
  1159. /* face :: The current face object. */
  1160. /* */
  1161. /* size :: The current size object. */
  1162. /* */
  1163. /* glyph :: The current glyph object. */
  1164. /* */
  1165. /* hinting :: Whether hinting should be applied. */
  1166. /* */
  1167. FT_LOCAL_DEF( void )
  1168. t1_builder_init( T1_Builder builder,
  1169. FT_Face face,
  1170. FT_Size size,
  1171. FT_GlyphSlot glyph,
  1172. FT_Bool hinting )
  1173. {
  1174. builder->parse_state = T1_Parse_Start;
  1175. builder->load_points = 1;
  1176. builder->face = face;
  1177. builder->glyph = glyph;
  1178. builder->memory = face->memory;
  1179. if ( glyph )
  1180. {
  1181. FT_GlyphLoader loader = glyph->internal->loader;
  1182. builder->loader = loader;
  1183. builder->base = &loader->base.outline;
  1184. builder->current = &loader->current.outline;
  1185. FT_GlyphLoader_Rewind( loader );
  1186. builder->hints_globals = size->internal;
  1187. builder->hints_funcs = 0;
  1188. if ( hinting )
  1189. builder->hints_funcs = glyph->internal->glyph_hints;
  1190. }
  1191. builder->pos_x = 0;
  1192. builder->pos_y = 0;
  1193. builder->left_bearing.x = 0;
  1194. builder->left_bearing.y = 0;
  1195. builder->advance.x = 0;
  1196. builder->advance.y = 0;
  1197. builder->funcs = t1_builder_funcs;
  1198. }
  1199. /*************************************************************************/
  1200. /* */
  1201. /* <Function> */
  1202. /* t1_builder_done */
  1203. /* */
  1204. /* <Description> */
  1205. /* Finalizes a given glyph builder. Its contents can still be used */
  1206. /* after the call, but the function saves important information */
  1207. /* within the corresponding glyph slot. */
  1208. /* */
  1209. /* <Input> */
  1210. /* builder :: A pointer to the glyph builder to finalize. */
  1211. /* */
  1212. FT_LOCAL_DEF( void )
  1213. t1_builder_done( T1_Builder builder )
  1214. {
  1215. FT_GlyphSlot glyph = builder->glyph;
  1216. if ( glyph )
  1217. glyph->outline = *builder->base;
  1218. }
  1219. /* check that there is enough space for `count' more points */
  1220. FT_LOCAL_DEF( FT_Error )
  1221. t1_builder_check_points( T1_Builder builder,
  1222. FT_Int count )
  1223. {
  1224. return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
  1225. }
  1226. /* add a new point, do not check space */
  1227. FT_LOCAL_DEF( void )
  1228. t1_builder_add_point( T1_Builder builder,
  1229. FT_Pos x,
  1230. FT_Pos y,
  1231. FT_Byte flag )
  1232. {
  1233. FT_Outline* outline = builder->current;
  1234. if ( builder->load_points )
  1235. {
  1236. FT_Vector* point = outline->points + outline->n_points;
  1237. FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
  1238. point->x = FIXED_TO_INT( x );
  1239. point->y = FIXED_TO_INT( y );
  1240. *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
  1241. }
  1242. outline->n_points++;
  1243. }
  1244. /* check space for a new on-curve point, then add it */
  1245. FT_LOCAL_DEF( FT_Error )
  1246. t1_builder_add_point1( T1_Builder builder,
  1247. FT_Pos x,
  1248. FT_Pos y )
  1249. {
  1250. FT_Error error;
  1251. error = t1_builder_check_points( builder, 1 );
  1252. if ( !error )
  1253. t1_builder_add_point( builder, x, y, 1 );
  1254. return error;
  1255. }
  1256. /* check space for a new contour, then add it */
  1257. FT_LOCAL_DEF( FT_Error )
  1258. t1_builder_add_contour( T1_Builder builder )
  1259. {
  1260. FT_Outline* outline = builder->current;
  1261. FT_Error error;
  1262. if ( !builder->load_points )
  1263. {
  1264. outline->n_contours++;
  1265. return PSaux_Err_Ok;
  1266. }
  1267. error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
  1268. if ( !error )
  1269. {
  1270. if ( outline->n_contours > 0 )
  1271. outline->contours[outline->n_contours - 1] =
  1272. (short)( outline->n_points - 1 );
  1273. outline->n_contours++;
  1274. }
  1275. return error;
  1276. }
  1277. /* if a path was begun, add its first on-curve point */
  1278. FT_LOCAL_DEF( FT_Error )
  1279. t1_builder_start_point( T1_Builder builder,
  1280. FT_Pos x,
  1281. FT_Pos y )
  1282. {
  1283. FT_Error error = PSaux_Err_Invalid_File_Format;
  1284. /* test whether we are building a new contour */
  1285. if ( builder->parse_state == T1_Parse_Have_Path )
  1286. error = PSaux_Err_Ok;
  1287. else if ( builder->parse_state == T1_Parse_Have_Moveto )
  1288. {
  1289. builder->parse_state = T1_Parse_Have_Path;
  1290. error = t1_builder_add_contour( builder );
  1291. if ( !error )
  1292. error = t1_builder_add_point1( builder, x, y );
  1293. }
  1294. return error;
  1295. }
  1296. /* close the current contour */
  1297. FT_LOCAL_DEF( void )
  1298. t1_builder_close_contour( T1_Builder builder )
  1299. {
  1300. FT_Outline* outline = builder->current;
  1301. FT_Int first;
  1302. if ( !outline )
  1303. return;
  1304. first = outline->n_contours <= 1
  1305. ? 0 : outline->contours[outline->n_contours - 2] + 1;
  1306. /* We must not include the last point in the path if it */
  1307. /* is located on the first point. */
  1308. if ( outline->n_points > 1 )
  1309. {
  1310. FT_Vector* p1 = outline->points + first;
  1311. FT_Vector* p2 = outline->points + outline->n_points - 1;
  1312. FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1;
  1313. /* `delete' last point only if it coincides with the first */
  1314. /* point and it is not a control point (which can happen). */
  1315. if ( p1->x == p2->x && p1->y == p2->y )
  1316. if ( *control == FT_CURVE_TAG_ON )
  1317. outline->n_points--;
  1318. }
  1319. if ( outline->n_contours > 0 )
  1320. {
  1321. /* Don't add contours only consisting of one point, i.e., */
  1322. /* check whether the first and the last point is the same. */
  1323. if ( first == outline->n_points - 1 )
  1324. {
  1325. outline->n_contours--;
  1326. outline->n_points--;
  1327. }
  1328. else
  1329. outline->contours[outline->n_contours - 1] =
  1330. (short)( outline->n_points - 1 );
  1331. }
  1332. }
  1333. /*************************************************************************/
  1334. /*************************************************************************/
  1335. /***** *****/
  1336. /***** OTHER *****/
  1337. /***** *****/
  1338. /*************************************************************************/
  1339. /*************************************************************************/
  1340. FT_LOCAL_DEF( void )
  1341. t1_decrypt( FT_Byte* buffer,
  1342. FT_Offset length,
  1343. FT_UShort seed )
  1344. {
  1345. PS_Conv_EexecDecode( &buffer,
  1346. buffer + length,
  1347. buffer,
  1348. length,
  1349. &seed );
  1350. }
  1351. /* END */