source: trunk/poppler/freetype-2.1.10/src/cid/cidparse.c @ 2

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

First import

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