cidparse.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  cidparse.c                                                             */
00004 /*                                                                         */
00005 /*    CID-keyed Type1 parser (body).                                       */
00006 /*                                                                         */
00007 /*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by       */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include <ft2build.h>
00020 #include FT_INTERNAL_DEBUG_H
00021 #include FT_INTERNAL_OBJECTS_H
00022 #include FT_INTERNAL_STREAM_H
00023 
00024 #include "cidparse.h"
00025 
00026 #include "ciderrs.h"
00027 
00028 
00029   /*************************************************************************/
00030   /*                                                                       */
00031   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00032   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00033   /* messages during execution.                                            */
00034   /*                                                                       */
00035 #undef  FT_COMPONENT
00036 #define FT_COMPONENT  trace_cidparse
00037 
00038 
00039   /*************************************************************************/
00040   /*************************************************************************/
00041   /*************************************************************************/
00042   /*****                                                               *****/
00043   /*****                    INPUT STREAM PARSER                        *****/
00044   /*****                                                               *****/
00045   /*************************************************************************/
00046   /*************************************************************************/
00047   /*************************************************************************/
00048 
00049 
00050   FT_LOCAL_DEF( FT_Error )
00051   cid_parser_new( CID_Parser*    parser,
00052                   FT_Stream      stream,
00053                   FT_Memory      memory,
00054                   PSAux_Service  psaux )
00055   {
00056     FT_Error  error;
00057     FT_ULong  base_offset, offset, ps_len;
00058     FT_Byte   *cur, *limit;
00059     FT_Byte   *arg1, *arg2;
00060 
00061 
00062     FT_MEM_ZERO( parser, sizeof ( *parser ) );
00063     psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
00064 
00065     parser->stream = stream;
00066 
00067     base_offset = FT_STREAM_POS();
00068 
00069     /* first of all, check the font format in the header */
00070     if ( FT_FRAME_ENTER( 31 ) )
00071       goto Exit;
00072 
00073     if ( ft_strncmp( (char *)stream->cursor,
00074                      "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
00075     {
00076       FT_TRACE2(( "[not a valid CID-keyed font]\n" ));
00077       error = CID_Err_Unknown_File_Format;
00078     }
00079 
00080     FT_FRAME_EXIT();
00081     if ( error )
00082       goto Exit;
00083 
00084   Again:
00085     /* now, read the rest of the file until we find */
00086     /* `StartData' or `/sfnts'                      */
00087     {
00088       FT_Byte   buffer[256 + 10];
00089       FT_Long   read_len = 256 + 10; /* same as signed FT_Stream->size */
00090       FT_Byte*  p        = buffer;
00091 
00092 
00093       for ( offset = FT_STREAM_POS(); ; offset += 256 )
00094       {
00095         FT_Long  stream_len; /* same as signed FT_Stream->size */
00096 
00097 
00098         stream_len = stream->size - FT_STREAM_POS();
00099         if ( stream_len == 0 )
00100         {
00101           FT_TRACE2(( "cid_parser_new: no `StartData' keyword found\n" ));
00102           error = CID_Err_Unknown_File_Format;
00103           goto Exit;
00104         }
00105 
00106         read_len = FT_MIN( read_len, stream_len );
00107         if ( FT_STREAM_READ( p, read_len ) )
00108           goto Exit;
00109 
00110         if ( read_len < 256 )
00111           p[read_len]  = '\0';
00112 
00113         limit = p + read_len - 10;
00114 
00115         for ( p = buffer; p < limit; p++ )
00116         {
00117           if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 )
00118           {
00119             /* save offset of binary data after `StartData' */
00120             offset += p - buffer + 10;
00121             goto Found;
00122           }
00123           else if ( p[1] == 's' && ft_strncmp( (char*)p, "/sfnts", 6 ) == 0 )
00124           {
00125             offset += p - buffer + 7;
00126             goto Found;
00127           }
00128         }
00129 
00130         FT_MEM_MOVE( buffer, p, 10 );
00131         read_len = 256;
00132         p = buffer + 10;
00133       }
00134     }
00135 
00136   Found:
00137     /* We have found the start of the binary data or the `/sfnts' token. */
00138     /* Now rewind and extract the frame corresponding to this PostScript */
00139     /* section.                                                          */
00140 
00141     ps_len = offset - base_offset;
00142     if ( FT_STREAM_SEEK( base_offset )                  ||
00143          FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
00144       goto Exit;
00145 
00146     parser->data_offset    = offset;
00147     parser->postscript_len = ps_len;
00148     parser->root.base      = parser->postscript;
00149     parser->root.cursor    = parser->postscript;
00150     parser->root.limit     = parser->root.cursor + ps_len;
00151     parser->num_dict       = -1;
00152 
00153     /* Finally, we check whether `StartData' or `/sfnts' was real --  */
00154     /* it could be in a comment or string.  We also get the arguments */
00155     /* of `StartData' to find out whether the data is represented in  */
00156     /* binary or hex format.                                          */
00157 
00158     arg1 = parser->root.cursor;
00159     cid_parser_skip_PS_token( parser );
00160     cid_parser_skip_spaces  ( parser );
00161     arg2 = parser->root.cursor;
00162     cid_parser_skip_PS_token( parser );
00163     cid_parser_skip_spaces  ( parser );
00164 
00165     limit = parser->root.limit;
00166     cur   = parser->root.cursor;
00167 
00168     while ( cur < limit )
00169     {
00170       if ( parser->root.error )
00171       {
00172         error = parser->root.error;
00173         goto Exit;
00174       }
00175 
00176       if ( cur[0] == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
00177       {
00178         if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
00179           parser->binary_length = ft_atol( (const char *)arg2 );
00180 
00181         limit = parser->root.limit;
00182         cur   = parser->root.cursor;
00183         goto Exit;
00184       }
00185       else if ( cur[1] == 's' && ft_strncmp( (char*)cur, "/sfnts", 6 ) == 0 )
00186       {
00187         FT_TRACE2(( "cid_parser_new: cannot handle Type 11 fonts\n" ));
00188         error = CID_Err_Unknown_File_Format;
00189         goto Exit;
00190       }
00191 
00192       cid_parser_skip_PS_token( parser );
00193       cid_parser_skip_spaces  ( parser );
00194       arg1 = arg2;
00195       arg2 = cur;
00196       cur  = parser->root.cursor;
00197     }
00198 
00199     /* we haven't found the correct `StartData'; go back and continue */
00200     /* searching                                                      */
00201     FT_FRAME_RELEASE( parser->postscript );
00202     if ( !FT_STREAM_SEEK( offset ) )
00203       goto Again;
00204 
00205   Exit:
00206     return error;
00207   }
00208 
00209 
00210   FT_LOCAL_DEF( void )
00211   cid_parser_done( CID_Parser*  parser )
00212   {
00213     /* always free the private dictionary */
00214     if ( parser->postscript )
00215     {
00216       FT_Stream  stream = parser->stream;
00217 
00218 
00219       FT_FRAME_RELEASE( parser->postscript );
00220     }
00221     parser->root.funcs.done( &parser->root );
00222   }
00223 
00224 
00225 /* END */

Generated on Tue Jul 5 14:13:46 2011 for ROOT_528-00b_version by  doxygen 1.5.1