xref: /inferno-os/libfreetype/pfrload.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 *37da2899SCharles.Forsyth /***************************************************************************/
2 *37da2899SCharles.Forsyth /*                                                                         */
3 *37da2899SCharles.Forsyth /*  pfrload.c                                                              */
4 *37da2899SCharles.Forsyth /*                                                                         */
5 *37da2899SCharles.Forsyth /*    FreeType PFR loader (body).                                          */
6 *37da2899SCharles.Forsyth /*                                                                         */
7 *37da2899SCharles.Forsyth /*  Copyright 2002 by                                                      */
8 *37da2899SCharles.Forsyth /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9 *37da2899SCharles.Forsyth /*                                                                         */
10 *37da2899SCharles.Forsyth /*  This file is part of the FreeType project, and may only be used,       */
11 *37da2899SCharles.Forsyth /*  modified, and distributed under the terms of the FreeType project      */
12 *37da2899SCharles.Forsyth /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13 *37da2899SCharles.Forsyth /*  this file you indicate that you have read the license and              */
14 *37da2899SCharles.Forsyth /*  understand and accept it fully.                                        */
15 *37da2899SCharles.Forsyth /*                                                                         */
16 *37da2899SCharles.Forsyth /***************************************************************************/
17 *37da2899SCharles.Forsyth 
18 *37da2899SCharles.Forsyth 
19 *37da2899SCharles.Forsyth #include "pfrload.h"
20 *37da2899SCharles.Forsyth #include FT_INTERNAL_DEBUG_H
21 *37da2899SCharles.Forsyth #include FT_INTERNAL_STREAM_H
22 *37da2899SCharles.Forsyth 
23 *37da2899SCharles.Forsyth #include "pfrerror.h"
24 *37da2899SCharles.Forsyth 
25 *37da2899SCharles.Forsyth #undef  FT_COMPONENT
26 *37da2899SCharles.Forsyth #define FT_COMPONENT  trace_pfr
27 *37da2899SCharles.Forsyth 
28 *37da2899SCharles.Forsyth 
29 *37da2899SCharles.Forsyth   /*************************************************************************/
30 *37da2899SCharles.Forsyth   /*************************************************************************/
31 *37da2899SCharles.Forsyth   /*****                                                               *****/
32 *37da2899SCharles.Forsyth   /*****                          EXTRA ITEMS                          *****/
33 *37da2899SCharles.Forsyth   /*****                                                               *****/
34 *37da2899SCharles.Forsyth   /*************************************************************************/
35 *37da2899SCharles.Forsyth   /*************************************************************************/
36 *37da2899SCharles.Forsyth 
37 *37da2899SCharles.Forsyth 
38 *37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
pfr_extra_items_skip(FT_Byte ** pp,FT_Byte * limit)39 *37da2899SCharles.Forsyth   pfr_extra_items_skip( FT_Byte*  *pp,
40 *37da2899SCharles.Forsyth                         FT_Byte*   limit )
41 *37da2899SCharles.Forsyth   {
42 *37da2899SCharles.Forsyth     return pfr_extra_items_parse( pp, limit, NULL, NULL );
43 *37da2899SCharles.Forsyth   }
44 *37da2899SCharles.Forsyth 
45 *37da2899SCharles.Forsyth 
46 *37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
pfr_extra_items_parse(FT_Byte ** pp,FT_Byte * limit,PFR_ExtraItem item_list,FT_Pointer item_data)47 *37da2899SCharles.Forsyth   pfr_extra_items_parse( FT_Byte*       *pp,
48 *37da2899SCharles.Forsyth                          FT_Byte*        limit,
49 *37da2899SCharles.Forsyth                          PFR_ExtraItem   item_list,
50 *37da2899SCharles.Forsyth                          FT_Pointer      item_data )
51 *37da2899SCharles.Forsyth   {
52 *37da2899SCharles.Forsyth     FT_Error  error = 0;
53 *37da2899SCharles.Forsyth     FT_Byte*  p     = *pp;
54 *37da2899SCharles.Forsyth     FT_UInt   num_items, item_type, item_size;
55 *37da2899SCharles.Forsyth 
56 *37da2899SCharles.Forsyth 
57 *37da2899SCharles.Forsyth     PFR_CHECK( 1 );
58 *37da2899SCharles.Forsyth     num_items = PFR_NEXT_BYTE( p );
59 *37da2899SCharles.Forsyth 
60 *37da2899SCharles.Forsyth     for ( ; num_items > 0; num_items-- )
61 *37da2899SCharles.Forsyth     {
62 *37da2899SCharles.Forsyth       PFR_CHECK( 2 );
63 *37da2899SCharles.Forsyth       item_size = PFR_NEXT_BYTE( p );
64 *37da2899SCharles.Forsyth       item_type = PFR_NEXT_BYTE( p );
65 *37da2899SCharles.Forsyth 
66 *37da2899SCharles.Forsyth       PFR_CHECK( item_size );
67 *37da2899SCharles.Forsyth 
68 *37da2899SCharles.Forsyth       if ( item_list )
69 *37da2899SCharles.Forsyth       {
70 *37da2899SCharles.Forsyth         PFR_ExtraItem  extra = item_list;
71 *37da2899SCharles.Forsyth 
72 *37da2899SCharles.Forsyth 
73 *37da2899SCharles.Forsyth         for ( extra = item_list; extra->parser != NULL; extra++ )
74 *37da2899SCharles.Forsyth         {
75 *37da2899SCharles.Forsyth           if ( extra->type == item_type )
76 *37da2899SCharles.Forsyth           {
77 *37da2899SCharles.Forsyth             error = extra->parser( p, p + item_size, item_data );
78 *37da2899SCharles.Forsyth             if ( error ) goto Exit;
79 *37da2899SCharles.Forsyth 
80 *37da2899SCharles.Forsyth             break;
81 *37da2899SCharles.Forsyth           }
82 *37da2899SCharles.Forsyth         }
83 *37da2899SCharles.Forsyth       }
84 *37da2899SCharles.Forsyth 
85 *37da2899SCharles.Forsyth       p += item_size;
86 *37da2899SCharles.Forsyth     }
87 *37da2899SCharles.Forsyth 
88 *37da2899SCharles.Forsyth   Exit:
89 *37da2899SCharles.Forsyth     *pp = p;
90 *37da2899SCharles.Forsyth     return error;
91 *37da2899SCharles.Forsyth 
92 *37da2899SCharles.Forsyth   Too_Short:
93 *37da2899SCharles.Forsyth     FT_ERROR(( "pfr_extra_items_parse: invalid extra items table\n" ));
94 *37da2899SCharles.Forsyth     error = PFR_Err_Invalid_Table;
95 *37da2899SCharles.Forsyth     goto Exit;
96 *37da2899SCharles.Forsyth   }
97 *37da2899SCharles.Forsyth 
98 *37da2899SCharles.Forsyth 
99 *37da2899SCharles.Forsyth   /*************************************************************************/
100 *37da2899SCharles.Forsyth   /*************************************************************************/
101 *37da2899SCharles.Forsyth   /*****                                                               *****/
102 *37da2899SCharles.Forsyth   /*****                          PFR HEADER                           *****/
103 *37da2899SCharles.Forsyth   /*****                                                               *****/
104 *37da2899SCharles.Forsyth   /*************************************************************************/
105 *37da2899SCharles.Forsyth   /*************************************************************************/
106 *37da2899SCharles.Forsyth 
107 *37da2899SCharles.Forsyth    static const FT_Frame_Field  pfr_header_fields[] =
108 *37da2899SCharles.Forsyth    {
109 *37da2899SCharles.Forsyth #undef  FT_STRUCTURE
110 *37da2899SCharles.Forsyth #define FT_STRUCTURE  PFR_HeaderRec
111 *37da2899SCharles.Forsyth 
112 *37da2899SCharles.Forsyth      FT_FRAME_START( 58 ),
113 *37da2899SCharles.Forsyth        FT_FRAME_ULONG ( signature ),
114 *37da2899SCharles.Forsyth        FT_FRAME_USHORT( version ),
115 *37da2899SCharles.Forsyth        FT_FRAME_USHORT( signature2 ),
116 *37da2899SCharles.Forsyth        FT_FRAME_USHORT( header_size ),
117 *37da2899SCharles.Forsyth 
118 *37da2899SCharles.Forsyth        FT_FRAME_USHORT( log_dir_size ),
119 *37da2899SCharles.Forsyth        FT_FRAME_USHORT( log_dir_offset ),
120 *37da2899SCharles.Forsyth 
121 *37da2899SCharles.Forsyth        FT_FRAME_USHORT( log_font_max_size ),
122 *37da2899SCharles.Forsyth        FT_FRAME_UOFF3 ( log_font_section_size ),
123 *37da2899SCharles.Forsyth        FT_FRAME_UOFF3 ( log_font_section_offset ),
124 *37da2899SCharles.Forsyth 
125 *37da2899SCharles.Forsyth        FT_FRAME_USHORT( phy_font_max_size ),
126 *37da2899SCharles.Forsyth        FT_FRAME_UOFF3 ( phy_font_section_size ),
127 *37da2899SCharles.Forsyth        FT_FRAME_UOFF3 ( phy_font_section_offset ),
128 *37da2899SCharles.Forsyth 
129 *37da2899SCharles.Forsyth        FT_FRAME_USHORT( gps_max_size ),
130 *37da2899SCharles.Forsyth        FT_FRAME_UOFF3 ( gps_section_size ),
131 *37da2899SCharles.Forsyth        FT_FRAME_UOFF3 ( gps_section_offset ),
132 *37da2899SCharles.Forsyth 
133 *37da2899SCharles.Forsyth        FT_FRAME_BYTE  ( max_blue_values ),
134 *37da2899SCharles.Forsyth        FT_FRAME_BYTE  ( max_x_orus ),
135 *37da2899SCharles.Forsyth        FT_FRAME_BYTE  ( max_y_orus ),
136 *37da2899SCharles.Forsyth 
137 *37da2899SCharles.Forsyth        FT_FRAME_BYTE  ( phy_font_max_size_high ),
138 *37da2899SCharles.Forsyth        FT_FRAME_BYTE  ( color_flags ),
139 *37da2899SCharles.Forsyth 
140 *37da2899SCharles.Forsyth        FT_FRAME_UOFF3 ( bct_max_size ),
141 *37da2899SCharles.Forsyth        FT_FRAME_UOFF3 ( bct_set_max_size ),
142 *37da2899SCharles.Forsyth        FT_FRAME_UOFF3 ( phy_bct_set_max_size ),
143 *37da2899SCharles.Forsyth 
144 *37da2899SCharles.Forsyth        FT_FRAME_USHORT( num_phy_fonts ),
145 *37da2899SCharles.Forsyth        FT_FRAME_BYTE  ( max_vert_stem_snap ),
146 *37da2899SCharles.Forsyth        FT_FRAME_BYTE  ( max_horz_stem_snap ),
147 *37da2899SCharles.Forsyth        FT_FRAME_USHORT( max_chars ),
148 *37da2899SCharles.Forsyth      FT_FRAME_END
149 *37da2899SCharles.Forsyth    };
150 *37da2899SCharles.Forsyth 
151 *37da2899SCharles.Forsyth 
152 *37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
pfr_header_load(PFR_Header header,FT_Stream stream)153 *37da2899SCharles.Forsyth   pfr_header_load( PFR_Header  header,
154 *37da2899SCharles.Forsyth                    FT_Stream   stream )
155 *37da2899SCharles.Forsyth   {
156 *37da2899SCharles.Forsyth     FT_Error   error;
157 *37da2899SCharles.Forsyth 
158 *37da2899SCharles.Forsyth 
159 *37da2899SCharles.Forsyth     /* read header directly */
160 *37da2899SCharles.Forsyth     if ( !FT_STREAM_SEEK( 0 )                                &&
161 *37da2899SCharles.Forsyth          !FT_STREAM_READ_FIELDS( pfr_header_fields, header ) )
162 *37da2899SCharles.Forsyth     {
163 *37da2899SCharles.Forsyth       /* make a few adjustments to the header */
164 *37da2899SCharles.Forsyth       header->phy_font_max_size +=
165 *37da2899SCharles.Forsyth         (FT_UInt32)header->phy_font_max_size_high << 16;
166 *37da2899SCharles.Forsyth     }
167 *37da2899SCharles.Forsyth 
168 *37da2899SCharles.Forsyth     return error;
169 *37da2899SCharles.Forsyth   }
170 *37da2899SCharles.Forsyth 
171 *37da2899SCharles.Forsyth 
172 *37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Bool )
pfr_header_check(PFR_Header header)173 *37da2899SCharles.Forsyth   pfr_header_check( PFR_Header  header )
174 *37da2899SCharles.Forsyth   {
175 *37da2899SCharles.Forsyth     FT_Bool  result = 1;
176 *37da2899SCharles.Forsyth 
177 *37da2899SCharles.Forsyth 
178 *37da2899SCharles.Forsyth     /* check signature and header size */
179 *37da2899SCharles.Forsyth     if ( header->signature  != 0x50465230L ||   /* "PFR0" */
180 *37da2899SCharles.Forsyth          header->version     > 4           ||
181 *37da2899SCharles.Forsyth          header->header_size < 58          ||
182 *37da2899SCharles.Forsyth          header->signature2 != 0x0d0a      )    /* CR/LF  */
183 *37da2899SCharles.Forsyth     {
184 *37da2899SCharles.Forsyth       result = 0;
185 *37da2899SCharles.Forsyth     }
186 *37da2899SCharles.Forsyth     return  result;
187 *37da2899SCharles.Forsyth   }
188 *37da2899SCharles.Forsyth 
189 *37da2899SCharles.Forsyth 
190 *37da2899SCharles.Forsyth   /***********************************************************************/
191 *37da2899SCharles.Forsyth   /***********************************************************************/
192 *37da2899SCharles.Forsyth   /*****                                                             *****/
193 *37da2899SCharles.Forsyth   /*****                    PFR LOGICAL FONTS                        *****/
194 *37da2899SCharles.Forsyth   /*****                                                             *****/
195 *37da2899SCharles.Forsyth   /***********************************************************************/
196 *37da2899SCharles.Forsyth   /***********************************************************************/
197 *37da2899SCharles.Forsyth 
198 *37da2899SCharles.Forsyth 
199 *37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
pfr_log_font_count(FT_Stream stream,FT_UInt32 section_offset,FT_UInt * acount)200 *37da2899SCharles.Forsyth   pfr_log_font_count( FT_Stream  stream,
201 *37da2899SCharles.Forsyth                       FT_UInt32  section_offset,
202 *37da2899SCharles.Forsyth                       FT_UInt   *acount )
203 *37da2899SCharles.Forsyth   {
204 *37da2899SCharles.Forsyth     FT_Error   error;
205 *37da2899SCharles.Forsyth     FT_UInt    count;
206 *37da2899SCharles.Forsyth     FT_UInt    result = 0;
207 *37da2899SCharles.Forsyth 
208 *37da2899SCharles.Forsyth 
209 *37da2899SCharles.Forsyth     if ( FT_STREAM_SEEK( section_offset ) || FT_READ_USHORT( count ) )
210 *37da2899SCharles.Forsyth       goto Exit;
211 *37da2899SCharles.Forsyth 
212 *37da2899SCharles.Forsyth     result = count;
213 *37da2899SCharles.Forsyth 
214 *37da2899SCharles.Forsyth   Exit:
215 *37da2899SCharles.Forsyth     *acount = result;
216 *37da2899SCharles.Forsyth     return error;
217 *37da2899SCharles.Forsyth   }
218 *37da2899SCharles.Forsyth 
219 *37da2899SCharles.Forsyth 
220 *37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
pfr_log_font_load(PFR_LogFont log_font,FT_Stream stream,FT_UInt idx,FT_UInt32 section_offset,FT_Bool size_increment)221 *37da2899SCharles.Forsyth   pfr_log_font_load( PFR_LogFont  log_font,
222 *37da2899SCharles.Forsyth                      FT_Stream    stream,
223 *37da2899SCharles.Forsyth                      FT_UInt      idx,
224 *37da2899SCharles.Forsyth                      FT_UInt32    section_offset,
225 *37da2899SCharles.Forsyth                      FT_Bool      size_increment )
226 *37da2899SCharles.Forsyth   {
227 *37da2899SCharles.Forsyth     FT_UInt    num_log_fonts;
228 *37da2899SCharles.Forsyth     FT_UInt    flags;
229 *37da2899SCharles.Forsyth     FT_UInt32  offset;
230 *37da2899SCharles.Forsyth     FT_UInt32  size;
231 *37da2899SCharles.Forsyth     FT_Error   error;
232 *37da2899SCharles.Forsyth 
233 *37da2899SCharles.Forsyth 
234 *37da2899SCharles.Forsyth     if ( FT_STREAM_SEEK( section_offset ) ||
235 *37da2899SCharles.Forsyth          FT_READ_USHORT( num_log_fonts )  )
236 *37da2899SCharles.Forsyth       goto Exit;
237 *37da2899SCharles.Forsyth 
238 *37da2899SCharles.Forsyth     if ( idx >= num_log_fonts )
239 *37da2899SCharles.Forsyth       return PFR_Err_Invalid_Argument;
240 *37da2899SCharles.Forsyth 
241 *37da2899SCharles.Forsyth     if ( FT_STREAM_SKIP( idx * 5 ) ||
242 *37da2899SCharles.Forsyth          FT_READ_USHORT( size )      ||
243 *37da2899SCharles.Forsyth          FT_READ_UOFF3 ( offset )    )
244 *37da2899SCharles.Forsyth       goto Exit;
245 *37da2899SCharles.Forsyth 
246 *37da2899SCharles.Forsyth     /* save logical font size and offset */
247 *37da2899SCharles.Forsyth     log_font->size   = size;
248 *37da2899SCharles.Forsyth     log_font->offset = offset;
249 *37da2899SCharles.Forsyth 
250 *37da2899SCharles.Forsyth     /* now, check the rest of the table before loading it */
251 *37da2899SCharles.Forsyth     {
252 *37da2899SCharles.Forsyth       FT_Byte*  p;
253 *37da2899SCharles.Forsyth       FT_Byte*  limit;
254 *37da2899SCharles.Forsyth       FT_UInt   local;
255 *37da2899SCharles.Forsyth 
256 *37da2899SCharles.Forsyth 
257 *37da2899SCharles.Forsyth       if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) )
258 *37da2899SCharles.Forsyth         goto Exit;
259 *37da2899SCharles.Forsyth 
260 *37da2899SCharles.Forsyth       p     = stream->cursor;
261 *37da2899SCharles.Forsyth       limit = p + size;
262 *37da2899SCharles.Forsyth 
263 *37da2899SCharles.Forsyth       PFR_CHECK(13);
264 *37da2899SCharles.Forsyth 
265 *37da2899SCharles.Forsyth       log_font->matrix[0] = PFR_NEXT_LONG( p );
266 *37da2899SCharles.Forsyth       log_font->matrix[1] = PFR_NEXT_LONG( p );
267 *37da2899SCharles.Forsyth       log_font->matrix[2] = PFR_NEXT_LONG( p );
268 *37da2899SCharles.Forsyth       log_font->matrix[3] = PFR_NEXT_LONG( p );
269 *37da2899SCharles.Forsyth 
270 *37da2899SCharles.Forsyth       flags = PFR_NEXT_BYTE( p );
271 *37da2899SCharles.Forsyth 
272 *37da2899SCharles.Forsyth       local = 0;
273 *37da2899SCharles.Forsyth       if ( flags & PFR_LOG_STROKE )
274 *37da2899SCharles.Forsyth       {
275 *37da2899SCharles.Forsyth         local++;
276 *37da2899SCharles.Forsyth         if ( flags & PFR_LOG_2BYTE_STROKE )
277 *37da2899SCharles.Forsyth           local++;
278 *37da2899SCharles.Forsyth 
279 *37da2899SCharles.Forsyth         if ( (flags & PFR_LINE_JOIN_MASK) == PFR_LINE_JOIN_MITER )
280 *37da2899SCharles.Forsyth           local += 3;
281 *37da2899SCharles.Forsyth       }
282 *37da2899SCharles.Forsyth       if ( flags & PFR_LOG_BOLD )
283 *37da2899SCharles.Forsyth       {
284 *37da2899SCharles.Forsyth         local++;
285 *37da2899SCharles.Forsyth         if ( flags & PFR_LOG_2BYTE_BOLD )
286 *37da2899SCharles.Forsyth           local++;
287 *37da2899SCharles.Forsyth       }
288 *37da2899SCharles.Forsyth 
289 *37da2899SCharles.Forsyth       PFR_CHECK( local );
290 *37da2899SCharles.Forsyth 
291 *37da2899SCharles.Forsyth       if ( flags & PFR_LOG_STROKE )
292 *37da2899SCharles.Forsyth       {
293 *37da2899SCharles.Forsyth         log_font->stroke_thickness = ( flags & PFR_LOG_2BYTE_STROKE )
294 *37da2899SCharles.Forsyth                                      ? PFR_NEXT_SHORT( p )
295 *37da2899SCharles.Forsyth                                      : PFR_NEXT_BYTE( p );
296 *37da2899SCharles.Forsyth 
297 *37da2899SCharles.Forsyth         if ( ( flags & PFR_LINE_JOIN_MASK ) == PFR_LINE_JOIN_MITER )
298 *37da2899SCharles.Forsyth           log_font->miter_limit = PFR_NEXT_LONG( p );
299 *37da2899SCharles.Forsyth       }
300 *37da2899SCharles.Forsyth 
301 *37da2899SCharles.Forsyth       if ( flags & PFR_LOG_BOLD )
302 *37da2899SCharles.Forsyth       {
303 *37da2899SCharles.Forsyth         log_font->bold_thickness = ( flags & PFR_LOG_2BYTE_BOLD )
304 *37da2899SCharles.Forsyth                                    ? PFR_NEXT_SHORT( p )
305 *37da2899SCharles.Forsyth                                    : PFR_NEXT_BYTE( p );
306 *37da2899SCharles.Forsyth       }
307 *37da2899SCharles.Forsyth 
308 *37da2899SCharles.Forsyth       if ( flags & PFR_LOG_EXTRA_ITEMS )
309 *37da2899SCharles.Forsyth       {
310 *37da2899SCharles.Forsyth         error = pfr_extra_items_skip( &p, limit );
311 *37da2899SCharles.Forsyth         if (error) goto Fail;
312 *37da2899SCharles.Forsyth       }
313 *37da2899SCharles.Forsyth 
314 *37da2899SCharles.Forsyth       PFR_CHECK(5);
315 *37da2899SCharles.Forsyth       log_font->phys_size   = PFR_NEXT_USHORT( p );
316 *37da2899SCharles.Forsyth       log_font->phys_offset = PFR_NEXT_ULONG( p );
317 *37da2899SCharles.Forsyth       if ( size_increment )
318 *37da2899SCharles.Forsyth       {
319 *37da2899SCharles.Forsyth         PFR_CHECK( 1 );
320 *37da2899SCharles.Forsyth         log_font->phys_size += (FT_UInt32)PFR_NEXT_BYTE( p ) << 16;
321 *37da2899SCharles.Forsyth       }
322 *37da2899SCharles.Forsyth     }
323 *37da2899SCharles.Forsyth 
324 *37da2899SCharles.Forsyth   Fail:
325 *37da2899SCharles.Forsyth     FT_FRAME_EXIT();
326 *37da2899SCharles.Forsyth 
327 *37da2899SCharles.Forsyth   Exit:
328 *37da2899SCharles.Forsyth     return error;
329 *37da2899SCharles.Forsyth 
330 *37da2899SCharles.Forsyth   Too_Short:
331 *37da2899SCharles.Forsyth     FT_ERROR(( "pfr_log_font_load: invalid logical font table\n" ));
332 *37da2899SCharles.Forsyth     error = PFR_Err_Invalid_Table;
333 *37da2899SCharles.Forsyth     goto Fail;
334 *37da2899SCharles.Forsyth   }
335 *37da2899SCharles.Forsyth 
336 *37da2899SCharles.Forsyth 
337 *37da2899SCharles.Forsyth   /***********************************************************************/
338 *37da2899SCharles.Forsyth   /***********************************************************************/
339 *37da2899SCharles.Forsyth   /*****                                                             *****/
340 *37da2899SCharles.Forsyth   /*****                    PFR PHYSICAL FONTS                       *****/
341 *37da2899SCharles.Forsyth   /*****                                                             *****/
342 *37da2899SCharles.Forsyth   /***********************************************************************/
343 *37da2899SCharles.Forsyth   /***********************************************************************/
344 *37da2899SCharles.Forsyth 
345 *37da2899SCharles.Forsyth 
346 *37da2899SCharles.Forsyth   /* load bitmap strikes lists */
347 *37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
pfr_extra_item_load_bitmap_info(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)348 *37da2899SCharles.Forsyth   pfr_extra_item_load_bitmap_info( FT_Byte*     p,
349 *37da2899SCharles.Forsyth                                    FT_Byte*     limit,
350 *37da2899SCharles.Forsyth                                    PFR_PhyFont  phy_font )
351 *37da2899SCharles.Forsyth   {
352 *37da2899SCharles.Forsyth     FT_Memory   memory = phy_font->memory;
353 *37da2899SCharles.Forsyth     PFR_Strike  strike;
354 *37da2899SCharles.Forsyth     FT_UInt     flags0;
355 *37da2899SCharles.Forsyth     FT_UInt     n, count, size1;
356 *37da2899SCharles.Forsyth     FT_Error    error = 0;
357 *37da2899SCharles.Forsyth 
358 *37da2899SCharles.Forsyth 
359 *37da2899SCharles.Forsyth     PFR_CHECK( 5 );
360 *37da2899SCharles.Forsyth 
361 *37da2899SCharles.Forsyth     p += 3;  /* skip bctSize */
362 *37da2899SCharles.Forsyth     flags0 = PFR_NEXT_BYTE( p );
363 *37da2899SCharles.Forsyth     count  = PFR_NEXT_BYTE( p );
364 *37da2899SCharles.Forsyth 
365 *37da2899SCharles.Forsyth     /* re-allocate when needed */
366 *37da2899SCharles.Forsyth     if ( phy_font->num_strikes + count > phy_font->max_strikes )
367 *37da2899SCharles.Forsyth     {
368 *37da2899SCharles.Forsyth       FT_UInt  new_max = (phy_font->num_strikes + count + 3) & -4;
369 *37da2899SCharles.Forsyth 
370 *37da2899SCharles.Forsyth       if ( FT_RENEW_ARRAY( phy_font->strikes,
371 *37da2899SCharles.Forsyth                            phy_font->num_strikes,
372 *37da2899SCharles.Forsyth                            new_max ) )
373 *37da2899SCharles.Forsyth         goto Exit;
374 *37da2899SCharles.Forsyth 
375 *37da2899SCharles.Forsyth       phy_font->max_strikes = new_max;
376 *37da2899SCharles.Forsyth     }
377 *37da2899SCharles.Forsyth 
378 *37da2899SCharles.Forsyth     size1 = 1 + 1 + 1 + 2 + 2 + 1;
379 *37da2899SCharles.Forsyth     if ( flags0 & PFR_STRIKE_2BYTE_XPPM )
380 *37da2899SCharles.Forsyth       size1++;
381 *37da2899SCharles.Forsyth 
382 *37da2899SCharles.Forsyth     if ( flags0 & PFR_STRIKE_2BYTE_YPPM )
383 *37da2899SCharles.Forsyth       size1++;
384 *37da2899SCharles.Forsyth 
385 *37da2899SCharles.Forsyth     if ( flags0 & PFR_STRIKE_3BYTE_SIZE )
386 *37da2899SCharles.Forsyth       size1++;
387 *37da2899SCharles.Forsyth 
388 *37da2899SCharles.Forsyth     if ( flags0 & PFR_STRIKE_3BYTE_OFFSET )
389 *37da2899SCharles.Forsyth       size1++;
390 *37da2899SCharles.Forsyth 
391 *37da2899SCharles.Forsyth     if ( flags0 & PFR_STRIKE_2BYTE_COUNT )
392 *37da2899SCharles.Forsyth       size1++;
393 *37da2899SCharles.Forsyth 
394 *37da2899SCharles.Forsyth     strike = phy_font->strikes + phy_font->num_strikes;
395 *37da2899SCharles.Forsyth 
396 *37da2899SCharles.Forsyth     PFR_CHECK( count * size1 );
397 *37da2899SCharles.Forsyth 
398 *37da2899SCharles.Forsyth     for ( n = 0; n < count; n++, strike++ )
399 *37da2899SCharles.Forsyth     {
400 *37da2899SCharles.Forsyth       strike->x_ppm       = ( flags0 & PFR_STRIKE_2BYTE_XPPM )
401 *37da2899SCharles.Forsyth                             ? PFR_NEXT_USHORT( p )
402 *37da2899SCharles.Forsyth                             : PFR_NEXT_BYTE( p );
403 *37da2899SCharles.Forsyth 
404 *37da2899SCharles.Forsyth       strike->y_ppm       = ( flags0 & PFR_STRIKE_2BYTE_YPPM )
405 *37da2899SCharles.Forsyth                             ? PFR_NEXT_USHORT( p )
406 *37da2899SCharles.Forsyth                             : PFR_NEXT_BYTE( p );
407 *37da2899SCharles.Forsyth 
408 *37da2899SCharles.Forsyth       strike->flags       = PFR_NEXT_BYTE( p );
409 *37da2899SCharles.Forsyth 
410 *37da2899SCharles.Forsyth       strike->bct_size    = ( flags0 & PFR_STRIKE_3BYTE_SIZE )
411 *37da2899SCharles.Forsyth                             ? PFR_NEXT_ULONG( p )
412 *37da2899SCharles.Forsyth                             : PFR_NEXT_USHORT( p );
413 *37da2899SCharles.Forsyth 
414 *37da2899SCharles.Forsyth       strike->bct_offset  = ( flags0 & PFR_STRIKE_3BYTE_OFFSET )
415 *37da2899SCharles.Forsyth                             ? PFR_NEXT_ULONG( p )
416 *37da2899SCharles.Forsyth                             : PFR_NEXT_USHORT( p );
417 *37da2899SCharles.Forsyth 
418 *37da2899SCharles.Forsyth       strike->num_bitmaps = ( flags0 & PFR_STRIKE_2BYTE_COUNT )
419 *37da2899SCharles.Forsyth                             ? PFR_NEXT_USHORT( p )
420 *37da2899SCharles.Forsyth                             : PFR_NEXT_BYTE( p );
421 *37da2899SCharles.Forsyth     }
422 *37da2899SCharles.Forsyth 
423 *37da2899SCharles.Forsyth     phy_font->num_strikes += count;
424 *37da2899SCharles.Forsyth 
425 *37da2899SCharles.Forsyth   Exit:
426 *37da2899SCharles.Forsyth     return error;
427 *37da2899SCharles.Forsyth 
428 *37da2899SCharles.Forsyth   Too_Short:
429 *37da2899SCharles.Forsyth     error = PFR_Err_Invalid_Table;
430 *37da2899SCharles.Forsyth     FT_ERROR(( "pfr_extra_item_load_bitmap_info: invalid bitmap info table\n" ));
431 *37da2899SCharles.Forsyth     goto Exit;
432 *37da2899SCharles.Forsyth   }
433 *37da2899SCharles.Forsyth 
434 *37da2899SCharles.Forsyth 
435 *37da2899SCharles.Forsyth   /* load font ID, i.e. name */
436 *37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
pfr_extra_item_load_font_id(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)437 *37da2899SCharles.Forsyth   pfr_extra_item_load_font_id( FT_Byte*     p,
438 *37da2899SCharles.Forsyth                                FT_Byte*     limit,
439 *37da2899SCharles.Forsyth                                PFR_PhyFont  phy_font )
440 *37da2899SCharles.Forsyth   {
441 *37da2899SCharles.Forsyth     FT_Error   error  = 0;
442 *37da2899SCharles.Forsyth     FT_Memory  memory = phy_font->memory;
443 *37da2899SCharles.Forsyth     FT_UInt    len    = (FT_UInt)( limit - p );
444 *37da2899SCharles.Forsyth 
445 *37da2899SCharles.Forsyth 
446 *37da2899SCharles.Forsyth     if ( phy_font->font_id != NULL )
447 *37da2899SCharles.Forsyth       goto Exit;
448 *37da2899SCharles.Forsyth 
449 *37da2899SCharles.Forsyth     if ( FT_ALLOC( phy_font->font_id, len+1 ) )
450 *37da2899SCharles.Forsyth       goto Exit;
451 *37da2899SCharles.Forsyth 
452 *37da2899SCharles.Forsyth     /* copy font ID name, and terminate it for safety */
453 *37da2899SCharles.Forsyth     FT_MEM_COPY( phy_font->font_id, p, len );
454 *37da2899SCharles.Forsyth     phy_font->font_id[len] = 0;
455 *37da2899SCharles.Forsyth 
456 *37da2899SCharles.Forsyth   Exit:
457 *37da2899SCharles.Forsyth     return error;
458 *37da2899SCharles.Forsyth   }
459 *37da2899SCharles.Forsyth 
460 *37da2899SCharles.Forsyth 
461 *37da2899SCharles.Forsyth   /* load stem snap tables */
462 *37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
pfr_extra_item_load_stem_snaps(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)463 *37da2899SCharles.Forsyth   pfr_extra_item_load_stem_snaps( FT_Byte*     p,
464 *37da2899SCharles.Forsyth                                   FT_Byte*     limit,
465 *37da2899SCharles.Forsyth                                   PFR_PhyFont  phy_font )
466 *37da2899SCharles.Forsyth   {
467 *37da2899SCharles.Forsyth     FT_UInt    count, num_vert, num_horz;
468 *37da2899SCharles.Forsyth     FT_Int*    snaps;
469 *37da2899SCharles.Forsyth     FT_Error   error  = 0;
470 *37da2899SCharles.Forsyth     FT_Memory  memory = phy_font->memory;
471 *37da2899SCharles.Forsyth 
472 *37da2899SCharles.Forsyth 
473 *37da2899SCharles.Forsyth     if ( phy_font->vertical.stem_snaps != NULL )
474 *37da2899SCharles.Forsyth       goto Exit;
475 *37da2899SCharles.Forsyth 
476 *37da2899SCharles.Forsyth     PFR_CHECK( 1 );
477 *37da2899SCharles.Forsyth     count = PFR_NEXT_BYTE( p );
478 *37da2899SCharles.Forsyth 
479 *37da2899SCharles.Forsyth     num_vert = count & 15;
480 *37da2899SCharles.Forsyth     num_horz = count >> 4;
481 *37da2899SCharles.Forsyth     count    = num_vert + num_horz;
482 *37da2899SCharles.Forsyth 
483 *37da2899SCharles.Forsyth     PFR_CHECK( count * 2 );
484 *37da2899SCharles.Forsyth 
485 *37da2899SCharles.Forsyth     if ( FT_NEW_ARRAY( snaps, count ) )
486 *37da2899SCharles.Forsyth       goto Exit;
487 *37da2899SCharles.Forsyth 
488 *37da2899SCharles.Forsyth     phy_font->vertical.stem_snaps = snaps;
489 *37da2899SCharles.Forsyth     phy_font->horizontal.stem_snaps = snaps + num_vert;
490 *37da2899SCharles.Forsyth 
491 *37da2899SCharles.Forsyth     for ( ; count > 0; count--, snaps++ )
492 *37da2899SCharles.Forsyth       *snaps = FT_NEXT_SHORT( p );
493 *37da2899SCharles.Forsyth 
494 *37da2899SCharles.Forsyth   Exit:
495 *37da2899SCharles.Forsyth     return error;
496 *37da2899SCharles.Forsyth 
497 *37da2899SCharles.Forsyth   Too_Short:
498 *37da2899SCharles.Forsyth     error = PFR_Err_Invalid_Table;
499 *37da2899SCharles.Forsyth     FT_ERROR(( "pfr_exta_item_load_stem_snaps: invalid stem snaps table\n" ));
500 *37da2899SCharles.Forsyth     goto Exit;
501 *37da2899SCharles.Forsyth   }
502 *37da2899SCharles.Forsyth 
503 *37da2899SCharles.Forsyth 
504 *37da2899SCharles.Forsyth #if 0
505 *37da2899SCharles.Forsyth 
506 *37da2899SCharles.Forsyth   /* load kerning pair data */
507 *37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
508 *37da2899SCharles.Forsyth   pfr_extra_item_load_kerning_pairs( FT_Byte*     p,
509 *37da2899SCharles.Forsyth                                      FT_Byte*     limit,
510 *37da2899SCharles.Forsyth                                      PFR_PhyFont  phy_font )
511 *37da2899SCharles.Forsyth   {
512 *37da2899SCharles.Forsyth     FT_Int        count;
513 *37da2899SCharles.Forsyth     FT_UShort     base_adj;
514 *37da2899SCharles.Forsyth     FT_UInt       flags;
515 *37da2899SCharles.Forsyth     FT_UInt       num_pairs;
516 *37da2899SCharles.Forsyth     PFR_KernPair  pairs;
517 *37da2899SCharles.Forsyth     FT_Error      error  = 0;
518 *37da2899SCharles.Forsyth     FT_Memory     memory = phy_font->memory;
519 *37da2899SCharles.Forsyth 
520 *37da2899SCharles.Forsyth 
521 *37da2899SCharles.Forsyth     /* allocate a new kerning item */
522 *37da2899SCharles.Forsyth     /* XXX: there may be multiple extra items for kerning */
523 *37da2899SCharles.Forsyth     if ( phy_font->kern_pairs != NULL )
524 *37da2899SCharles.Forsyth       goto Exit;
525 *37da2899SCharles.Forsyth 
526 *37da2899SCharles.Forsyth     FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" ));
527 *37da2899SCharles.Forsyth 
528 *37da2899SCharles.Forsyth     PFR_CHECK( 4 );
529 *37da2899SCharles.Forsyth 
530 *37da2899SCharles.Forsyth     num_pairs = PFR_NEXT_BYTE( p );
531 *37da2899SCharles.Forsyth     base_adj  = PFR_NEXT_SHORT( p );
532 *37da2899SCharles.Forsyth     flags     = PFR_NEXT_BYTE( p );
533 *37da2899SCharles.Forsyth 
534 *37da2899SCharles.Forsyth #ifndef PFR_CONFIG_NO_CHECKS
535 *37da2899SCharles.Forsyth     count = 3;
536 *37da2899SCharles.Forsyth 
537 *37da2899SCharles.Forsyth     if ( flags & PFR_KERN_2BYTE_CHAR )
538 *37da2899SCharles.Forsyth       count += 2;
539 *37da2899SCharles.Forsyth 
540 *37da2899SCharles.Forsyth     if ( flags & PFR_KERN_2BYTE_ADJ )
541 *37da2899SCharles.Forsyth       count += 1;
542 *37da2899SCharles.Forsyth 
543 *37da2899SCharles.Forsyth     PFR_CHECK( num_pairs * count );
544 *37da2899SCharles.Forsyth #endif
545 *37da2899SCharles.Forsyth 
546 *37da2899SCharles.Forsyth     if ( FT_NEW_ARRAY( pairs, num_pairs ) )
547 *37da2899SCharles.Forsyth       goto Exit;
548 *37da2899SCharles.Forsyth 
549 *37da2899SCharles.Forsyth     phy_font->num_kern_pairs = num_pairs;
550 *37da2899SCharles.Forsyth     phy_font->kern_pairs     = pairs;
551 *37da2899SCharles.Forsyth 
552 *37da2899SCharles.Forsyth     for (count = num_pairs ; count > 0; count--, pairs++ )
553 *37da2899SCharles.Forsyth     {
554 *37da2899SCharles.Forsyth       if ( flags & PFR_KERN_2BYTE_CHAR )
555 *37da2899SCharles.Forsyth       {
556 *37da2899SCharles.Forsyth         pairs->glyph1 = PFR_NEXT_USHORT( p );
557 *37da2899SCharles.Forsyth         pairs->glyph2 = PFR_NEXT_USHORT( p );
558 *37da2899SCharles.Forsyth       }
559 *37da2899SCharles.Forsyth       else
560 *37da2899SCharles.Forsyth       {
561 *37da2899SCharles.Forsyth         pairs->glyph1 = PFR_NEXT_BYTE( p );
562 *37da2899SCharles.Forsyth         pairs->glyph2 = PFR_NEXT_BYTE( p );
563 *37da2899SCharles.Forsyth       }
564 *37da2899SCharles.Forsyth 
565 *37da2899SCharles.Forsyth       if ( flags & PFR_KERN_2BYTE_ADJ )
566 *37da2899SCharles.Forsyth         pairs->kerning.x = base_adj + PFR_NEXT_SHORT( p );
567 *37da2899SCharles.Forsyth       else
568 *37da2899SCharles.Forsyth         pairs->kerning.x = base_adj + PFR_NEXT_INT8( p );
569 *37da2899SCharles.Forsyth 
570 *37da2899SCharles.Forsyth       pairs->kerning.y = 0;
571 *37da2899SCharles.Forsyth 
572 *37da2899SCharles.Forsyth       FT_TRACE2(( "kerning %d <-> %d : %ld\n",
573 *37da2899SCharles.Forsyth                    pairs->glyph1, pairs->glyph2, pairs->kerning.x ));
574 *37da2899SCharles.Forsyth     }
575 *37da2899SCharles.Forsyth 
576 *37da2899SCharles.Forsyth   Exit:
577 *37da2899SCharles.Forsyth     return error;
578 *37da2899SCharles.Forsyth 
579 *37da2899SCharles.Forsyth   Too_Short:
580 *37da2899SCharles.Forsyth     error = PFR_Err_Invalid_Table;
581 *37da2899SCharles.Forsyth     FT_ERROR(( "pfr_extra_item_load_kerning_pairs: "
582 *37da2899SCharles.Forsyth                "invalid kerning pairs table\n" ));
583 *37da2899SCharles.Forsyth     goto Exit;
584 *37da2899SCharles.Forsyth   }
585 *37da2899SCharles.Forsyth 
586 *37da2899SCharles.Forsyth #else /* 0 */
587 *37da2899SCharles.Forsyth 
588 *37da2899SCharles.Forsyth   /* load kerning pair data */
589 *37da2899SCharles.Forsyth   FT_CALLBACK_DEF( FT_Error )
pfr_extra_item_load_kerning_pairs(FT_Byte * p,FT_Byte * limit,PFR_PhyFont phy_font)590 *37da2899SCharles.Forsyth   pfr_extra_item_load_kerning_pairs( FT_Byte*     p,
591 *37da2899SCharles.Forsyth                                      FT_Byte*     limit,
592 *37da2899SCharles.Forsyth                                      PFR_PhyFont  phy_font )
593 *37da2899SCharles.Forsyth   {
594 *37da2899SCharles.Forsyth     PFR_KernItem  item;
595 *37da2899SCharles.Forsyth     FT_Error      error  = 0;
596 *37da2899SCharles.Forsyth     FT_Memory     memory = phy_font->memory;
597 *37da2899SCharles.Forsyth 
598 *37da2899SCharles.Forsyth 
599 *37da2899SCharles.Forsyth     FT_TRACE2(( "pfr_extra_item_load_kerning_pairs()\n" ));
600 *37da2899SCharles.Forsyth 
601 *37da2899SCharles.Forsyth     if ( FT_NEW( item ) )
602 *37da2899SCharles.Forsyth       goto Exit;
603 *37da2899SCharles.Forsyth 
604 *37da2899SCharles.Forsyth     PFR_CHECK( 4 );
605 *37da2899SCharles.Forsyth 
606 *37da2899SCharles.Forsyth     item->pair_count = PFR_NEXT_BYTE( p );
607 *37da2899SCharles.Forsyth     item->base_adj   = PFR_NEXT_SHORT( p );
608 *37da2899SCharles.Forsyth     item->flags      = PFR_NEXT_BYTE( p );
609 *37da2899SCharles.Forsyth     item->offset     = phy_font->offset + ( p - phy_font->cursor );
610 *37da2899SCharles.Forsyth 
611 *37da2899SCharles.Forsyth #ifndef PFR_CONFIG_NO_CHECKS
612 *37da2899SCharles.Forsyth     item->pair_size = 3;
613 *37da2899SCharles.Forsyth 
614 *37da2899SCharles.Forsyth     if ( item->flags & PFR_KERN_2BYTE_CHAR )
615 *37da2899SCharles.Forsyth       item->pair_size += 2;
616 *37da2899SCharles.Forsyth 
617 *37da2899SCharles.Forsyth     if ( item->flags & PFR_KERN_2BYTE_ADJ )
618 *37da2899SCharles.Forsyth       item->pair_size += 1;
619 *37da2899SCharles.Forsyth 
620 *37da2899SCharles.Forsyth     PFR_CHECK( item->pair_count * item->pair_size );
621 *37da2899SCharles.Forsyth #endif
622 *37da2899SCharles.Forsyth 
623 *37da2899SCharles.Forsyth     /* load first and last pairs into the item to speed up */
624 *37da2899SCharles.Forsyth     /* lookup later...                                     */
625 *37da2899SCharles.Forsyth     if ( item->pair_count > 0 )
626 *37da2899SCharles.Forsyth     {
627 *37da2899SCharles.Forsyth       FT_UInt   char1, char2;
628 *37da2899SCharles.Forsyth       FT_Byte*  q;
629 *37da2899SCharles.Forsyth 
630 *37da2899SCharles.Forsyth 
631 *37da2899SCharles.Forsyth       if ( item->flags & PFR_KERN_2BYTE_CHAR )
632 *37da2899SCharles.Forsyth       {
633 *37da2899SCharles.Forsyth         q     = p;
634 *37da2899SCharles.Forsyth         char1 = PFR_NEXT_USHORT( q );
635 *37da2899SCharles.Forsyth         char2 = PFR_NEXT_USHORT( q );
636 *37da2899SCharles.Forsyth 
637 *37da2899SCharles.Forsyth         item->pair1 = PFR_KERN_INDEX( char1, char2 );
638 *37da2899SCharles.Forsyth 
639 *37da2899SCharles.Forsyth         q = p + item->pair_size * ( item->pair_count - 1 );
640 *37da2899SCharles.Forsyth         char1 = PFR_NEXT_USHORT( q );
641 *37da2899SCharles.Forsyth         char2 = PFR_NEXT_USHORT( q );
642 *37da2899SCharles.Forsyth 
643 *37da2899SCharles.Forsyth         item->pair2 = PFR_KERN_INDEX( char1, char2 );
644 *37da2899SCharles.Forsyth       }
645 *37da2899SCharles.Forsyth       else
646 *37da2899SCharles.Forsyth       {
647 *37da2899SCharles.Forsyth         q     = p;
648 *37da2899SCharles.Forsyth         char1 = PFR_NEXT_BYTE( q );
649 *37da2899SCharles.Forsyth         char2 = PFR_NEXT_BYTE( q );
650 *37da2899SCharles.Forsyth 
651 *37da2899SCharles.Forsyth         item->pair1 = PFR_KERN_INDEX( char1, char2 );
652 *37da2899SCharles.Forsyth 
653 *37da2899SCharles.Forsyth         q = p + item->pair_size * ( item->pair_count - 1 );
654 *37da2899SCharles.Forsyth         char1 = PFR_NEXT_BYTE( q );
655 *37da2899SCharles.Forsyth         char2 = PFR_NEXT_BYTE( q );
656 *37da2899SCharles.Forsyth 
657 *37da2899SCharles.Forsyth         item->pair2 = PFR_KERN_INDEX( char1, char2 );
658 *37da2899SCharles.Forsyth       }
659 *37da2899SCharles.Forsyth 
660 *37da2899SCharles.Forsyth       /* add new item to the current list */
661 *37da2899SCharles.Forsyth       item->next                 = NULL;
662 *37da2899SCharles.Forsyth       *phy_font->kern_items_tail = item;
663 *37da2899SCharles.Forsyth       phy_font->kern_items_tail  = &item->next;
664 *37da2899SCharles.Forsyth       phy_font->num_kern_pairs  += item->pair_count;
665 *37da2899SCharles.Forsyth     }
666 *37da2899SCharles.Forsyth     else
667 *37da2899SCharles.Forsyth     {
668 *37da2899SCharles.Forsyth       /* empty item! */
669 *37da2899SCharles.Forsyth       FT_FREE( item );
670 *37da2899SCharles.Forsyth     }
671 *37da2899SCharles.Forsyth 
672 *37da2899SCharles.Forsyth   Exit:
673 *37da2899SCharles.Forsyth     return error;
674 *37da2899SCharles.Forsyth 
675 *37da2899SCharles.Forsyth   Too_Short:
676 *37da2899SCharles.Forsyth     FT_FREE( item );
677 *37da2899SCharles.Forsyth 
678 *37da2899SCharles.Forsyth     error = PFR_Err_Invalid_Table;
679 *37da2899SCharles.Forsyth     FT_ERROR(( "pfr_extra_item_load_kerning_pairs: "
680 *37da2899SCharles.Forsyth                "invalid kerning pairs table\n" ));
681 *37da2899SCharles.Forsyth     goto Exit;
682 *37da2899SCharles.Forsyth   }
683 *37da2899SCharles.Forsyth #endif /* 0 */
684 *37da2899SCharles.Forsyth 
685 *37da2899SCharles.Forsyth 
686 *37da2899SCharles.Forsyth   static const PFR_ExtraItemRec  pfr_phy_font_extra_items[] =
687 *37da2899SCharles.Forsyth   {
688 *37da2899SCharles.Forsyth     { 1, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_bitmap_info },
689 *37da2899SCharles.Forsyth     { 2, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_font_id },
690 *37da2899SCharles.Forsyth     { 3, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_stem_snaps },
691 *37da2899SCharles.Forsyth     { 4, (PFR_ExtraItem_ParseFunc) pfr_extra_item_load_kerning_pairs },
692 *37da2899SCharles.Forsyth     { 0, NULL }
693 *37da2899SCharles.Forsyth   };
694 *37da2899SCharles.Forsyth 
695 *37da2899SCharles.Forsyth 
696 *37da2899SCharles.Forsyth   FT_LOCAL_DEF( void )
pfr_phy_font_done(PFR_PhyFont phy_font,FT_Memory memory)697 *37da2899SCharles.Forsyth   pfr_phy_font_done( PFR_PhyFont  phy_font,
698 *37da2899SCharles.Forsyth                      FT_Memory    memory )
699 *37da2899SCharles.Forsyth   {
700 *37da2899SCharles.Forsyth     if ( phy_font->font_id )
701 *37da2899SCharles.Forsyth       FT_FREE( phy_font->font_id );
702 *37da2899SCharles.Forsyth 
703 *37da2899SCharles.Forsyth     FT_FREE( phy_font->vertical.stem_snaps );
704 *37da2899SCharles.Forsyth     phy_font->vertical.num_stem_snaps = 0;
705 *37da2899SCharles.Forsyth 
706 *37da2899SCharles.Forsyth     phy_font->horizontal.stem_snaps     = NULL;
707 *37da2899SCharles.Forsyth     phy_font->horizontal.num_stem_snaps = 0;
708 *37da2899SCharles.Forsyth 
709 *37da2899SCharles.Forsyth     FT_FREE( phy_font->strikes );
710 *37da2899SCharles.Forsyth     phy_font->num_strikes = 0;
711 *37da2899SCharles.Forsyth     phy_font->max_strikes = 0;
712 *37da2899SCharles.Forsyth 
713 *37da2899SCharles.Forsyth     FT_FREE( phy_font->chars );
714 *37da2899SCharles.Forsyth     phy_font->num_chars    = 0;
715 *37da2899SCharles.Forsyth     phy_font->chars_offset = 0;
716 *37da2899SCharles.Forsyth 
717 *37da2899SCharles.Forsyth     FT_FREE( phy_font->blue_values );
718 *37da2899SCharles.Forsyth     phy_font->num_blue_values = 0;
719 *37da2899SCharles.Forsyth 
720 *37da2899SCharles.Forsyth     {
721 *37da2899SCharles.Forsyth       PFR_KernItem  item, next;
722 *37da2899SCharles.Forsyth 
723 *37da2899SCharles.Forsyth 
724 *37da2899SCharles.Forsyth       item = phy_font->kern_items;
725 *37da2899SCharles.Forsyth       while ( item )
726 *37da2899SCharles.Forsyth       {
727 *37da2899SCharles.Forsyth         next = item->next;
728 *37da2899SCharles.Forsyth         FT_FREE( item );
729 *37da2899SCharles.Forsyth         item = next;
730 *37da2899SCharles.Forsyth       }
731 *37da2899SCharles.Forsyth       phy_font->kern_items      = NULL;
732 *37da2899SCharles.Forsyth       phy_font->kern_items_tail = NULL;
733 *37da2899SCharles.Forsyth     }
734 *37da2899SCharles.Forsyth 
735 *37da2899SCharles.Forsyth     phy_font->num_kern_pairs = 0;
736 *37da2899SCharles.Forsyth   }
737 *37da2899SCharles.Forsyth 
738 *37da2899SCharles.Forsyth 
739 *37da2899SCharles.Forsyth   FT_LOCAL_DEF( FT_Error )
pfr_phy_font_load(PFR_PhyFont phy_font,FT_Stream stream,FT_UInt32 offset,FT_UInt32 size)740 *37da2899SCharles.Forsyth   pfr_phy_font_load( PFR_PhyFont  phy_font,
741 *37da2899SCharles.Forsyth                      FT_Stream    stream,
742 *37da2899SCharles.Forsyth                      FT_UInt32    offset,
743 *37da2899SCharles.Forsyth                      FT_UInt32    size )
744 *37da2899SCharles.Forsyth   {
745 *37da2899SCharles.Forsyth     FT_Error   error;
746 *37da2899SCharles.Forsyth     FT_Memory  memory = stream->memory;
747 *37da2899SCharles.Forsyth     FT_UInt    flags, num_aux;
748 *37da2899SCharles.Forsyth     FT_Byte*   p;
749 *37da2899SCharles.Forsyth     FT_Byte*   limit;
750 *37da2899SCharles.Forsyth 
751 *37da2899SCharles.Forsyth 
752 *37da2899SCharles.Forsyth     phy_font->memory = memory;
753 *37da2899SCharles.Forsyth     phy_font->offset = offset;
754 *37da2899SCharles.Forsyth 
755 *37da2899SCharles.Forsyth     phy_font->kern_items      = NULL;
756 *37da2899SCharles.Forsyth     phy_font->kern_items_tail = &phy_font->kern_items;
757 *37da2899SCharles.Forsyth 
758 *37da2899SCharles.Forsyth     if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) )
759 *37da2899SCharles.Forsyth       goto Exit;
760 *37da2899SCharles.Forsyth 
761 *37da2899SCharles.Forsyth     phy_font->cursor = stream->cursor;
762 *37da2899SCharles.Forsyth 
763 *37da2899SCharles.Forsyth     p     = stream->cursor;
764 *37da2899SCharles.Forsyth     limit = p + size;
765 *37da2899SCharles.Forsyth 
766 *37da2899SCharles.Forsyth     PFR_CHECK( 15 );
767 *37da2899SCharles.Forsyth     phy_font->font_ref_number    = PFR_NEXT_USHORT( p );
768 *37da2899SCharles.Forsyth     phy_font->outline_resolution = PFR_NEXT_USHORT( p );
769 *37da2899SCharles.Forsyth     phy_font->metrics_resolution = PFR_NEXT_USHORT( p );
770 *37da2899SCharles.Forsyth     phy_font->bbox.xMin          = PFR_NEXT_SHORT( p );
771 *37da2899SCharles.Forsyth     phy_font->bbox.yMin          = PFR_NEXT_SHORT( p );
772 *37da2899SCharles.Forsyth     phy_font->bbox.xMax          = PFR_NEXT_SHORT( p );
773 *37da2899SCharles.Forsyth     phy_font->bbox.yMax          = PFR_NEXT_SHORT( p );
774 *37da2899SCharles.Forsyth     phy_font->flags      = flags = PFR_NEXT_BYTE( p );
775 *37da2899SCharles.Forsyth 
776 *37da2899SCharles.Forsyth     /* get the standard advance for non-proprotional fonts */
777 *37da2899SCharles.Forsyth     if ( !(flags & PFR_PHY_PROPORTIONAL) )
778 *37da2899SCharles.Forsyth     {
779 *37da2899SCharles.Forsyth       PFR_CHECK( 2 );
780 *37da2899SCharles.Forsyth       phy_font->standard_advance = PFR_NEXT_SHORT( p );
781 *37da2899SCharles.Forsyth     }
782 *37da2899SCharles.Forsyth 
783 *37da2899SCharles.Forsyth     /* load the extra items when present */
784 *37da2899SCharles.Forsyth     if ( flags & PFR_PHY_EXTRA_ITEMS )
785 *37da2899SCharles.Forsyth     {
786 *37da2899SCharles.Forsyth       error =  pfr_extra_items_parse( &p, limit,
787 *37da2899SCharles.Forsyth                                       pfr_phy_font_extra_items, phy_font );
788 *37da2899SCharles.Forsyth 
789 *37da2899SCharles.Forsyth       if ( error )
790 *37da2899SCharles.Forsyth         goto Fail;
791 *37da2899SCharles.Forsyth     }
792 *37da2899SCharles.Forsyth 
793 *37da2899SCharles.Forsyth     /* skip the aux bytes */
794 *37da2899SCharles.Forsyth     PFR_CHECK( 3 );
795 *37da2899SCharles.Forsyth     num_aux = PFR_NEXT_ULONG( p );
796 *37da2899SCharles.Forsyth 
797 *37da2899SCharles.Forsyth     PFR_CHECK( num_aux );
798 *37da2899SCharles.Forsyth     p += num_aux;
799 *37da2899SCharles.Forsyth 
800 *37da2899SCharles.Forsyth     /* read the blue values */
801 *37da2899SCharles.Forsyth     {
802 *37da2899SCharles.Forsyth       FT_UInt  n, count;
803 *37da2899SCharles.Forsyth 
804 *37da2899SCharles.Forsyth       PFR_CHECK( 1 );
805 *37da2899SCharles.Forsyth       phy_font->num_blue_values = count = PFR_NEXT_BYTE( p );
806 *37da2899SCharles.Forsyth 
807 *37da2899SCharles.Forsyth       PFR_CHECK( count * 2 );
808 *37da2899SCharles.Forsyth 
809 *37da2899SCharles.Forsyth       if ( FT_NEW_ARRAY( phy_font->blue_values, count ) )
810 *37da2899SCharles.Forsyth         goto Fail;
811 *37da2899SCharles.Forsyth 
812 *37da2899SCharles.Forsyth       for ( n = 0; n < count; n++ )
813 *37da2899SCharles.Forsyth         phy_font->blue_values[n] = PFR_NEXT_SHORT( p );
814 *37da2899SCharles.Forsyth     }
815 *37da2899SCharles.Forsyth 
816 *37da2899SCharles.Forsyth     PFR_CHECK( 8 );
817 *37da2899SCharles.Forsyth     phy_font->blue_fuzz  = PFR_NEXT_BYTE( p );
818 *37da2899SCharles.Forsyth     phy_font->blue_scale = PFR_NEXT_BYTE( p );
819 *37da2899SCharles.Forsyth 
820 *37da2899SCharles.Forsyth     phy_font->vertical.standard   = PFR_NEXT_USHORT( p );
821 *37da2899SCharles.Forsyth     phy_font->horizontal.standard = PFR_NEXT_USHORT( p );
822 *37da2899SCharles.Forsyth 
823 *37da2899SCharles.Forsyth     /* read the character descriptors */
824 *37da2899SCharles.Forsyth     {
825 *37da2899SCharles.Forsyth       FT_UInt  n, count, Size;
826 *37da2899SCharles.Forsyth 
827 *37da2899SCharles.Forsyth 
828 *37da2899SCharles.Forsyth       phy_font->num_chars    = count = PFR_NEXT_USHORT( p );
829 *37da2899SCharles.Forsyth       phy_font->chars_offset = offset + ( p - stream->cursor );
830 *37da2899SCharles.Forsyth 
831 *37da2899SCharles.Forsyth       if ( FT_NEW_ARRAY( phy_font->chars, count ) )
832 *37da2899SCharles.Forsyth         goto Fail;
833 *37da2899SCharles.Forsyth 
834 *37da2899SCharles.Forsyth       Size = 1 + 1 + 2;
835 *37da2899SCharles.Forsyth       if ( flags & PFR_PHY_2BYTE_CHARCODE )
836 *37da2899SCharles.Forsyth         Size += 1;
837 *37da2899SCharles.Forsyth 
838 *37da2899SCharles.Forsyth       if ( flags & PFR_PHY_PROPORTIONAL )
839 *37da2899SCharles.Forsyth         Size += 2;
840 *37da2899SCharles.Forsyth 
841 *37da2899SCharles.Forsyth       if ( flags & PFR_PHY_ASCII_CODE )
842 *37da2899SCharles.Forsyth         Size += 1;
843 *37da2899SCharles.Forsyth 
844 *37da2899SCharles.Forsyth       if ( flags & PFR_PHY_2BYTE_GPS_SIZE )
845 *37da2899SCharles.Forsyth         Size += 1;
846 *37da2899SCharles.Forsyth 
847 *37da2899SCharles.Forsyth       if ( flags & PFR_PHY_3BYTE_GPS_OFFSET )
848 *37da2899SCharles.Forsyth         Size += 1;
849 *37da2899SCharles.Forsyth 
850 *37da2899SCharles.Forsyth       PFR_CHECK( count * Size );
851 *37da2899SCharles.Forsyth 
852 *37da2899SCharles.Forsyth       for ( n = 0; n < count; n++ )
853 *37da2899SCharles.Forsyth       {
854 *37da2899SCharles.Forsyth         PFR_Char  cur = &phy_font->chars[n];
855 *37da2899SCharles.Forsyth 
856 *37da2899SCharles.Forsyth 
857 *37da2899SCharles.Forsyth         cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE )
858 *37da2899SCharles.Forsyth                          ? PFR_NEXT_USHORT( p )
859 *37da2899SCharles.Forsyth                          : PFR_NEXT_BYTE( p );
860 *37da2899SCharles.Forsyth 
861 *37da2899SCharles.Forsyth         cur->advance   = ( flags & PFR_PHY_PROPORTIONAL )
862 *37da2899SCharles.Forsyth                          ? PFR_NEXT_SHORT( p )
863 *37da2899SCharles.Forsyth                          : (FT_Int) phy_font->standard_advance;
864 *37da2899SCharles.Forsyth 
865 *37da2899SCharles.Forsyth #if 0
866 *37da2899SCharles.Forsyth         cur->ascii     = ( flags & PFR_PHY_ASCII_CODE )
867 *37da2899SCharles.Forsyth                          ? PFR_NEXT_BYTE( p )
868 *37da2899SCharles.Forsyth                          : 0;
869 *37da2899SCharles.Forsyth #else
870 *37da2899SCharles.Forsyth         if ( flags & PFR_PHY_ASCII_CODE )
871 *37da2899SCharles.Forsyth           p += 1;
872 *37da2899SCharles.Forsyth #endif
873 *37da2899SCharles.Forsyth         cur->gps_size  = ( flags & PFR_PHY_2BYTE_GPS_SIZE )
874 *37da2899SCharles.Forsyth                          ? PFR_NEXT_USHORT( p )
875 *37da2899SCharles.Forsyth                          : PFR_NEXT_BYTE( p );
876 *37da2899SCharles.Forsyth 
877 *37da2899SCharles.Forsyth         cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET )
878 *37da2899SCharles.Forsyth                           ? PFR_NEXT_ULONG( p )
879 *37da2899SCharles.Forsyth                           : PFR_NEXT_USHORT( p );
880 *37da2899SCharles.Forsyth       }
881 *37da2899SCharles.Forsyth     }
882 *37da2899SCharles.Forsyth 
883 *37da2899SCharles.Forsyth     /* that's it !! */
884 *37da2899SCharles.Forsyth   Fail:
885 *37da2899SCharles.Forsyth     FT_FRAME_EXIT();
886 *37da2899SCharles.Forsyth 
887 *37da2899SCharles.Forsyth     /* save position of bitmap info */
888 *37da2899SCharles.Forsyth     phy_font->bct_offset = FT_STREAM_POS();
889 *37da2899SCharles.Forsyth     phy_font->cursor     = NULL;
890 *37da2899SCharles.Forsyth 
891 *37da2899SCharles.Forsyth   Exit:
892 *37da2899SCharles.Forsyth     return error;
893 *37da2899SCharles.Forsyth 
894 *37da2899SCharles.Forsyth   Too_Short:
895 *37da2899SCharles.Forsyth     error = PFR_Err_Invalid_Table;
896 *37da2899SCharles.Forsyth     FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" ));
897 *37da2899SCharles.Forsyth     goto Fail;
898 *37da2899SCharles.Forsyth   }
899 *37da2899SCharles.Forsyth 
900 *37da2899SCharles.Forsyth 
901 *37da2899SCharles.Forsyth /* END */
902