source: trunk/poppler/freetype-2.2.1/src/cid/cidparse.c @ 150

Last change on this file since 150 was 150, checked in by Eugene Romanenko, 15 years ago

update freetype to 2.2.1

File size: 6.8 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  cidparse.c                                                             */
4/*                                                                         */
5/*    CID-keyed Type1 parser (body).                                       */
6/*                                                                         */
7/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006 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
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_cidparse
38
39
40  /*************************************************************************/
41  /*************************************************************************/
42  /*************************************************************************/
43  /*****                                                               *****/
44  /*****                    INPUT STREAM PARSER                        *****/
45  /*****                                                               *****/
46  /*************************************************************************/
47  /*************************************************************************/
48  /*************************************************************************/
49
50
51  FT_LOCAL_DEF( FT_Error )
52  cid_parser_new( CID_Parser*    parser,
53                  FT_Stream      stream,
54                  FT_Memory      memory,
55                  PSAux_Service  psaux )
56  {
57    FT_Error  error;
58    FT_ULong  base_offset, offset, ps_len;
59    FT_Byte   *cur, *limit;
60    FT_Byte   *arg1, *arg2;
61
62
63    FT_MEM_ZERO( parser, sizeof ( *parser ) );
64    psaux->ps_parser_funcs->init( &parser->root, 0, 0, memory );
65
66    parser->stream = stream;
67
68    base_offset = FT_STREAM_POS();
69
70    /* first of all, check the font format in the header */
71    if ( FT_FRAME_ENTER( 31 ) )
72      goto Exit;
73
74    if ( ft_strncmp( (char *)stream->cursor,
75                     "%!PS-Adobe-3.0 Resource-CIDFont", 31 ) )
76    {
77      FT_TRACE2(( "[not a valid CID-keyed font]\n" ));
78      error = CID_Err_Unknown_File_Format;
79    }
80
81    FT_FRAME_EXIT();
82    if ( error )
83      goto Exit;
84
85  Again:
86    /* now, read the rest of the file until we find a `StartData' */
87    {
88      FT_Byte   buffer[256 + 10];
89      FT_Int    read_len = 256 + 10;
90      FT_Byte*  p        = buffer;
91
92
93      for ( offset = (FT_ULong)FT_STREAM_POS(); ; offset += 256 )
94      {
95        FT_Int    stream_len;
96
97
98        stream_len = stream->size - FT_STREAM_POS();
99        if ( stream_len == 0 )
100          goto Exit;
101
102        read_len = FT_MIN( read_len, stream_len );
103        if ( FT_STREAM_READ( p, read_len ) )
104          goto Exit;
105
106        if ( read_len < 256 )
107          p[read_len]  = '\0';
108
109        limit = p + read_len - 10;
110
111        for ( p = buffer; p < limit; p++ )
112        {
113          if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 )
114          {
115            /* save offset of binary data after `StartData' */
116            offset += p - buffer + 10;
117            goto Found;
118          }
119        }
120
121        FT_MEM_MOVE( buffer, p, 10 );
122        read_len = 256;
123        p = buffer + 10;
124      }
125    }
126
127  Found:
128    /* We have found the start of the binary data.  Now rewind and */
129    /* extract the frame corresponding to the PostScript section.  */
130
131    ps_len = offset - base_offset;
132    if ( FT_STREAM_SEEK( base_offset )                  ||
133         FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
134      goto Exit;
135
136    parser->data_offset    = offset;
137    parser->postscript_len = ps_len;
138    parser->root.base      = parser->postscript;
139    parser->root.cursor    = parser->postscript;
140    parser->root.limit     = parser->root.cursor + ps_len;
141    parser->num_dict       = -1;
142
143    /* Finally, we check whether `StartData' was real -- it could be  */
144    /* in a comment or string.  We also get its arguments to find out */
145    /* whether the data is represented in binary or hex format.       */
146
147    arg1 = parser->root.cursor;
148    cid_parser_skip_PS_token( parser );
149    cid_parser_skip_spaces  ( parser );
150    arg2 = parser->root.cursor;
151    cid_parser_skip_PS_token( parser );
152    cid_parser_skip_spaces  ( parser );
153
154    limit = parser->root.limit;
155    cur   = parser->root.cursor;
156
157    while ( cur < limit )
158    {
159      if ( parser->root.error )
160        break;
161
162      if ( *cur == 'S' && ft_strncmp( (char*)cur, "StartData", 9 ) == 0 )
163      {
164        if ( ft_strncmp( (char*)arg1, "(Hex)", 5 ) == 0 )
165          parser->binary_length = ft_atol( (const char *)arg2 );
166
167        limit = parser->root.limit;
168        cur   = parser->root.cursor;
169        goto Exit;
170      }
171
172      cid_parser_skip_PS_token( parser );
173      cid_parser_skip_spaces  ( parser );
174      arg1 = arg2;
175      arg2 = cur;
176      cur  = parser->root.cursor;
177    }
178
179    /* we haven't found the correct `StartData'; go back and continue */
180    /* searching                                                      */
181    FT_FRAME_RELEASE( parser->postscript );
182    if ( !FT_STREAM_SEEK( offset ) )
183      goto Again;
184
185  Exit:
186    return error;
187  }
188
189
190  FT_LOCAL_DEF( void )
191  cid_parser_done( CID_Parser*  parser )
192  {
193    /* always free the private dictionary */
194    if ( parser->postscript )
195    {
196      FT_Stream  stream = parser->stream;
197
198
199      FT_FRAME_RELEASE( parser->postscript );
200    }
201    parser->root.funcs.done( &parser->root );
202  }
203
204
205/* END */
Note: See TracBrowser for help on using the repository browser.