xref: /inferno-os/libfreetype/cidparse.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
1 /***************************************************************************/
2 /*                                                                         */
3 /*  cidparse.c                                                             */
4 /*                                                                         */
5 /*    CID-keyed Type1 parser (body).                                       */
6 /*                                                                         */
7 /*  Copyright 1996-2001, 2002 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 
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     /* now, read the rest of the file, until we find a `StartData' */
86     buff_len = 256;
87     for (;;)
88     {
89       FT_Byte   *p, *limit = buffer + 256;
90       FT_ULong  top_position;
91 
92 
93       /* fill input buffer */
94       buff_len -= 256;
95       if ( buff_len > 0 )
96         FT_MEM_MOVE( buffer, limit, buff_len );
97 
98       p = buffer + buff_len;
99 
100       if ( FT_STREAM_READ( p, 256 + 10 - buff_len ) )
101         goto Exit;
102 
103       top_position = FT_STREAM_POS() - buff_len;
104       buff_len = 256 + 10;
105 
106       /* look for `StartData' */
107       for ( p = buffer; p < limit; p++ )
108       {
109         if ( p[0] == 'S' && ft_strncmp( (char*)p, "StartData", 9 ) == 0 )
110         {
111           /* save offset of binary data after `StartData' */
112           offset = (FT_ULong)( top_position - ( limit - p ) + 10 );
113           goto Found;
114         }
115       }
116     }
117 
118   Found:
119     /* we have found the start of the binary data.  We will now        */
120     /* rewind and extract the frame of corresponding to the Postscript */
121     /* section                                                         */
122 
123     ps_len = offset - base_offset;
124     if ( FT_STREAM_SEEK( base_offset )                    ||
125          FT_FRAME_EXTRACT( ps_len, parser->postscript ) )
126       goto Exit;
127 
128     parser->data_offset    = offset;
129     parser->postscript_len = ps_len;
130     parser->root.base      = parser->postscript;
131     parser->root.cursor    = parser->postscript;
132     parser->root.limit     = parser->root.cursor + ps_len;
133     parser->num_dict       = -1;
134 
135   Exit:
136     return error;
137   }
138 
139 
140   FT_LOCAL_DEF( void )
141   cid_parser_done( CID_Parser*  parser )
142   {
143     /* always free the private dictionary */
144     if ( parser->postscript )
145     {
146       FT_Stream  stream = parser->stream;
147 
148 
149       FT_FRAME_RELEASE( parser->postscript );
150     }
151     parser->root.funcs.done( &parser->root );
152   }
153 
154 
155 /* END */
156