]>
git.saurik.com Git - wxWidgets.git/blob - src/freetype/type1/t1parse.c
1 /***************************************************************************/
5 /* Type 1 parser (body). */
7 /* Copyright 1996-2000 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
19 #include <freetype/internal/ftdebug.h>
20 #include <freetype/internal/t1types.h>
23 #ifdef FT_FLAT_COMPILE
29 #include <type1/t1parse.h>
34 #include <stdio.h> /* for sscanf() */
35 #include <string.h> /* for strncpy() */
38 /*************************************************************************/
44 /* Initializes a T1_Table structure. */
47 /* table :: The address of the target table. */
50 /* count :: The table size (i.e. maximum number of elements). */
51 /* memory :: The memory object to use for all subsequent */
55 /* FreeType error code. 0 means success. */
58 FT_Error
T1_New_Table( T1_Table
* table
,
65 table
->memory
= memory
;
67 if ( ALLOC_ARRAY( table
->elements
, count
, FT_Byte
* ) )
70 if ( ALLOC_ARRAY( table
->lengths
, count
, FT_Byte
* ) )
72 FREE( table
->elements
);
76 table
->max_elems
= count
;
88 FT_Error
reallocate_t1_table( T1_Table
* table
,
91 FT_Memory memory
= table
->memory
;
92 FT_Byte
* old_base
= table
->block
;
96 /* reallocate the base block */
97 if ( REALLOC( table
->block
, table
->capacity
, new_size
) )
99 table
->capacity
= new_size
;
101 /* shift all offsets if necessary */
104 FT_Long delta
= table
->block
- old_base
;
105 FT_Byte
** offset
= table
->elements
;
106 FT_Byte
** limit
= offset
+ table
->max_elems
;
110 for ( ; offset
< limit
; offset
++ )
119 /*************************************************************************/
125 /* Adds an object to a T1_Table, possibly growing its memory block. */
128 /* table :: The target table. */
131 /* index :: The index of the object in the table. */
133 /* object :: The address of the object to copy in memory. */
135 /* length :: The length in bytes of the source object. */
138 /* FreeType error code. 0 means success. An error is returned if a */
139 /* reallocation failed. */
142 FT_Error
T1_Add_Table( T1_Table
* table
,
147 if ( index
< 0 || index
> table
->max_elems
)
149 FT_ERROR(( "T1_Add_Table: invalid index\n" ));
150 return T1_Err_Syntax_Error
;
153 /* grow the base block if needed */
154 if ( table
->cursor
+ length
> table
->capacity
)
157 FT_Int new_size
= table
->capacity
;
160 while ( new_size
< table
->cursor
+ length
)
163 error
= reallocate_t1_table( table
, new_size
);
168 /* add the object to the base block and adjust offset */
169 table
->elements
[index
] = table
->block
+ table
->cursor
;
170 table
->lengths
[index
] = length
;
171 MEM_Copy( table
->block
+ table
->cursor
, object
, length
);
173 table
->cursor
+= length
;
179 /*************************************************************************/
185 /* Finalize a T1_Table (reallocate it to its current cursor). */
188 /* table :: The target table. */
191 /* This function does NOT release the heap's memory block. It is up */
192 /* to the caller to clean it, or reference it in its own structures. */
195 void T1_Done_Table( T1_Table
* table
)
197 FT_Memory memory
= table
->memory
;
202 /* should never fail, as rec.cursor <= rec.size */
203 old_base
= table
->block
;
207 (void)REALLOC( table
->block
, table
->capacity
, table
->cursor
);
208 table
->capacity
= table
->cursor
;
210 if ( old_base
!= table
->block
)
212 FT_Long delta
= table
->block
- old_base
;
213 FT_Byte
** element
= table
->elements
;
214 FT_Byte
** limit
= element
+ table
->max_elems
;
217 for ( ; element
< limit
; element
++ )
225 FT_String
* CopyString( T1_Parser
* parser
)
227 FT_String
* string
= NULL
;
228 T1_Token
* token
= parser
->args
++;
229 FT_Memory memory
= parser
->tokenizer
->memory
;
233 if ( token
->kind
== tok_string
)
235 FT_Int len
= token
->len
- 2;
238 if ( ALLOC( string
, len
+ 1 ) )
240 parser
->error
= error
;
244 MEM_Copy( string
, parser
->tokenizer
->base
+ token
->start
+ 1, len
);
247 parser
->error
= T1_Err_Ok
;
251 FT_ERROR(( "T1_CopyString: syntax error, string token expected!\n" ));
252 parser
->error
= T1_Err_Syntax_Error
;
260 FT_Error
parse_int( FT_Byte
* base
,
275 else if ( *base
== '-' )
287 sum
= ( 10 * sum
+ ( *base
++ - '0' ) );
289 } while ( base
< limit
);
298 FT_ERROR(( "parse_int: integer expected\n" ));
300 return T1_Err_Syntax_Error
;
305 FT_Error
parse_float( FT_Byte
* base
,
312 /* XXX: We are simply much too lazy to code this function */
313 /* properly for now. We will do that when the rest of */
314 /* the driver works properly. */
316 int len
= limit
- base
;
323 strncpy( temp
, (char*)base
, len
);
325 if ( sscanf( temp
, "%lf", &value
) != 1 )
328 *result
= (FT_Long
)( scale
* value
);
334 FT_Bool sign
= 0; /* sign */
335 FT_Long number_int
= 0; /* integer part */
336 FT_Long number_frac
= 0; /* fractional part */
337 FT_Long exponent
= 0; /* exponent value */
338 FT_Int num_frac
= 0; /* number of fractional digits */
345 else if ( *base
== '-' )
351 /* find integer part */
353 while ( cur
< limit
)
358 if ( c
== '.' || c
== 'e' || c
== 'E' )
366 error
= parse_integer( base
, cur
, &number_int
);
371 /* read fractional part, if any */
376 while ( cur
< limit
)
381 if ( c
== 'e' || c
== 'E' )
386 num_frac
= cur
- base
;
390 error
= parse_integer( base
, cur
, &number_frac
);
397 /* read exponent, if any */
398 if ( *cur
== 'e' || *cur
== 'E' )
402 error
= parse_integer( base
, limit
, &exponent
);
406 /* now check that exponent is within `correct bounds' */
407 /* i.e. between -6 and 6 */
408 if ( exponent
< -6 || exponent
> 6 )
412 /* now adjust integer value and exponent for fractional part */
413 while ( num_frac
> 0 )
420 number_int
+= num_frac
;
422 /* skip point if any, read fractional part */
423 if ( cur
+ 1 < limit
)
428 /* now compute scaled float value */
429 /* XXX: incomplete! */
434 FT_ERROR(( "parse_float: syntax error!\n" ));
435 return T1_Err_Syntax_Error
;
440 FT_Error
parse_integer( FT_Byte
* base
,
447 /* the lexical analyser accepts floats as well as integers */
448 /* now; check that we really have an int in this token */
450 while ( cur
< limit
)
455 if ( c
== '.' || c
== 'e' || c
== 'E' )
459 /* now read the number's value */
460 return parse_int( base
, limit
, result
);
463 /* we really have a float there; simply call parse_float in this */
464 /* case with a scale of `10' to perform round */
469 error
= parse_float( base
, limit
, 10, result
);
473 *result
= ( *result
+ 5 ) / 10; /* round value */
475 *result
= -( ( 5 - *result
) / 10 );
483 FT_Long
CopyInteger( T1_Parser
* parser
)
486 T1_Token
* token
= parser
->args
++;
489 if ( token
->kind
== tok_number
)
491 FT_Byte
* base
= parser
->tokenizer
->base
+ token
->start
;
492 FT_Byte
* limit
= base
+ token
->len
;
495 /* now read the number's value */
496 parser
->error
= parse_integer( base
, limit
, &sum
);
500 FT_ERROR(( "CopyInteger: number expected\n" ));
502 parser
->error
= T1_Err_Syntax_Error
;
508 FT_Bool
CopyBoolean( T1_Parser
* parser
)
510 FT_Error error
= T1_Err_Ok
;
512 T1_Token
* token
= parser
->args
++;
515 if ( token
->kind
== tok_keyword
)
517 if ( token
->kind2
== key_false
)
520 else if ( token
->kind2
== key_true
)
529 FT_ERROR(( "CopyBoolean:" ));
530 FT_ERROR(( " syntax error; `false' or `true' expected\n" ));
531 error
= T1_Err_Syntax_Error
;
533 parser
->error
= error
;
539 FT_Long
CopyFloat( T1_Parser
* parser
,
544 T1_Token
* token
= parser
->args
++;
547 if ( token
->kind
== tok_number
)
549 FT_Byte
* base
= parser
->tokenizer
->base
+ token
->start
;
550 FT_Byte
* limit
= base
+ token
->len
;
553 error
= parser
->error
= parse_float( base
, limit
, scale
, &sum
);
561 FT_ERROR(( "CopyFloat: syntax error!\n" ));
562 parser
->error
= T1_Err_Syntax_Error
;
568 void CopyBBox( T1_Parser
* parser
,
571 T1_Token
* token
= parser
->args
++;
576 if ( token
->kind
== tok_program
||
577 token
->kind
== tok_array
)
579 /* get rid of `['/`]', or `{'/`}' */
580 FT_Byte
* base
= parser
->tokenizer
->base
+ token
->start
+ 1;
581 FT_Byte
* limit
= base
+ token
->len
- 2;
586 /* read each parameter independently */
588 for ( n
= 0; n
< 4; n
++ )
593 /* skip whitespace */
594 while ( cur
< limit
&& *cur
== ' ' )
599 while ( cur
< limit
&& *cur
!= ' ' )
602 /* compute result address */
606 result
= &bbox
->xMin
;
609 result
= &bbox
->yMin
;
612 result
= &bbox
->xMax
;
615 result
= &bbox
->yMax
;
618 error
= parse_integer( start
, cur
, result
);
627 FT_ERROR(( "CopyBBox: syntax error!\n" ));
628 parser
->error
= T1_Err_Syntax_Error
;
633 void CopyMatrix( T1_Parser
* parser
,
636 T1_Token
* token
= parser
->args
++;
640 if ( token
->kind
== tok_array
)
642 /* get rid of `[' and `]' */
643 FT_Byte
* base
= parser
->tokenizer
->base
+ token
->start
+ 1;
644 FT_Byte
* limit
= base
+ token
->len
- 2;
650 /* read each parameter independently */
652 for ( n
= 0; n
< 4; n
++ )
657 /* skip whitespace */
658 while ( cur
< limit
&& *cur
== ' ' )
663 while ( cur
< limit
&& *cur
!= ' ')
666 /* compute result address */
670 result
= &matrix
->xx
;
673 result
= &matrix
->yx
;
676 result
= &matrix
->xy
;
679 result
= &matrix
->yy
;
682 error
= parse_float( start
, cur
, 65536000L, result
);
691 FT_ERROR(( "CopyMatrix: syntax error!\n" ));
692 parser
->error
= T1_Err_Syntax_Error
;
697 void CopyArray( T1_Parser
* parser
,
698 FT_Byte
* num_elements
,
700 FT_Int max_elements
)
702 T1_Token
* token
= parser
->args
++;
706 if ( token
->kind
== tok_array
||
707 token
->kind
== tok_program
) /* in the case of MinFeature */
709 /* get rid of `['/`]', or `{'/`}' */
710 FT_Byte
* base
= parser
->tokenizer
->base
+ token
->start
+ 1;
711 FT_Byte
* limit
= base
+ token
->len
- 2;
717 /* read each parameter independently */
719 for ( n
= 0; n
< max_elements
; n
++ )
724 /* test end of string */
728 /* skip whitespace */
729 while ( cur
< limit
&& *cur
== ' ' )
738 while ( cur
< limit
&& *cur
!= ' ' )
741 error
= parse_integer( start
, cur
, &result
);
745 *elements
++ = (FT_Short
)result
;
749 *num_elements
= (FT_Byte
)n
;
756 FT_ERROR(( "CopyArray: syntax error!\n" ));
757 parser
->error
= T1_Err_Syntax_Error
;