1 /***************************************************************************/ 
   5 /*    CID-keyed Type1 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/ftcalc.h> 
  21 #include <freetype/internal/ftobjs.h> 
  22 #include <freetype/internal/ftstream.h> 
  23 #include <freetype/internal/t1errors.h> 
  26 #ifdef FT_FLAT_COMPILE 
  32 #include <cid/cidparse.h> 
  37 #include <string.h>     /* for strncmp() */ 
  40   /*************************************************************************/ 
  42   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */ 
  43   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */ 
  44   /* messages during execution.                                            */ 
  47 #define FT_COMPONENT  trace_cidparse 
  52   /*************************************************************************/ 
  53   /*************************************************************************/ 
  54   /*************************************************************************/ 
  56   /*****           IMPLEMENTATION OF CID_TABLE OBJECT                  *****/ 
  58   /*************************************************************************/ 
  59   /*************************************************************************/ 
  60   /*************************************************************************/ 
  63   /*************************************************************************/ 
  69   /*    Initializes a CID_Table.                                           */ 
  72   /*    table  :: The address of the target table.                         */ 
  75   /*    count  :: The table size, i.e., the maximal number of elements.    */ 
  77   /*    memory :: The memory object to be used for all subsequent          */ 
  81   /*    FreeType error code.  0 means success.                             */ 
  84   FT_Error  
