Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
psobjs.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* psobjs.c */
4 /* */
5 /* Auxiliary functions for PostScript fonts (body). */
6 /* */
7 /* Copyright 1996-2013 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
17 
18 
19 #include <ft2build.h>
20 #include FT_INTERNAL_POSTSCRIPT_AUX_H
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_CALC_H
23 
24 #include "psobjs.h"
25 #include "psconv.h"
26 
27 #include "psauxerr.h"
28 
29 
30  /*************************************************************************/
31  /* */
32  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
33  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
34  /* messages during execution. */
35  /* */
36 #undef FT_COMPONENT
37 #define FT_COMPONENT trace_psobjs
38 
39 
40  /*************************************************************************/
41  /*************************************************************************/
42  /***** *****/
43  /***** PS_TABLE *****/
44  /***** *****/
45  /*************************************************************************/
46  /*************************************************************************/
47 
48  /*************************************************************************/
49  /* */
50  /* <Function> */
51  /* ps_table_new */
52  /* */
53  /* <Description> */
54  /* Initializes a PS_Table. */
55  /* */
56  /* <InOut> */
57  /* table :: The address of the target table. */
58  /* */
59  /* <Input> */
60  /* count :: The table size = the maximum number of elements. */
61  /* */
62  /* memory :: The memory object to use for all subsequent */
63  /* reallocations. */
64  /* */
65  /* <Return> */
66  /* FreeType error code. 0 means success. */
67  /* */
70  FT_Int count,
71  FT_Memory memory )
72  {
74 
75 
76  table->memory = memory;
77  if ( FT_NEW_ARRAY( table->elements, count ) ||
78  FT_NEW_ARRAY( table->lengths, count ) )
79  goto Exit;
80 
81  table->max_elems = count;
82  table->init = 0xDEADBEEFUL;
83  table->num_elems = 0;
84  table->block = 0;
85  table->capacity = 0;
86  table->cursor = 0;
87 
88  *(PS_Table_FuncsRec*)&table->funcs = ps_table_funcs;
89 
90  Exit:
91  if ( error )
92  FT_FREE( table->elements );
93 
94  return error;
95  }
96 
97 
98  static void
99  shift_elements( PS_Table table,
100  FT_Byte* old_base )
101  {
102  FT_PtrDist delta = table->block - old_base;
103  FT_Byte** offset = table->elements;
104  FT_Byte** limit = offset + table->max_elems;
105 
106 
107  for ( ; offset < limit; offset++ )
108  {
109  if ( offset[0] )
110  offset[0] += delta;
111  }
112  }
113 
114 
115  static FT_Error
116  reallocate_t1_table( PS_Table table,
117  FT_Long new_size )
118  {
119  FT_Memory memory = table->memory;
120  FT_Byte* old_base = table->block;
121  FT_Error error;
122 
123 
124  /* allocate new base block */
125  if ( FT_ALLOC( table->block, new_size ) )
126  {
127  table->block = old_base;
128  return error;
129  }
130 
131  /* copy elements and shift offsets */
132  if ( old_base )
133  {
134  FT_MEM_COPY( table->block, old_base, table->capacity );
135  shift_elements( table, old_base );
136  FT_FREE( old_base );
137  }
138 
139  table->capacity = new_size;
140 
141  return FT_Err_Ok;
142  }
143 
144 
145  /*************************************************************************/
146  /* */
147  /* <Function> */
148  /* ps_table_add */
149  /* */
150  /* <Description> */
151  /* Adds an object to a PS_Table, possibly growing its memory block. */
152  /* */
153  /* <InOut> */
154  /* table :: The target table. */
155  /* */
156  /* <Input> */
157  /* idx :: The index of the object in the table. */
158  /* */
159  /* object :: The address of the object to copy in memory. */
160  /* */
161  /* length :: The length in bytes of the source object. */
162  /* */
163  /* <Return> */
164  /* FreeType error code. 0 means success. An error is returned if a */
165  /* reallocation fails. */
166  /* */
169  FT_Int idx,
170  void* object,
172  {
173  if ( idx < 0 || idx >= table->max_elems )
174  {
175  FT_ERROR(( "ps_table_add: invalid index\n" ));
176  return FT_THROW( Invalid_Argument );
177  }
178 
179  if ( length < 0 )
180  {
181  FT_ERROR(( "ps_table_add: invalid length\n" ));
182  return FT_THROW( Invalid_Argument );
183  }
184 
185  /* grow the base block if needed */
186  if ( table->cursor + length > table->capacity )
187  {
188  FT_Error error;
189  FT_Offset new_size = table->capacity;
190  FT_PtrDist in_offset;
191 
192 
193  in_offset = (FT_Byte*)object - table->block;
194  if ( in_offset < 0 || (FT_Offset)in_offset >= table->capacity )
195  in_offset = -1;
196 
197  while ( new_size < table->cursor + length )
198  {
199  /* increase size by 25% and round up to the nearest multiple
200  of 1024 */
201  new_size += ( new_size >> 2 ) + 1;
202  new_size = FT_PAD_CEIL( new_size, 1024 );
203  }
204 
205  error = reallocate_t1_table( table, new_size );
206  if ( error )
207  return error;
208 
209  if ( in_offset >= 0 )
210  object = table->block + in_offset;
211  }
212 
213  /* add the object to the base block and adjust offset */
214  table->elements[idx] = table->block + table->cursor;
215  table->lengths [idx] = length;
216  FT_MEM_COPY( table->block + table->cursor, object, length );
217 
218  table->cursor += length;
219  return FT_Err_Ok;
220  }
221 
222 
223  /*************************************************************************/
224  /* */
225  /* <Function> */
226  /* ps_table_done */
227  /* */
228  /* <Description> */
229  /* Finalizes a PS_TableRec (i.e., reallocate it to its current */
230  /* cursor). */
231  /* */
232  /* <InOut> */
233  /* table :: The target table. */
234  /* */
235  /* <Note> */
236  /* This function does NOT release the heap's memory block. It is up */
237  /* to the caller to clean it, or reference it in its own structures. */
238  /* */
239  FT_LOCAL_DEF( void )
241  {
242  FT_Memory memory = table->memory;
243  FT_Error error;
244  FT_Byte* old_base = table->block;
245 
246 
247  /* should never fail, because rec.cursor <= rec.size */
248  if ( !old_base )
249  return;
250 
251  if ( FT_ALLOC( table->block, table->cursor ) )
252  return;
253  FT_MEM_COPY( table->block, old_base, table->cursor );
254  shift_elements( table, old_base );
255 
256  table->capacity = table->cursor;
257  FT_FREE( old_base );
258 
259  FT_UNUSED( error );
260  }
261 
262 
263  FT_LOCAL_DEF( void )
265  {
266  FT_Memory memory = table->memory;
267 
268 
269  if ( (FT_ULong)table->init == 0xDEADBEEFUL )
270  {
271  FT_FREE( table->block );
272  FT_FREE( table->elements );
273  FT_FREE( table->lengths );
274  table->init = 0;
275  }
276  }
277 
278 
279  /*************************************************************************/
280  /*************************************************************************/
281  /***** *****/
282  /***** T1 PARSER *****/
283  /***** *****/
284  /*************************************************************************/
285  /*************************************************************************/
286 
287 
288  /* first character must be already part of the comment */
289 
290  static void
291  skip_comment( FT_Byte* *acur,
292  FT_Byte* limit )
293  {
294  FT_Byte* cur = *acur;
295 
296 
297  while ( cur < limit )
298  {
299  if ( IS_PS_NEWLINE( *cur ) )
300  break;
301  cur++;
302  }
303 
304  *acur = cur;
305  }
306 
307 
308  static void
309  skip_spaces( FT_Byte* *acur,
310  FT_Byte* limit )
311  {
312  FT_Byte* cur = *acur;
313 
314 
315  while ( cur < limit )
316  {
317  if ( !IS_PS_SPACE( *cur ) )
318  {
319  if ( *cur == '%' )
320  /* According to the PLRM, a comment is equal to a space. */
321  skip_comment( &cur, limit );
322  else
323  break;
324  }
325  cur++;
326  }
327 
328  *acur = cur;
329  }
330 
331 
332 #define IS_OCTAL_DIGIT( c ) ( '0' <= (c) && (c) <= '7' )
333 
334 
335  /* first character must be `('; */
336  /* *acur is positioned at the character after the closing `)' */
337 
338  static FT_Error
339  skip_literal_string( FT_Byte* *acur,
340  FT_Byte* limit )
341  {
342  FT_Byte* cur = *acur;
343  FT_Int embed = 0;
344  FT_Error error = FT_ERR( Invalid_File_Format );
345  unsigned int i;
346 
347 
348  while ( cur < limit )
349  {
350  FT_Byte c = *cur;
351 
352 
353  ++cur;
354 
355  if ( c == '\\' )
356  {
357  /* Red Book 3rd ed., section `Literal Text Strings', p. 29: */
358  /* A backslash can introduce three different types */
359  /* of escape sequences: */
360  /* - a special escaped char like \r, \n, etc. */
361  /* - a one-, two-, or three-digit octal number */
362  /* - none of the above in which case the backslash is ignored */
363 
364  if ( cur == limit )
365  /* error (or to be ignored?) */
366  break;
367 
368  switch ( *cur )
369  {
370  /* skip `special' escape */
371  case 'n':
372  case 'r':
373  case 't':
374  case 'b':
375  case 'f':
376  case '\\':
377  case '(':
378  case ')':
379  ++cur;
380  break;
381 
382  default:
383  /* skip octal escape or ignore backslash */
384  for ( i = 0; i < 3 && cur < limit; ++i )
385  {
386  if ( !IS_OCTAL_DIGIT( *cur ) )
387  break;
388 
389  ++cur;
390  }
391  }
392  }
393  else if ( c == '(' )
394  embed++;
395  else if ( c == ')' )
396  {
397  embed--;
398  if ( embed == 0 )
399  {
400  error = FT_Err_Ok;
401  break;
402  }
403  }
404  }
405 
406  *acur = cur;
407 
408  return error;
409  }
410 
411 
412  /* first character must be `<' */
413 
414  static FT_Error
415  skip_string( FT_Byte* *acur,
416  FT_Byte* limit )
417  {
418  FT_Byte* cur = *acur;
419  FT_Error err = FT_Err_Ok;
420 
421 
422  while ( ++cur < limit )
423  {
424  /* All whitespace characters are ignored. */
425  skip_spaces( &cur, limit );
426  if ( cur >= limit )
427  break;
428 
429  if ( !IS_PS_XDIGIT( *cur ) )
430  break;
431  }
432 
433  if ( cur < limit && *cur != '>' )
434  {
435  FT_ERROR(( "skip_string: missing closing delimiter `>'\n" ));
436  err = FT_THROW( Invalid_File_Format );
437  }
438  else
439  cur++;
440 
441  *acur = cur;
442  return err;
443  }
444 
445 
446  /* first character must be the opening brace that */
447  /* starts the procedure */
448 
449  /* NB: [ and ] need not match: */
450  /* `/foo {[} def' is a valid PostScript fragment, */
451  /* even within a Type1 font */
452 
453  static FT_Error
454  skip_procedure( FT_Byte* *acur,
455  FT_Byte* limit )
456  {
457  FT_Byte* cur;
458  FT_Int embed = 0;
459  FT_Error error = FT_Err_Ok;
460 
461 
462  FT_ASSERT( **acur == '{' );
463 
464  for ( cur = *acur; cur < limit && error == FT_Err_Ok; ++cur )
465  {
466  switch ( *cur )
467  {
468  case '{':
469  ++embed;
470  break;
471 
472  case '}':
473  --embed;
474  if ( embed == 0 )
475  {
476  ++cur;
477  goto end;
478  }
479  break;
480 
481  case '(':
482  error = skip_literal_string( &cur, limit );
483  break;
484 
485  case '<':
486  error = skip_string( &cur, limit );
487  break;
488 
489  case '%':
490  skip_comment( &cur, limit );
491  break;
492  }
493  }
494 
495  end:
496  if ( embed != 0 )
497  error = FT_THROW( Invalid_File_Format );
498 
499  *acur = cur;
500 
501  return error;
502  }
503 
504 
505  /***********************************************************************/
506  /* */
507  /* All exported parsing routines handle leading whitespace and stop at */
508  /* the first character which isn't part of the just handled token. */
509  /* */
510  /***********************************************************************/
511 
512 
513  FT_LOCAL_DEF( void )
514  ps_parser_skip_PS_token( PS_Parser parser )
515  {
516  /* Note: PostScript allows any non-delimiting, non-whitespace */
517  /* character in a name (PS Ref Manual, 3rd ed, p31). */
518  /* PostScript delimiters are (, ), <, >, [, ], {, }, /, and %. */
519 
520  FT_Byte* cur = parser->cursor;
521  FT_Byte* limit = parser->limit;
522  FT_Error error = FT_Err_Ok;
523 
524 
525  skip_spaces( &cur, limit ); /* this also skips comments */
526  if ( cur >= limit )
527  goto Exit;
528 
529  /* self-delimiting, single-character tokens */
530  if ( *cur == '[' || *cur == ']' )
531  {
532  cur++;
533  goto Exit;
534  }
535 
536  /* skip balanced expressions (procedures and strings) */
537 
538  if ( *cur == '{' ) /* {...} */
539  {
540  error = skip_procedure( &cur, limit );
541  goto Exit;
542  }
543 
544  if ( *cur == '(' ) /* (...) */
545  {
546  error = skip_literal_string( &cur, limit );
547  goto Exit;
548  }
549 
550  if ( *cur == '<' ) /* <...> */
551  {
552  if ( cur + 1 < limit && *(cur + 1) == '<' ) /* << */
553  {
554  cur++;
555  cur++;
556  }
557  else
558  error = skip_string( &cur, limit );
559 
560  goto Exit;
561  }
562 
563  if ( *cur == '>' )
564  {
565  cur++;
566  if ( cur >= limit || *cur != '>' ) /* >> */
567  {
568  FT_ERROR(( "ps_parser_skip_PS_token:"
569  " unexpected closing delimiter `>'\n" ));
570  error = FT_THROW( Invalid_File_Format );
571  goto Exit;
572  }
573  cur++;
574  goto Exit;
575  }
576 
577  if ( *cur == '/' )
578  cur++;
579 
580  /* anything else */
581  while ( cur < limit )
582  {
583  /* *cur might be invalid (e.g., ')' or '}'), but this */
584  /* is handled by the test `cur == parser->cursor' below */
585  if ( IS_PS_DELIM( *cur ) )
586  break;
587 
588  cur++;
589  }
590 
591  Exit:
592  if ( cur < limit && cur == parser->cursor )
593  {
594  FT_ERROR(( "ps_parser_skip_PS_token:"
595  " current token is `%c' which is self-delimiting\n"
596  " "
597  " but invalid at this point\n",
598  *cur ));
599 
600  error = FT_THROW( Invalid_File_Format );
601  }
602 
603  parser->error = error;
604  parser->cursor = cur;
605  }
606 
607 
608  FT_LOCAL_DEF( void )
610  {
611  skip_spaces( &parser->cursor, parser->limit );
612  }
613 
614 
615  /* `token' here means either something between balanced delimiters */
616  /* or the next token; the delimiters are not removed. */
617 
618  FT_LOCAL_DEF( void )
620  T1_Token token )
621  {
622  FT_Byte* cur;
623  FT_Byte* limit;
624  FT_Int embed;
625 
626 
627  token->type = T1_TOKEN_TYPE_NONE;
628  token->start = 0;
629  token->limit = 0;
630 
631  /* first of all, skip leading whitespace */
632  ps_parser_skip_spaces( parser );
633 
634  cur = parser->cursor;
635  limit = parser->limit;
636 
637  if ( cur >= limit )
638  return;
639 
640  switch ( *cur )
641  {
642  /************* check for literal string *****************/
643  case '(':
644  token->type = T1_TOKEN_TYPE_STRING;
645  token->start = cur;
646 
647  if ( skip_literal_string( &cur, limit ) == FT_Err_Ok )
648  token->limit = cur;
649  break;
650 
651  /************* check for programs/array *****************/
652  case '{':
653  token->type = T1_TOKEN_TYPE_ARRAY;
654  token->start = cur;
655 
656  if ( skip_procedure( &cur, limit ) == FT_Err_Ok )
657  token->limit = cur;
658  break;
659 
660  /************* check for table/array ********************/
661  /* XXX: in theory we should also look for "<<" */
662  /* since this is semantically equivalent to "["; */
663  /* in practice it doesn't matter (?) */
664  case '[':
665  token->type = T1_TOKEN_TYPE_ARRAY;
666  embed = 1;
667  token->start = cur++;
668 
669  /* we need this to catch `[ ]' */
670  parser->cursor = cur;
671  ps_parser_skip_spaces( parser );
672  cur = parser->cursor;
673 
674  while ( cur < limit && !parser->error )
675  {
676  /* XXX: this is wrong because it does not */
677  /* skip comments, procedures, and strings */
678  if ( *cur == '[' )
679  embed++;
680  else if ( *cur == ']' )
681  {
682  embed--;
683  if ( embed <= 0 )
684  {
685  token->limit = ++cur;
686  break;
687  }
688  }
689 
690  parser->cursor = cur;
691  ps_parser_skip_PS_token( parser );
692  /* we need this to catch `[XXX ]' */
693  ps_parser_skip_spaces ( parser );
694  cur = parser->cursor;
695  }
696  break;
697 
698  /* ************ otherwise, it is any token **************/
699  default:
700  token->start = cur;
701  token->type = ( *cur == '/' ? T1_TOKEN_TYPE_KEY : T1_TOKEN_TYPE_ANY );
702  ps_parser_skip_PS_token( parser );
703  cur = parser->cursor;
704  if ( !parser->error )
705  token->limit = cur;
706  }
707 
708  if ( !token->limit )
709  {
710  token->start = 0;
711  token->type = T1_TOKEN_TYPE_NONE;
712  }
713 
714  parser->cursor = cur;
715  }
716 
717 
718  /* NB: `tokens' can be NULL if we only want to count */
719  /* the number of array elements */
720 
721  FT_LOCAL_DEF( void )
723  T1_Token tokens,
724  FT_UInt max_tokens,
725  FT_Int* pnum_tokens )
726  {
727  T1_TokenRec master;
728 
729 
730  *pnum_tokens = -1;
731 
732  /* this also handles leading whitespace */
733  ps_parser_to_token( parser, &master );
734 
735  if ( master.type == T1_TOKEN_TYPE_ARRAY )
736  {
737  FT_Byte* old_cursor = parser->cursor;
738  FT_Byte* old_limit = parser->limit;
739  T1_Token cur = tokens;
740  T1_Token limit = cur + max_tokens;
741 
742 
743  /* don't include outermost delimiters */
744  parser->cursor = master.start + 1;
745  parser->limit = master.limit - 1;
746 
747  while ( parser->cursor < parser->limit )
748  {
749  T1_TokenRec token;
750 
751 
752  ps_parser_to_token( parser, &token );
753  if ( !token.type )
754  break;
755 
756  if ( tokens != NULL && cur < limit )
757  *cur = token;
758 
759  cur++;
760  }
761 
762  *pnum_tokens = (FT_Int)( cur - tokens );
763 
764  parser->cursor = old_cursor;
765  parser->limit = old_limit;
766  }
767  }
768 
769 
770  /* first character must be a delimiter or a part of a number */
771  /* NB: `coords' can be NULL if we just want to skip the */
772  /* array; in this case we ignore `max_coords' */
773 
774  static FT_Int
775  ps_tocoordarray( FT_Byte* *acur,
776  FT_Byte* limit,
777  FT_Int max_coords,
778  FT_Short* coords )
779  {
780  FT_Byte* cur = *acur;
781  FT_Int count = 0;
782  FT_Byte c, ender;
783 
784 
785  if ( cur >= limit )
786  goto Exit;
787 
788  /* check for the beginning of an array; otherwise, only one number */
789  /* will be read */
790  c = *cur;
791  ender = 0;
792 
793  if ( c == '[' )
794  ender = ']';
795  else if ( c == '{' )
796  ender = '}';
797 
798  if ( ender )
799  cur++;
800 
801  /* now, read the coordinates */
802  while ( cur < limit )
803  {
804  FT_Short dummy;
805  FT_Byte* old_cur;
806 
807 
808  /* skip whitespace in front of data */
809  skip_spaces( &cur, limit );
810  if ( cur >= limit )
811  goto Exit;
812 
813  if ( *cur == ender )
814  {
815  cur++;
816  break;
817  }
818 
819  old_cur = cur;
820 
821  if ( coords != NULL && count >= max_coords )
822  break;
823 
824  /* call PS_Conv_ToFixed() even if coords == NULL */
825  /* to properly parse number at `cur' */
826  *( coords != NULL ? &coords[count] : &dummy ) =
827  (FT_Short)( PS_Conv_ToFixed( &cur, limit, 0 ) >> 16 );
828 
829  if ( old_cur == cur )
830  {
831  count = -1;
832  goto Exit;
833  }
834  else
835  count++;
836 
837  if ( !ender )
838  break;
839  }
840 
841  Exit:
842  *acur = cur;
843  return count;
844  }
845 
846 
847  /* first character must be a delimiter or a part of a number */
848  /* NB: `values' can be NULL if we just want to skip the */
849  /* array; in this case we ignore `max_values' */
850 
851  static FT_Int
852  ps_tofixedarray( FT_Byte* *acur,
853  FT_Byte* limit,
854  FT_Int max_values,
855  FT_Fixed* values,
856  FT_Int power_ten )
857  {
858  FT_Byte* cur = *acur;
859  FT_Int count = 0;
860  FT_Byte c, ender;
861 
862 
863  if ( cur >= limit )
864  goto Exit;
865 
866  /* Check for the beginning of an array. Otherwise, only one number */
867  /* will be read. */
868  c = *cur;
869  ender = 0;
870 
871  if ( c == '[' )
872  ender = ']';
873  else if ( c == '{' )
874  ender = '}';
875 
876  if ( ender )
877  cur++;
878 
879  /* now, read the values */
880  while ( cur < limit )
881  {
882  FT_Fixed dummy;
883  FT_Byte* old_cur;
884 
885 
886  /* skip whitespace in front of data */
887  skip_spaces( &cur, limit );
888  if ( cur >= limit )
889  goto Exit;
890 
891  if ( *cur == ender )
892  {
893  cur++;
894  break;
895  }
896 
897  old_cur = cur;
898 
899  if ( values != NULL && count >= max_values )
900  break;
901 
902  /* call PS_Conv_ToFixed() even if coords == NULL */
903  /* to properly parse number at `cur' */
904  *( values != NULL ? &values[count] : &dummy ) =
905  PS_Conv_ToFixed( &cur, limit, power_ten );
906 
907  if ( old_cur == cur )
908  {
909  count = -1;
910  goto Exit;
911  }
912  else
913  count++;
914 
915  if ( !ender )
916  break;
917  }
918 
919  Exit:
920  *acur = cur;
921  return count;
922  }
923 
924 
925 #if 0
926 
927  static FT_String*
928  ps_tostring( FT_Byte** cursor,
929  FT_Byte* limit,
930  FT_Memory memory )
931  {
932  FT_Byte* cur = *cursor;
933  FT_PtrDist len = 0;
934  FT_Int count;
935  FT_String* result;
936  FT_Error error;
937 
938 
939  /* XXX: some stupid fonts have a `Notice' or `Copyright' string */
940  /* that simply doesn't begin with an opening parenthesis, even */
941  /* though they have a closing one! E.g. "amuncial.pfb" */
942  /* */
943  /* We must deal with these ill-fated cases there. Note that */
944  /* these fonts didn't work with the old Type 1 driver as the */
945  /* notice/copyright was not recognized as a valid string token */
946  /* and made the old token parser commit errors. */
947 
948  while ( cur < limit && ( *cur == ' ' || *cur == '\t' ) )
949  cur++;
950  if ( cur + 1 >= limit )
951  return 0;
952 
953  if ( *cur == '(' )
954  cur++; /* skip the opening parenthesis, if there is one */
955 
956  *cursor = cur;
957  count = 0;
958 
959  /* then, count its length */
960  for ( ; cur < limit; cur++ )
961  {
962  if ( *cur == '(' )
963  count++;
964 
965  else if ( *cur == ')' )
966  {
967  count--;
968  if ( count < 0 )
969  break;
970  }
971  }
972 
973  len = cur - *cursor;
974  if ( cur >= limit || FT_ALLOC( result, len + 1 ) )
975  return 0;
976 
977  /* now copy the string */
978  FT_MEM_COPY( result, *cursor, len );
979  result[len] = '\0';
980  *cursor = cur;
981  return result;
982  }
983 
984 #endif /* 0 */
985 
986 
987  static int
988  ps_tobool( FT_Byte* *acur,
989  FT_Byte* limit )
990  {
991  FT_Byte* cur = *acur;
992  FT_Bool result = 0;
993 
994 
995  /* return 1 if we find `true', 0 otherwise */
996  if ( cur + 3 < limit &&
997  cur[0] == 't' &&
998  cur[1] == 'r' &&
999  cur[2] == 'u' &&
1000  cur[3] == 'e' )
1001  {
1002  result = 1;
1003  cur += 5;
1004  }
1005  else if ( cur + 4 < limit &&
1006  cur[0] == 'f' &&
1007  cur[1] == 'a' &&
1008  cur[2] == 'l' &&
1009  cur[3] == 's' &&
1010  cur[4] == 'e' )
1011  {
1012  result = 0;
1013  cur += 6;
1014  }
1015 
1016  *acur = cur;
1017  return result;
1018  }
1019 
1020 
1021  /* load a simple field (i.e. non-table) into the current list of objects */
1022 
1025  const T1_Field field,
1026  void** objects,
1027  FT_UInt max_objects,
1028  FT_ULong* pflags )
1029  {
1030  T1_TokenRec token;
1031  FT_Byte* cur;
1032  FT_Byte* limit;
1033  FT_UInt count;
1034  FT_UInt idx;
1035  FT_Error error;
1037 
1038 
1039  /* this also skips leading whitespace */
1040  ps_parser_to_token( parser, &token );
1041  if ( !token.type )
1042  goto Fail;
1043 
1044  count = 1;
1045  idx = 0;
1046  cur = token.start;
1047  limit = token.limit;
1048 
1049  type = field->type;
1050 
1051  /* we must detect arrays in /FontBBox */
1052  if ( type == T1_FIELD_TYPE_BBOX )
1053  {
1054  T1_TokenRec token2;
1055  FT_Byte* old_cur = parser->cursor;
1056  FT_Byte* old_limit = parser->limit;
1057 
1058 
1059  /* don't include delimiters */
1060  parser->cursor = token.start + 1;
1061  parser->limit = token.limit - 1;
1062 
1063  ps_parser_to_token( parser, &token2 );
1064  parser->cursor = old_cur;
1065  parser->limit = old_limit;
1066 
1067  if ( token2.type == T1_TOKEN_TYPE_ARRAY )
1068  {
1070  goto FieldArray;
1071  }
1072  }
1073  else if ( token.type == T1_TOKEN_TYPE_ARRAY )
1074  {
1075  count = max_objects;
1076 
1077  FieldArray:
1078  /* if this is an array and we have no blend, an error occurs */
1079  if ( max_objects == 0 )
1080  goto Fail;
1081 
1082  idx = 1;
1083 
1084  /* don't include delimiters */
1085  cur++;
1086  limit--;
1087  }
1088 
1089  for ( ; count > 0; count--, idx++ )
1090  {
1091  FT_Byte* q = (FT_Byte*)objects[idx] + field->offset;
1092  FT_Long val;
1093  FT_String* string;
1094 
1095 
1096  skip_spaces( &cur, limit );
1097 
1098  switch ( type )
1099  {
1100  case T1_FIELD_TYPE_BOOL:
1101  val = ps_tobool( &cur, limit );
1102  goto Store_Integer;
1103 
1104  case T1_FIELD_TYPE_FIXED:
1105  val = PS_Conv_ToFixed( &cur, limit, 0 );
1106  goto Store_Integer;
1107 
1109  val = PS_Conv_ToFixed( &cur, limit, 3 );
1110  goto Store_Integer;
1111 
1112  case T1_FIELD_TYPE_INTEGER:
1113  val = PS_Conv_ToInt( &cur, limit );
1114  /* fall through */
1115 
1116  Store_Integer:
1117  switch ( field->size )
1118  {
1119  case (8 / FT_CHAR_BIT):
1120  *(FT_Byte*)q = (FT_Byte)val;
1121  break;
1122 
1123  case (16 / FT_CHAR_BIT):
1124  *(FT_UShort*)q = (FT_UShort)val;
1125  break;
1126 
1127  case (32 / FT_CHAR_BIT):
1128  *(FT_UInt32*)q = (FT_UInt32)val;
1129  break;
1130 
1131  default: /* for 64-bit systems */
1132  *(FT_Long*)q = val;
1133  }
1134  break;
1135 
1136  case T1_FIELD_TYPE_STRING:
1137  case T1_FIELD_TYPE_KEY:
1138  {
1139  FT_Memory memory = parser->memory;
1140  FT_UInt len = (FT_UInt)( limit - cur );
1141 
1142 
1143  if ( cur >= limit )
1144  break;
1145 
1146  /* we allow both a string or a name */
1147  /* for cases like /FontName (foo) def */
1148  if ( token.type == T1_TOKEN_TYPE_KEY )
1149  {
1150  /* don't include leading `/' */
1151  len--;
1152  cur++;
1153  }
1154  else if ( token.type == T1_TOKEN_TYPE_STRING )
1155  {
1156  /* don't include delimiting parentheses */
1157  /* XXX we don't handle <<...>> here */
1158  /* XXX should we convert octal escapes? */
1159  /* if so, what encoding should we use? */
1160  cur++;
1161  len -= 2;
1162  }
1163  else
1164  {
1165  FT_ERROR(( "ps_parser_load_field:"
1166  " expected a name or string\n"
1167  " "
1168  " but found token of type %d instead\n",
1169  token.type ));
1170  error = FT_THROW( Invalid_File_Format );
1171  goto Exit;
1172  }
1173 
1174  /* for this to work (FT_String**)q must have been */
1175  /* initialized to NULL */
1176  if ( *(FT_String**)q != NULL )
1177  {
1178  FT_TRACE0(( "ps_parser_load_field: overwriting field %s\n",
1179  field->ident ));
1180  FT_FREE( *(FT_String**)q );
1181  *(FT_String**)q = NULL;
1182  }
1183 
1184  if ( FT_ALLOC( string, len + 1 ) )
1185  goto Exit;
1186 
1187  FT_MEM_COPY( string, cur, len );
1188  string[len] = 0;
1189 
1190  *(FT_String**)q = string;
1191  }
1192  break;
1193 
1194  case T1_FIELD_TYPE_BBOX:
1195  {
1196  FT_Fixed temp[4];
1197  FT_BBox* bbox = (FT_BBox*)q;
1198  FT_Int result;
1199 
1200 
1201  result = ps_tofixedarray( &cur, limit, 4, temp, 0 );
1202 
1203  if ( result < 0 )
1204  {
1205  FT_ERROR(( "ps_parser_load_field:"
1206  " expected four integers in bounding box\n" ));
1207  error = FT_THROW( Invalid_File_Format );
1208  goto Exit;
1209  }
1210 
1211  bbox->xMin = FT_RoundFix( temp[0] );
1212  bbox->yMin = FT_RoundFix( temp[1] );
1213  bbox->xMax = FT_RoundFix( temp[2] );
1214  bbox->yMax = FT_RoundFix( temp[3] );
1215  }
1216  break;
1217 
1218  case T1_FIELD_TYPE_MM_BBOX:
1219  {
1220  FT_Memory memory = parser->memory;
1221  FT_Fixed* temp;
1222  FT_Int result;
1223  FT_UInt i;
1224 
1225 
1226  if ( FT_NEW_ARRAY( temp, max_objects * 4 ) )
1227  goto Exit;
1228 
1229  for ( i = 0; i < 4; i++ )
1230  {
1231  result = ps_tofixedarray( &cur, limit, max_objects,
1232  temp + i * max_objects, 0 );
1233  if ( result < 0 )
1234  {
1235  FT_ERROR(( "ps_parser_load_field:"
1236  " expected %d integers in the %s subarray\n"
1237  " "
1238  " of /FontBBox in the /Blend dictionary\n",
1239  max_objects,
1240  i == 0 ? "first"
1241  : ( i == 1 ? "second"
1242  : ( i == 2 ? "third"
1243  : "fourth" ) ) ));
1244  error = FT_THROW( Invalid_File_Format );
1245  goto Exit;
1246  }
1247 
1248  skip_spaces( &cur, limit );
1249  }
1250 
1251  for ( i = 0; i < max_objects; i++ )
1252  {
1253  FT_BBox* bbox = (FT_BBox*)objects[i];
1254 
1255 
1256  bbox->xMin = FT_RoundFix( temp[i ] );
1257  bbox->yMin = FT_RoundFix( temp[i + max_objects] );
1258  bbox->xMax = FT_RoundFix( temp[i + 2 * max_objects] );
1259  bbox->yMax = FT_RoundFix( temp[i + 3 * max_objects] );
1260  }
1261 
1262  FT_FREE( temp );
1263  }
1264  break;
1265 
1266  default:
1267  /* an error occurred */
1268  goto Fail;
1269  }
1270  }
1271 
1272 #if 0 /* obsolete -- keep for reference */
1273  if ( pflags )
1274  *pflags |= 1L << field->flag_bit;
1275 #else
1276  FT_UNUSED( pflags );
1277 #endif
1278 
1279  error = FT_Err_Ok;
1280 
1281  Exit:
1282  return error;
1283 
1284  Fail:
1285  error = FT_THROW( Invalid_File_Format );
1286  goto Exit;
1287  }
1288 
1289 
1290 #define T1_MAX_TABLE_ELEMENTS 32
1291 
1292 
1295  const T1_Field field,
1296  void** objects,
1297  FT_UInt max_objects,
1298  FT_ULong* pflags )
1299  {
1301  T1_Token token;
1302  FT_Int num_elements;
1304  FT_Byte* old_cursor;
1305  FT_Byte* old_limit;
1306  T1_FieldRec fieldrec = *(T1_Field)field;
1307 
1308 
1309  fieldrec.type = T1_FIELD_TYPE_INTEGER;
1310  if ( field->type == T1_FIELD_TYPE_FIXED_ARRAY ||
1311  field->type == T1_FIELD_TYPE_BBOX )
1312  fieldrec.type = T1_FIELD_TYPE_FIXED;
1313 
1314  ps_parser_to_token_array( parser, elements,
1315  T1_MAX_TABLE_ELEMENTS, &num_elements );
1316  if ( num_elements < 0 )
1317  {
1318  error = FT_ERR( Ignore );
1319  goto Exit;
1320  }
1321  if ( (FT_UInt)num_elements > field->array_max )
1322  num_elements = field->array_max;
1323 
1324  old_cursor = parser->cursor;
1325  old_limit = parser->limit;
1326 
1327  /* we store the elements count if necessary; */
1328  /* we further assume that `count_offset' can't be zero */
1329  if ( field->type != T1_FIELD_TYPE_BBOX && field->count_offset != 0 )
1330  *(FT_Byte*)( (FT_Byte*)objects[0] + field->count_offset ) =
1331  (FT_Byte)num_elements;
1332 
1333  /* we now load each element, adjusting the field.offset on each one */
1334  token = elements;
1335  for ( ; num_elements > 0; num_elements--, token++ )
1336  {
1337  parser->cursor = token->start;
1338  parser->limit = token->limit;
1339  ps_parser_load_field( parser, &fieldrec, objects, max_objects, 0 );
1340  fieldrec.offset += fieldrec.size;
1341  }
1342 
1343 #if 0 /* obsolete -- keep for reference */
1344  if ( pflags )
1345  *pflags |= 1L << field->flag_bit;
1346 #else
1347  FT_UNUSED( pflags );
1348 #endif
1349 
1350  parser->cursor = old_cursor;
1351  parser->limit = old_limit;
1352 
1353  Exit:
1354  return error;
1355  }
1356 
1357 
1360  {
1361  ps_parser_skip_spaces( parser );
1362  return PS_Conv_ToInt( &parser->cursor, parser->limit );
1363  }
1364 
1365 
1366  /* first character must be `<' if `delimiters' is non-zero */
1367 
1370  FT_Byte* bytes,
1371  FT_Offset max_bytes,
1372  FT_Long* pnum_bytes,
1373  FT_Bool delimiters )
1374  {
1376  FT_Byte* cur;
1377 
1378 
1379  ps_parser_skip_spaces( parser );
1380  cur = parser->cursor;
1381 
1382  if ( cur >= parser->limit )
1383  goto Exit;
1384 
1385  if ( delimiters )
1386  {
1387  if ( *cur != '<' )
1388  {
1389  FT_ERROR(( "ps_parser_to_bytes: Missing starting delimiter `<'\n" ));
1390  error = FT_THROW( Invalid_File_Format );
1391  goto Exit;
1392  }
1393 
1394  cur++;
1395  }
1396 
1397  *pnum_bytes = PS_Conv_ASCIIHexDecode( &cur,
1398  parser->limit,
1399  bytes,
1400  max_bytes );
1401 
1402  if ( delimiters )
1403  {
1404  if ( cur < parser->limit && *cur != '>' )
1405  {
1406  FT_ERROR(( "ps_parser_to_bytes: Missing closing delimiter `>'\n" ));
1407  error = FT_THROW( Invalid_File_Format );
1408  goto Exit;
1409  }
1410 
1411  cur++;
1412  }
1413 
1414  parser->cursor = cur;
1415 
1416  Exit:
1417  return error;
1418  }
1419 
1420 
1423  FT_Int power_ten )
1424  {
1425  ps_parser_skip_spaces( parser );
1426  return PS_Conv_ToFixed( &parser->cursor, parser->limit, power_ten );
1427  }
1428 
1429 
1430  FT_LOCAL_DEF( FT_Int )
1432  FT_Int max_coords,
1433  FT_Short* coords )
1434  {
1435  ps_parser_skip_spaces( parser );
1436  return ps_tocoordarray( &parser->cursor, parser->limit,
1437  max_coords, coords );
1438  }
1439 
1440 
1441  FT_LOCAL_DEF( FT_Int )
1443  FT_Int max_values,
1444  FT_Fixed* values,
1445  FT_Int power_ten )
1446  {
1447  ps_parser_skip_spaces( parser );
1448  return ps_tofixedarray( &parser->cursor, parser->limit,
1449  max_values, values, power_ten );
1450  }
1451 
1452 
1453 #if 0
1454 
1456  T1_ToString( PS_Parser parser )
1457  {
1458  return ps_tostring( &parser->cursor, parser->limit, parser->memory );
1459  }
1460 
1461 
1463  T1_ToBool( PS_Parser parser )
1464  {
1465  return ps_tobool( &parser->cursor, parser->limit );
1466  }
1467 
1468 #endif /* 0 */
1469 
1470 
1471  FT_LOCAL_DEF( void )
1473  FT_Byte* base,
1474  FT_Byte* limit,
1475  FT_Memory memory )
1476  {
1477  parser->error = FT_Err_Ok;
1478  parser->base = base;
1479  parser->limit = limit;
1480  parser->cursor = base;
1481  parser->memory = memory;
1482  parser->funcs = ps_parser_funcs;
1483  }
1484 
1485 
1486  FT_LOCAL_DEF( void )
1488  {
1489  FT_UNUSED( parser );
1490  }
1491 
1492 
1493  /*************************************************************************/
1494  /*************************************************************************/
1495  /***** *****/
1496  /***** T1 BUILDER *****/
1497  /***** *****/
1498  /*************************************************************************/
1499  /*************************************************************************/
1500 
1501  /*************************************************************************/
1502  /* */
1503  /* <Function> */
1504  /* t1_builder_init */
1505  /* */
1506  /* <Description> */
1507  /* Initializes a given glyph builder. */
1508  /* */
1509  /* <InOut> */
1510  /* builder :: A pointer to the glyph builder to initialize. */
1511  /* */
1512  /* <Input> */
1513  /* face :: The current face object. */
1514  /* */
1515  /* size :: The current size object. */
1516  /* */
1517  /* glyph :: The current glyph object. */
1518  /* */
1519  /* hinting :: Whether hinting should be applied. */
1520  /* */
1521  FT_LOCAL_DEF( void )
1523  FT_Face face,
1524  FT_Size size,
1525  FT_GlyphSlot glyph,
1526  FT_Bool hinting )
1527  {
1528  builder->parse_state = T1_Parse_Start;
1529  builder->load_points = 1;
1530 
1531  builder->face = face;
1532  builder->glyph = glyph;
1533  builder->memory = face->memory;
1534 
1535  if ( glyph )
1536  {
1537  FT_GlyphLoader loader = glyph->internal->loader;
1538 
1539 
1540  builder->loader = loader;
1541  builder->base = &loader->base.outline;
1542  builder->current = &loader->current.outline;
1543  FT_GlyphLoader_Rewind( loader );
1544 
1545  builder->hints_globals = size->internal;
1546  builder->hints_funcs = 0;
1547 
1548  if ( hinting )
1549  builder->hints_funcs = glyph->internal->glyph_hints;
1550  }
1551 
1552  builder->pos_x = 0;
1553  builder->pos_y = 0;
1554 
1555  builder->left_bearing.x = 0;
1556  builder->left_bearing.y = 0;
1557  builder->advance.x = 0;
1558  builder->advance.y = 0;
1559 
1560  builder->funcs = t1_builder_funcs;
1561  }
1562 
1563 
1564  /*************************************************************************/
1565  /* */
1566  /* <Function> */
1567  /* t1_builder_done */
1568  /* */
1569  /* <Description> */
1570  /* Finalizes a given glyph builder. Its contents can still be used */
1571  /* after the call, but the function saves important information */
1572  /* within the corresponding glyph slot. */
1573  /* */
1574  /* <Input> */
1575  /* builder :: A pointer to the glyph builder to finalize. */
1576  /* */
1577  FT_LOCAL_DEF( void )
1579  {
1580  FT_GlyphSlot glyph = builder->glyph;
1581 
1582 
1583  if ( glyph )
1584  glyph->outline = *builder->base;
1585  }
1586 
1587 
1588  /* check that there is enough space for `count' more points */
1591  FT_Int count )
1592  {
1593  return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
1594  }
1595 
1596 
1597  /* add a new point, do not check space */
1598  FT_LOCAL_DEF( void )
1600  FT_Pos x,
1601  FT_Pos y,
1602  FT_Byte flag )
1603  {
1604  FT_Outline* outline = builder->current;
1605 
1606 
1607  if ( builder->load_points )
1608  {
1609  FT_Vector* point = outline->points + outline->n_points;
1610  FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
1611 
1612 
1613  point->x = FIXED_TO_INT( x );
1614  point->y = FIXED_TO_INT( y );
1615  *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
1616  }
1617  outline->n_points++;
1618  }
1619 
1620 
1621  /* check space for a new on-curve point, then add it */
1624  FT_Pos x,
1625  FT_Pos y )
1626  {
1627  FT_Error error;
1628 
1629 
1630  error = t1_builder_check_points( builder, 1 );
1631  if ( !error )
1632  t1_builder_add_point( builder, x, y, 1 );
1633 
1634  return error;
1635  }
1636 
1637 
1638  /* check space for a new contour, then add it */
1641  {
1642  FT_Outline* outline = builder->current;
1643  FT_Error error;
1644 
1645 
1646  /* this might happen in invalid fonts */
1647  if ( !outline )
1648  {
1649  FT_ERROR(( "t1_builder_add_contour: no outline to add points to\n" ));
1650  return FT_THROW( Invalid_File_Format );
1651  }
1652 
1653  if ( !builder->load_points )
1654  {
1655  outline->n_contours++;
1656  return FT_Err_Ok;
1657  }
1658 
1659  error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
1660  if ( !error )
1661  {
1662  if ( outline->n_contours > 0 )
1663  outline->contours[outline->n_contours - 1] =
1664  (short)( outline->n_points - 1 );
1665 
1666  outline->n_contours++;
1667  }
1668 
1669  return error;
1670  }
1671 
1672 
1673  /* if a path was begun, add its first on-curve point */
1676  FT_Pos x,
1677  FT_Pos y )
1678  {
1679  FT_Error error = FT_ERR( Invalid_File_Format );
1680 
1681 
1682  /* test whether we are building a new contour */
1683 
1684  if ( builder->parse_state == T1_Parse_Have_Path )
1685  error = FT_Err_Ok;
1686  else
1687  {
1688  builder->parse_state = T1_Parse_Have_Path;
1689  error = t1_builder_add_contour( builder );
1690  if ( !error )
1691  error = t1_builder_add_point1( builder, x, y );
1692  }
1693 
1694  return error;
1695  }
1696 
1697 
1698  /* close the current contour */
1699  FT_LOCAL_DEF( void )
1701  {
1702  FT_Outline* outline = builder->current;
1703  FT_Int first;
1704 
1705 
1706  if ( !outline )
1707  return;
1708 
1709  first = outline->n_contours <= 1
1710  ? 0 : outline->contours[outline->n_contours - 2] + 1;
1711 
1712  /* We must not include the last point in the path if it */
1713  /* is located on the first point. */
1714  if ( outline->n_points > 1 )
1715  {
1716  FT_Vector* p1 = outline->points + first;
1717  FT_Vector* p2 = outline->points + outline->n_points - 1;
1718  FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1;
1719 
1720 
1721  /* `delete' last point only if it coincides with the first */
1722  /* point and it is not a control point (which can happen). */
1723  if ( p1->x == p2->x && p1->y == p2->y )
1724  if ( *control == FT_CURVE_TAG_ON )
1725  outline->n_points--;
1726  }
1727 
1728  if ( outline->n_contours > 0 )
1729  {
1730  /* Don't add contours only consisting of one point, i.e., */
1731  /* check whether the first and the last point is the same. */
1732  if ( first == outline->n_points - 1 )
1733  {
1734  outline->n_contours--;
1735  outline->n_points--;
1736  }
1737  else
1738  outline->contours[outline->n_contours - 1] =
1739  (short)( outline->n_points - 1 );
1740  }
1741  }
1742 
1743 
1744  /*************************************************************************/
1745  /*************************************************************************/
1746  /***** *****/
1747  /***** OTHER *****/
1748  /***** *****/
1749  /*************************************************************************/
1750  /*************************************************************************/
1751 
1752  FT_LOCAL_DEF( void )
1754  FT_Offset length,
1755  FT_UShort seed )
1756  {
1758  buffer + length,
1759  buffer,
1760  length,
1761  &seed );
1762  }
1763 
1764 
1765 /* END */
GLenum GLuint GLenum GLsizei length
#define FT_ALLOC(ptr, size)
Definition: ftmemory.h:260
#define FIXED_TO_INT(x)
Definition: ftcalc.h:179
int FT_Error
Definition: fttypes.h:296
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:333
signed long FT_Long
Definition: fttypes.h:238
unsigned long FT_ULong
Definition: fttypes.h:249
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:59
t1_builder_done(T1_Builder builder)
Definition: psobjs.c:1578
t1_builder_add_point1(T1_Builder builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:1623
PS_Conv_ToFixed(FT_Byte **cursor, FT_Byte *limit, FT_Long power_ten)
Definition: psconv.c:192
#define FT_CURVE_TAG_CUBIC
Definition: ftimage.h:518
#define NULL
Definition: ftobjs.h:61
GLint GLint GLint GLint GLint GLint y
enum T1_FieldType_ T1_FieldType
signed int FT_Int
Definition: fttypes.h:216
short n_contours
Definition: ftimage.h:385
GLdouble GLdouble GLdouble GLdouble q
FT_BBox bbox
Definition: ftbbox.c:565
ps_parser_load_field_table(PS_Parser parser, const T1_Field field, void **objects, FT_UInt max_objects, FT_ULong *pflags)
Definition: psobjs.c:1294
t1_builder_start_point(T1_Builder builder, FT_Pos x, FT_Pos y)
Definition: psobjs.c:1675
ps_parser_done(PS_Parser parser)
Definition: psobjs.c:1487
return FT_THROW(Missing_Property)
short * contours
Definition: ftimage.h:390
PS_Conv_EexecDecode(FT_Byte **cursor, FT_Byte *limit, FT_Byte *buffer, FT_Offset n, FT_UShort *seed)
Definition: psconv.c:549
FT_RoundFix(FT_Fixed a)
Definition: ftcalc.c:76
#define FT_UNUSED(arg)
Definition: ftconfig.h:76
char * tags
Definition: ftimage.h:389
ps_parser_to_fixed(PS_Parser parser, FT_Int power_ten)
Definition: psobjs.c:1422
unsigned int FT_UInt32
Definition: ftconfig.h:133
#define IS_PS_NEWLINE(ch)
Definition: psaux.h:830
ps_parser_skip_PS_token(PS_Parser parser)
Definition: psobjs.c:514
GLint GLint GLint GLint GLint x
ps_parser_to_fixed_array(PS_Parser parser, FT_Int max_values, FT_Fixed *values, FT_Int power_ten)
Definition: psobjs.c:1442
#define IS_PS_SPACE(ch)
Definition: psaux.h:834
return FT_Err_Ok
Definition: ftbbox.c:645
ps_parser_to_token(PS_Parser parser, T1_Token token)
Definition: psobjs.c:619
png_uint_32 i
Definition: png.h:2640
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
ps_table_new(PS_Table table, FT_Int count, FT_Memory memory)
Definition: psobjs.c:69
GLenum GLuint GLint GLenum face
#define const
Definition: zconf.h:91
FT_Outline outline
Definition: freetype.h:1631
FT_CALLBACK_TABLE_DEF const T1_Builder_FuncsRec t1_builder_funcs
Definition: psauxmod.c:60
typedefFT_BEGIN_HEADER struct FT_GlyphLoaderRec_ * FT_GlyphLoader
Definition: ftgloadr.h:43
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
ps_table_add(PS_Table table, FT_Int idx, void *object, FT_PtrDist length)
Definition: psobjs.c:168
#define FT_PAD_CEIL(x, n)
Definition: ftobjs.h:78
unsigned char FT_Byte
Definition: fttypes.h:150
FT_CALLBACK_TABLE_DEF const PS_Parser_FuncsRec ps_parser_funcs
Definition: psauxmod.c:41
#define FT_FREE(ptr)
Definition: ftmemory.h:286
FT_Pos yMax
Definition: ftimage.h:119
FT_Pos xMin
Definition: ftimage.h:118
struct T1_FieldRec_ * T1_Field
Definition: psaux.h:150
PS_Parser_FuncsRec funcs
Definition: psaux.h:436
GLenum GLsizei len
ps_parser_skip_spaces(PS_Parser parser)
Definition: psobjs.c:609
FT_Byte * cursor
Definition: psaux.h:430
ps_table_release(PS_Table table)
Definition: psobjs.c:264
FT_UInt idx
Definition: cffcmap.c:127
#define FT_ERR(e)
Definition: fttypes.h:582
ps_parser_load_field(PS_Parser parser, const T1_Field field, void **objects, FT_UInt max_objects, FT_ULong *pflags)
Definition: psobjs.c:1024
FT_Error error
Definition: cffdrivr.c:411
ps_parser_to_int(PS_Parser parser)
Definition: psobjs.c:1359
FT_Pos x
Definition: ftimage.h:77
char FT_String
Definition: fttypes.h:183
FT_Byte * start
Definition: psaux.h:171
PS_Conv_ASCIIHexDecode(FT_Byte **cursor, FT_Byte *limit, FT_Byte *buffer, FT_Offset n)
Definition: psconv.c:456
FT_Pos y
Definition: ftimage.h:78
GLuint GLfloat * val
#define IS_OCTAL_DIGIT(c)
Definition: psobjs.c:332
GLdouble n
GLuint buffer
const GLubyte * c
ps_table_done(PS_Table table)
Definition: psobjs.c:240
const GLint * first
GLintptr offset
FT_Pos xMax
Definition: ftimage.h:119
t1_builder_close_contour(T1_Builder builder)
Definition: psobjs.c:1700
FT_Byte size
Definition: psaux.h:231
short n_points
Definition: ftimage.h:386
T1_FieldType type
Definition: psaux.h:228
signed short FT_Short
Definition: fttypes.h:194
GLboolean GLenum GLenum GLvoid * values
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_Memory memory
Definition: psaux.h:434
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:290
t1_decrypt(FT_Byte *buffer, FT_Offset length, FT_UShort seed)
Definition: psobjs.c:1753
FT_Byte * base
Definition: psaux.h:431
if(!abbox) return FT_THROW(Invalid_Argument)
GLenum type
typedefFT_BEGIN_HEADER struct PS_TableRec_ * PS_Table
Definition: psaux.h:42
signed long FT_Fixed
Definition: fttypes.h:284
ps_parser_to_bytes(PS_Parser parser, FT_Byte *bytes, FT_Offset max_bytes, FT_Long *pnum_bytes, FT_Bool delimiters)
Definition: psobjs.c:1369
ps_parser_to_coord_array(PS_Parser parser, FT_Int max_coords, FT_Short *coords)
Definition: psobjs.c:1431
GLuint64EXT * result
unsigned int FT_UInt
Definition: fttypes.h:227
#define T1_MAX_TABLE_ELEMENTS
Definition: psobjs.c:1290
FT_GlyphLoader_Rewind(FT_GlyphLoader loader)
Definition: ftgloadr.c:88
FT_Error error
Definition: psaux.h:433
#define unexpected(table, a0)
Definition: tif_fax3.c:187
t1_builder_add_point(T1_Builder builder, FT_Pos x, FT_Pos y, FT_Byte flag)
Definition: psobjs.c:1599
ps_parser_init(PS_Parser parser, FT_Byte *base, FT_Byte *limit, FT_Memory memory)
Definition: psobjs.c:1472
t1_builder_add_contour(T1_Builder builder)
Definition: psobjs.c:1640
GLuint GLuint GLsizei count
FT_UInt offset
Definition: psaux.h:230
#define FT_CURVE_TAG_ON
Definition: ftimage.h:516
t1_builder_init(T1_Builder builder, FT_Face face, FT_Size size, FT_GlyphSlot glyph, FT_Bool hinting)
Definition: psobjs.c:1522
FT_TRACE0(("cff_property_set: missing property `%s'\, property_name))
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:203
png_infop png_uint_32 flag
Definition: png.h:2005
#define IS_PS_DELIM(ch)
Definition: psaux.h:849
T1_TokenType type
Definition: psaux.h:173
PS_Conv_ToInt(FT_Byte **cursor, FT_Byte *limit)
Definition: psconv.c:158
FT_Byte * limit
Definition: psaux.h:432
unsigned short FT_UShort
Definition: fttypes.h:205
GLenum GLsizei GLenum GLenum const GLvoid * table
#define FT_GLYPHLOADER_CHECK_POINTS(_loader, _points, _contours)
Definition: ftgloadr.h:134
FT_Pos yMin
Definition: ftimage.h:118
GLsizeiptr size
ps_parser_to_token_array(PS_Parser parser, T1_Token tokens, FT_UInt max_tokens, FT_Int *pnum_tokens)
Definition: psobjs.c:722
GLuint coords
FT_Vector * points
Definition: ftimage.h:388
#define IS_PS_XDIGIT(ch)
Definition: psaux.h:856
FT_Byte * limit
Definition: psaux.h:172
t1_builder_check_points(T1_Builder builder, FT_Int count)
Definition: psobjs.c:1590
GLint limit
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:236
size_t FT_Offset
Definition: fttypes.h:320
#define FT_CHAR_BIT
Definition: ftconfig.h:70
FT_CALLBACK_TABLE_DEF const PS_Table_FuncsRec ps_table_funcs
Definition: psauxmod.c:31