~ubuntu-branches/ubuntu/wily/hedgewars/wily

« back to all changes in this revision

Viewing changes to misc/libfreetype/src/pfr/pfrload.c

  • Committer: Package Import Robot
  • Author(s): Dmitry E. Oboukhov
  • Date: 2011-09-23 10:16:55 UTC
  • mfrom: (1.2.11 upstream)
  • Revision ID: package-import@ubuntu.com-20110923101655-3977th2gc5n0a3pv
Tags: 0.9.16-1
* New upstream version.
 + Downloadable content! Simply click to install any content.
   New voices, hats, maps, themes, translations, music, scripts...
   Hedgewars is now more customisable than ever before! As time goes
   by we will be soliciting community content to feature on this page,
   so remember to check it from time to time. If you decide you want
   to go back to standard Hedgewars, just remove the Data directory
   from your Hedgewars config directory.
 + 3-D rendering! Diorama-like rendering of the game in a variety
   of 3D modes. Let us know which ones work best for you, we didn't
   really have the equipment to test them all.
 + Resizable game window.
 + New utilities! The Time Box will remove one of your hedgehogs
   from the game for a while, protecting from attack until it returns,
   somewhere else on the map. Land spray will allow you to build bridges,
   seal up holes, or just make life unpleasant for your enemies.
 + New single player: Bamboo Thicket, That Sinking Feeling, Newton and
   the Tree and multi-player: The Specialists, Space Invaders,
   Racer - scripts! And a ton more script hooks for scripters
 + New twists on old weapons. Drill strike, seduction and fire have
   been adjusted. Defective mines have been added, rope can attach to
   hogs/crates/barrels again, grenades now have variable bounce (use
   precise key + 1-5). Portal gun is now more usable in flight and
   all game actions are a lot faster.
 + New theme - Golf, dozens of new community hats and a new
   localised Default voice, Ukranian.

Show diffs side-by-side

added added

removed removed

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