CID_New_Table( CID_Table
*  table
, 
  91     table
->memory 
= memory
; 
  92     if ( ALLOC_ARRAY( table
->elements
, count
, FT_Byte
*  ) || 
  93          ALLOC_ARRAY( table
->lengths
, count
, FT_Byte
* )   ) 
  96     table
->max_elems 
= count
; 
  97     table
->init      
= 0xDEADBEEFL
; 
 105       FREE( table
->elements 
); 
 112   void  shift_elements( CID_Table
*  table
, 
 115     FT_Long    delta  
= table
->block 
- old_base
; 
 116     FT_Byte
**  offset 
= table
->elements
; 
 117     FT_Byte
**  limit  
= offset 
+ table
->max_elems
; 
 121       for ( ; offset 
< limit
; offset
++ ) 
 130   FT_Error  
reallocate_t1_table( CID_Table
*  table
, 
 133     FT_Memory  memory   
= table
->memory
; 
 134     FT_Byte
*   old_base 
= table
->block
; 
 138     /* realloc the base block */ 
 139     if ( REALLOC( table
->block
, table
->capacity
, new_size 
) ) 
 142     table
->capacity 
= new_size
; 
 144     /* shift all offsets when needed */ 
 146       shift_elements( table
, old_base 
); 
 152   /*************************************************************************/ 
 158   /*    Adds an object to a CID_Table, possibly growing its memory block.  */ 
 161   /*    table  :: The target table.                                        */ 
 164   /*    index  :: The index of the object in the table.                    */ 
 166   /*    object :: The address of the object to copy in the memory.         */ 
 168   /*    length :: The length in bytes of the source object.                */ 
 171   /*    FreeType error code.  0 means success.  An error is returned if    */ 
 172   /*    reallocation fails.                                                */ 
 175   FT_Error  
CID_Add_Table( CID_Table
*  table
, 
 180     if ( index 
< 0 || index 
> table
->max_elems 
) 
 182       FT_ERROR(( "CID_Add_Table: invalid index\n" )); 
 183       return T1_Err_Syntax_Error
; 
 186     /* grow the base block if needed */ 
 187     if ( table
->cursor 
+ length 
> table
->capacity 
) 
 190       FT_Int    new_size 
= table
->capacity
; 
 193       while ( new_size 
< table
->cursor 
+ length 
) 
 196       error 
= reallocate_t1_table( table
, new_size 
); 
 201     /* add the object to the base block and adjust offset */ 
 202     table
->elements
[index
] = table
->block 
+ table
->cursor
; 
 203     table
->lengths 
[index
] = length
; 
 205     MEM_Copy( table
->block 
+ table
->cursor
, object
, length 
); 
 207     table
->cursor 
+= length
; 
 213   /*************************************************************************/ 
 219   /*    Finalizes a CID_Table (reallocate it to its current cursor).       */ 
 222   /*    table :: The target table.                                         */ 
 225   /*    This function does NOT release the heap's memory block.  It is up  */ 
 226   /*    to the caller to clean it, or reference it in its own structures.  */ 
 229   void  CID_Done_Table( CID_Table
*  table 
) 
 231     FT_Memory  memory 
= table
->memory
; 
 236     /* should never fail, as rec.cursor <= rec.size */ 
 237     old_base 
= table
->block
; 
 241     (void)REALLOC( table
->block
, table
->capacity
, table
->cursor 
); 
 242     table
->capacity 
= table
->cursor
; 
 244     if ( old_base 
!= table
->block 
) 
 245       shift_elements( table
, old_base 
); 
 250   void  CID_Release_Table( CID_Table
*  table 
) 
 252     FT_Memory  memory 
= table
->memory
; 
 255     if ( table
->init 
== 0xDEADBEEFL 
) 
 257       FREE( table
->block 
); 
 258       FREE( table
->elements 
); 
 259       FREE( table
->lengths 
); 
 267   /*************************************************************************/ 
 268   /*************************************************************************/ 
 269   /*************************************************************************/ 
 271   /*****                    INPUT STREAM PARSER                        *****/ 
 273   /*************************************************************************/ 
 274   /*************************************************************************/ 
 275   /*************************************************************************/ 
 278 #define IS_CID_WHITESPACE( c )  ( (c) == ' '  || (c) == '\t' ) 
 279 #define IS_CID_LINESPACE( c )   ( (c) == '\r' || (c) == '\n' ) 
 281 #define IS_CID_SPACE( c )  ( IS_CID_WHITESPACE( c ) || IS_CID_LINESPACE( c ) ) 
 285   void  CID_Skip_Spaces( CID_Parser
*  parser 
) 
 287     FT_Byte
* cur   
= parser
->cursor
; 
 288     FT_Byte
* limit 
= parser
->limit
; 
 291     while ( cur 
< limit 
) 
 296       if ( !IS_CID_SPACE( c 
) ) 
 301     parser
->cursor 
= cur
; 
 306   void  CID_ToToken( CID_Parser
*     parser
, 
 307                      CID_Token_Rec
*  token 
) 
 311     FT_Byte   starter
, ender
; 
 315     token
->type  
= t1_token_none
; 
 319     /* first of all, skip space */ 
 320     CID_Skip_Spaces( parser 
); 
 322     cur   
= parser
->cursor
; 
 323     limit 
= parser
->limit
; 
 329         /************* check for strings ***********************/ 
 331         token
->type 
= t1_token_string
; 
 335         /************* check for programs/array ****************/ 
 337         token
->type 
= t1_token_array
; 
 341         /************* check for table/array ******************/ 
 343         token
->type 
= t1_token_array
; 
 351         while ( cur 
< limit 
) 
 353           if ( *cur 
== starter 
) 
 355           else if ( *cur 
== ender 
) 
 360               token
->limit 
= cur
++; 
 368         /* **************** otherwise, it is any token **********/ 
 370         token
->start 
= cur
++; 
 371         token
->type  
= t1_token_any
; 
 372         while ( cur 
< limit 
&& !IS_CID_SPACE( *cur 
) ) 
 381         token
->type  
= t1_token_none
; 
 384       parser
->cursor 
= cur
; 
 390   void  CID_ToTokenArray( CID_Parser
*     parser
, 
 391                           CID_Token_Rec
*  tokens
, 
 393                           FT_Int
*         pnum_tokens 
) 
 395     CID_Token_Rec  master
; 
 400     CID_ToToken( parser
, &master 
); 
 402     if ( master
.type 
== t1_token_array 
) 
 404       FT_Byte
*        old_cursor 
= parser
->cursor
; 
 405       FT_Byte
*        old_limit  
= parser
->limit
; 
 406       CID_Token_Rec
*  cur        
= tokens
; 
 407       CID_Token_Rec
*  limit      
= cur 
+ max_tokens
; 
 410       parser
->cursor 
= master
.start
; 
 411       parser
->limit  
= master
.limit
; 
 413       while ( parser
->cursor 
< parser
->limit 
) 
 418         CID_ToToken( parser
, &token 
); 
 428       *pnum_tokens 
= cur 
- tokens
; 
 430       parser
->cursor 
= old_cursor
; 
 431       parser
->limit  
= old_limit
; 
 437   FT_Long  
t1_toint( FT_Byte
**  cursor
, 
 441     FT_Byte
*  cur    
= *cursor
; 
 445     for ( ; cur 
< limit
; cur
++ ) 
 448       d 
= (FT_Byte
)( c 
- '0' ); 
 463         d 
= (FT_Byte
)( cur
[0] - '0' ); 
 467         result 
= result 
* 10 + d
; 
 470       } while ( cur 
< limit 
); 
 483   FT_Long  
t1_tofixed( FT_Byte
**  cursor
, 
 487     FT_Byte
*  cur 
= *cursor
; 
 488     FT_Long   num
, divider
, result
; 
 496     /* first of all, read the integer part */ 
 497     result  
= t1_toint( &cur
, limit 
) << 16; 
 510     /* read decimal part, if any */ 
 511     if ( *cur 
== '.' && cur 
+ 1 < limit 
) 
 517         d 
= (FT_Byte
)( *cur 
- '0' ); 
 521         if ( divider 
< 10000000L ) 
 533     /* read exponent, if any */ 
 534     if ( cur 
+ 1 < limit 
&& ( *cur 
== 'e' || *cur 
== 'E' ) ) 
 537       power_ten 
+= t1_toint( &cur
, limit 
); 
 541     /* raise to power of ten if needed */ 
 542     while ( power_ten 
> 0 ) 
 544       result 
= result 
* 10; 
 549     while ( power_ten 
< 0 ) 
 551       result  
= result 
/ 10; 
 552       divider 
= divider 
* 10; 
 557       result 
+= FT_DivFix( num
, divider 
); 
 569   int  t1_tobool( FT_Byte
**  cursor
, 
 572     FT_Byte
*  cur    
= *cursor
; 
 576     /* return 1 if we find a "true", 0 otherwise */ 
 577     if ( cur 
+ 3 < limit 
&& 
 586     else if ( cur 
+ 4 < limit 
&& 
 602   FT_Int  
t1_tocoordarray( FT_Byte
**  cursor
, 
 607     FT_Byte
*  cur   
= *cursor
; 
 615     /* check for the beginning of an array. */ 
 616     /* If not, only one number will be read */ 
 629     /* now, read the coordinates */ 
 630     for ( ; cur 
< limit
; ) 
 632       /* skip whitespace in front of data */ 
 636         if ( c 
!= ' ' && c 
!= '\t' ) 
 644       if ( count 
>= max_coords 
|| c 
== ender 
) 
 647       coords
[count
] = (FT_Short
)( t1_tofixed( &cur
, limit
, 0 ) >> 16 ); 
 661   FT_Int  
t1_tofixedarray( FT_Byte
**  cursor
, 
 667     FT_Byte
*  cur   
= *cursor
; 
 675     /* check for the beginning of an array. */ 
 676     /* If not, only one number will be read */ 
 689     /* now, read the values */ 
 690     for ( ; cur 
< limit
; ) 
 692       /* skip whitespace in front of data */ 
 696         if ( c 
!= ' ' && c 
!= '\t' ) 
 704       if ( count 
>= max_values 
|| c 
== ender 
) 
 707       values
[count
] = t1_tofixed( &cur
, limit
, power_ten 
); 
 721   /* Loads a simple field (i.e. non-table) into the current */ 
 722   /* list of objects                                        */ 
 724   FT_Error  
CID_Load_Field( CID_Parser
*           parser
, 
 725                             const CID_Field_Rec
*  field
, 
 736     CID_ToToken( parser
, &token 
); 
 746       FT_Byte
*   q 
= (FT_Byte
*)object 
+ field
->offset
; 
 751       switch ( field
->type 
) 
 754         val 
= t1_tobool( &cur
, limit 
); 
 758         val 
= t1_tofixed( &cur
, limit
, 0 ); 
 761       case t1_field_integer
: 
 762         val 
= t1_toint( &cur
, limit 
); 
 765         switch ( field
->size 
) 
 768             *(FT_Byte
*)q 
= (FT_Byte
)val
; 
 772             *(FT_UShort
*)q 
= (FT_UShort
)val
; 
 776             *(FT_Int32
*)q 
= (FT_Int
)val
; 
 779           default:  /* for 64-bit systems */ 
 784       case t1_field_string
: 
 786           FT_Memory  memory 
= parser
->memory
; 
 787           FT_UInt    len    
= limit
-cur
; 
 790           if ( ALLOC( string
, len 
+ 1 ) ) 
 793           MEM_Copy( string
, cur
, len 
); 
 796           *(FT_String
**)q 
= string
; 
 801         /* an error occurred */ 
 812     error 
= T1_Err_Invalid_File_Format
; 
 817 #define T1_MAX_TABLE_ELEMENTS  32 
 821   FT_Error  
CID_Load_Field_Table( CID_Parser
*           parser
, 
 822                                   const CID_Field_Rec
*  field
, 
 825     CID_Token_Rec   elements
[T1_MAX_TABLE_ELEMENTS
]; 
 826     CID_Token_Rec
*  token
; 
 831     CID_Field_Rec   fieldrec 
= *(CID_Field_Rec
*)field
; 
 834     fieldrec
.type 
= t1_field_integer
; 
 835     if ( field
->type 
== t1_field_fixed_array 
) 
 836       fieldrec
.type 
= t1_field_fixed
; 
 838     CID_ToTokenArray( parser
, elements
, 32, &num_elements 
); 
 839     if ( num_elements 
< 0 ) 
 842     if ( num_elements 
> T1_MAX_TABLE_ELEMENTS 
) 
 843       num_elements 
= T1_MAX_TABLE_ELEMENTS
; 
 845     old_cursor 
= parser
->cursor
; 
 846     old_limit  
= parser
->limit
; 
 848     /* we store the elements count */ 
 849     if ( field
->count_offset 
) 
 850       *(FT_Byte
*)( (FT_Byte
*)object 
+ field
->count_offset 
) = num_elements
; 
 852     /* we now load each element, adjusting the field.offset on each one */ 
 854     for ( ; num_elements 
> 0; num_elements
--, token
++ ) 
 856       parser
->cursor 
= token
->start
; 
 857       parser
->limit  
= token
->limit
; 
 858       CID_Load_Field( parser
, &fieldrec
, object 
); 
 859       fieldrec
.offset 
+= fieldrec
.size
; 
 862     parser
->cursor 
= old_cursor
; 
 863     parser
->limit  
= old_limit
; 
 869     error 
= T1_Err_Invalid_File_Format
; 
 875   FT_Long  
CID_ToInt( CID_Parser
*  parser 
) 
 877     return t1_toint( &parser
->cursor
, parser
->limit 
); 
 882   FT_Int  
CID_ToCoordArray( CID_Parser
*  parser
, 
 886     return t1_tocoordarray( &parser
->cursor
, parser
->limit
, 
 887                             max_coords
, coords 
); 
 892   FT_Int  
CID_ToFixedArray( CID_Parser
*  parser
, 
 897     return t1_tofixedarray( &parser
->cursor
, parser
->limit
, 
 898                             max_values
, values
, power_ten 
); 
 904   /* return the value of an hexadecimal digit */ 
 906   int  hexa_value( char  c 
) 
 911     d 
= (unsigned int)( c 
- '0' ); 
 915     d 
= (unsigned int)( c 
- 'a' ); 
 917       return (int)( d 
+ 10 ); 
 919     d 
= (unsigned int)( c 
- 'A' ); 
 921       return (int)( d 
+ 10 ); 
 930   FT_Error  
CID_New_Parser( CID_Parser
*  parser
, 
 935     FT_ULong  base_offset
, offset
, ps_len
; 
 936     FT_Byte   buffer
[256 + 10]; 
 940     MEM_Set( parser
, 0, sizeof ( *parser 
) ); 
 941     parser
->stream 
= stream
; 
 942     parser
->memory 
= memory
; 
 944     base_offset 
= FILE_Pos(); 
 946     /* first of all, check the font format in the  header */ 
 947     if ( ACCESS_Frame( 31 ) ) 
 950     if ( strncmp( (char *)stream
->cursor
, 
 951                   "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) ) 
 953       FT_TRACE2(( "[not a valid CID-keyed font]\n" )); 
 954       error 
= FT_Err_Unknown_File_Format
; 
 961     /* now, read the rest of the file, until we find a `StartData' */ 
 965       FT_Byte  
*p
, *limit 
= buffer 
+ 256; 
 967       /* fill input buffer */ 
 970         MEM_Move( buffer
, limit
, buff_len 
); 
 972       if ( FILE_Read( buffer
, 256 + 10 - buff_len 
) ) 
 977       /* look for `StartData' */ 
 978       for ( p 
= buffer
; p 
< limit
; p
++ ) 
 980         if ( p
[0] == 'S' && strncmp( (char*)p
, "StartData", 9 ) == 0 ) 
 982           /* save offset of binary data after `StartData' */ 
 983           offset 
= FILE_Pos() - ( limit 
- p 
) + 10; 
 990     /* we have found the start of the binary data.  We will now        */ 
 991     /* rewind and extract the frame of corresponding to the Postscript */ 
 994     ps_len 
= offset 
- base_offset
; 
 995     if ( FILE_Seek( base_offset 
)                    || 
 996          EXTRACT_Frame( ps_len
, parser
->postscript 
) ) 
 999     parser
->data_offset    
= offset
; 
1000     parser
->postscript_len 
= ps_len
; 
1001     parser
->cursor         
= parser
->postscript
; 
1002     parser
->limit          
= parser
->cursor 
+ ps_len
; 
1003     parser
->num_dict       
= -1; 
1011   void  CID_Done_Parser( CID_Parser
*  parser 
) 
1013     /* always free the private dictionary */ 
1014     if ( parser
->postscript 
) 
1016       FT_Stream  stream 
= parser
->stream
; 
1019       RELEASE_Frame( parser
->postscript 
);