cidparse.c revision 4e7eeeec7b24ac1b9f6f84e2f4a5b2ea3bce5fe7
1/***************************************************************************/
2/*                                                                         */
3/*  cidparse.c                                                             */
4/*                                                                         */
5/*    CID-keyed Type1 parser (body).                                       */
6/*                                                                         */
7/*  Copyright 1996-2001 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_DEBUG_H
21#include FT_INTERNAL_CALC_H
22#include FT_INTERNAL_OBJECTS_H
23#include FT_INTERNAL_STREAM_H
24
25#include "cidparse.h"
26
27#include "ciderrs.h"
28
29#include <string.h>     /* for strncmp() */
30
31
32  /*************************************************************************/
33  /*                                                                       */
34  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
35  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
36  /* messages during execution.                                            */
37  /*                                                                       */
38#undef  FT_COMPONENT
39#define FT_COMPONENT  trace_cidparse
40
41
42  /*************************************************************************/
43  /*************************************************************************/
44  /*************************************************************************/
45  /*****                                                               *****/
46  /*****                    INPUT STREAM PARSER                        *****/
47  /*****                                                               *****/
48  /*************************************************************************/
49  /*************************************************************************/
50  /*************************************************************************/
51
52
53  FT_LOCAL_DEF FT_Error
54  CID_New_Parser( CID_Parser*       parser,
55                  FT_Stream         stream,
56                  FT_Memory         memory,
57                  PSAux_Service  psaux )
58  {
59    FT_Error  error;
60    FT_ULong  base_offset, offset, ps_len;
61    FT_Byte   buffer[256 + 10];
62    FT_Int    buff_len;
63
64
65    MEM_Set( parser, 0, sizeof ( *parser ) );
66    psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
67
68    parser->stream = stream;
69
70    base_offset = FILE_Pos();
71
72    /* first of all, check the font format in the  header */
73    if ( ACCESS_Frame( 31 ) )
74      goto Exit;
75
76    if ( strncmp( (char *)stream->cursor,
77                  "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
78    {
79      FT_TRACE2(( "[not a valid CID-keyed font]\n" ));
80      error = CID_Err_Unknown_File_Format;
81    }
82
83    FORGET_Frame();
84    if ( error )
85      goto Exit;
86
87    /* now, read the rest of the file, until we find a `StartData' */
88    buff_len = 256;
89    for (;;)
90    {
91      FT_Byte   *p, *limit = buffer + 256;
92      FT_ULong  top_position;
93
94
95      /* fill input buffer */
96      buff_len -= 256;
97      if ( buff_len > 0 )
98        MEM_Move( buffer, limit, buff_len );
99
100      p = buffer + buff_len;
101
102      if ( FILE_Read( p, 256 + 10 - buff_len ) )
103        goto Exit;
104
105      top_position = FILE_Pos() - buff_len;
106      buff_len = 256 + 10;
107
108      /* look for `StartData' */
109      for ( p = buffer; p < limit; p++ )
110      {
111        if ( p[0] == 'S' && strncmp( (char*)p, "StartData", 9 ) == 0 )
112        {
113          /* save offset of binary data after `StartData' */
114          offset = (FT_ULong)( top_position - ( limit - p ) + 10 );
115          goto Found;
116        }
117      }
118    }
119
120  Found:
121    /* we have found the start of the binary data.  We will now        */
122    /* rewind and extract the frame of corresponding to the Postscript */
123    /* section                                                         */
124
125    ps_len = offset - base_offset;
126    if ( FILE_Seek( base_offset )                    ||
127         EXTRACT_Frame( ps_len, parser->postscript ) )
128      goto Exit;
129
130    parser->data_offset    = offset;
131    parser->postscript_len = ps_len;
132    parser->root.base      = parser->postscript;
133    parser->root.cursor    = parser->postscript;
134    parser->root.limit     = parser->root.cursor + ps_len;
135    parser->num_dict       = -1;
136
137  Exit:
138    return error;
139  }
140
141
142  FT_LOCAL_DEF void
143  CID_Done_Parser( CID_Parser*  parser )
144  {
145    /* always free the private dictionary */
146    if ( parser->postscript )
147    {
148      FT_Stream  stream = parser->stream;
149
150
151      RELEASE_Frame( parser->postscript );
152    }
153    parser->root.funcs.done( &parser->root );
154  }
155
156
157/* END */
158