/[freetype]/freetype2/src/sfnt/ttsbit0.c
ViewVC logotype

Diff of /freetype2/src/sfnt/ttsbit0.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by freetype, Mon Feb 28 22:09:07 2005 UTC revision 1.2 by wl, Tue Mar 1 02:13:50 2005 UTC
# Line 1  Line 1 
1  /***************************************************************************/  /***************************************************************************/
2  /*                                                                         */  /*                                                                         */
3  /*  ttsbit.c                                                               */  /*  ttsbit0.c                                                              */
4  /*                                                                         */  /*                                                                         */
5  /*    TrueType and OpenType embedded bitmap support (body).                */  /*    TrueType and OpenType embedded bitmap support (body).                */
6    /*    This is a heap-optimized version.                                    */
7  /*                                                                         */  /*                                                                         */
8  /*  Copyright 1996-2001, 2002, 2003, 2004 by                               */  /*  Copyright 2005 by                                                      */
9  /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */  /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
10  /*                                                                         */  /*                                                                         */
11  /*  This file is part of the FreeType project, and may only be used,       */  /*  This file is part of the FreeType project, and may only be used,       */
# Line 84  Line 85 
85      };      };
86    
87    
   
88    FT_LOCAL_DEF( FT_Error )    FT_LOCAL_DEF( FT_Error )
89    tt_face_load_sbit_strikes( TT_Face    face,    tt_face_load_sbit_strikes( TT_Face    face,
90                               FT_Stream  stream )                               FT_Stream  stream )
91    {    {
92      FT_Error   error  = 0;      FT_Error   error  = SFNT_Err_Ok;
93      FT_Memory  memory = stream->memory;      FT_Memory  memory = stream->memory;
94      FT_Fixed   version;      FT_Fixed   version;
95      FT_ULong   num_strikes, table_size;      FT_ULong   num_strikes, table_size;
# Line 98  Line 98 
98      FT_Byte*   p_limit;      FT_Byte*   p_limit;
99      FT_UInt    nn, count;      FT_UInt    nn, count;
100    
101    
102      face->sbit_num_strikes = 0;      face->sbit_num_strikes = 0;
103    
104      /* this table is optional */      /* this table is optional */
# Line 109  Line 110 
110    
111      if ( table_size < 8 )      if ( table_size < 8 )
112      {      {
113        FT_ERROR(( "%s: table too short !\n", "tt_face_load_sbit_strikes" ));        FT_ERROR(( "%s: table too short!\n", "tt_face_load_sbit_strikes" ));
114        error = SFNT_Err_Invalid_File_Format;        error = SFNT_Err_Invalid_File_Format;
115        goto Exit;        goto Exit;
116      }      }
# Line 122  Line 123 
123      p       = face->sbit_table;      p       = face->sbit_table;
124      p_limit = p + table_size;      p_limit = p + table_size;
125    
126      version     = FT_NEXT_ULONG(p);      version     = FT_NEXT_ULONG( p );
127      num_strikes = FT_NEXT_ULONG(p);      num_strikes = FT_NEXT_ULONG( p );
128    
129      if ( version != 0x00020000 || num_strikes >= 0x10000UL )      if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
130      {      {
131        FT_ERROR(( "%s: invalid table version !\n", "tt_face_load_sbit_strikes" ));        FT_ERROR(( "%s: invalid table version!\n",
132                     "tt_face_load_sbit_strikes" ));
133        error = SFNT_Err_Invalid_File_Format;        error = SFNT_Err_Invalid_File_Format;
134        goto Fail;        goto Fail;
135      }      }
136    
137     /* count the number of strikes available in the table. we're a bit      /*
138      * paranoid there and don't trust the data.       *  Count the number of strikes available in the table.  We are a bit
139      */       *  paranoid there and don't trust the data.
140         */
141      count = (FT_UInt)num_strikes;      count = (FT_UInt)num_strikes;
142      if ( 8+48UL*count > table_size )      if ( 8 +48UL * count > table_size )
143        count = (FT_UInt)( (p_limit - p)/48 );        count = (FT_UInt)( ( p_limit - p ) / 48 );
144    
145      face->sbit_num_strikes = count;      face->sbit_num_strikes = count;
146    
147     /* now allocate the root array of F_Bitmap_Size records,      /*
148      * populate them, and that's all there is to it. Unfortunately,       *  Now allocate the root array of FT_Bitmap_Size records and
149      * it's not possible to indicate bit depths in the FT_Bitmap_Size       *  populate them.  Unfortunately, it isn't possible to indicate bit
150      * record. What were we thinking ?       *  depths in the FT_Bitmap_Size record.  This is a design error.
151      */       */
152      {      {
153        FT_Memory  memory  = face->root.stream->memory;        FT_Memory  memory  = face->root.stream->memory;
154        FT_UInt    em_size = (FT_UInt) face->header.Units_Per_EM;        FT_UInt    em_size = (FT_UInt) face->header.Units_Per_EM;
# Line 155  Line 158 
158    
159        FT_Short   avgwidth = face->os2.xAvgCharWidth;        FT_Short   avgwidth = face->os2.xAvgCharWidth;
160    
161    
162        if ( FT_NEW_ARRAY( face->root.available_sizes, count ) )        if ( FT_NEW_ARRAY( face->root.available_sizes, count ) )
163          goto Fail;          goto Fail;
164    
# Line 163  Line 167 
167          FT_Bitmap_Size*  bsize = face->root.available_sizes + nn;          FT_Bitmap_Size*  bsize = face->root.available_sizes + nn;
168          FT_UInt          x_ppem, y_ppem;          FT_UInt          x_ppem, y_ppem;
169    
170    
171          x_ppem = p[44];          x_ppem = p[44];
172          y_ppem = p[45];          y_ppem = p[45];
173    
174          bsize->x_ppem = (FT_Pos)(x_ppem << 6);          bsize->x_ppem = (FT_Pos)(x_ppem << 6);
175          bsize->y_ppem = (FT_Pos)(y_ppem << 6);          bsize->y_ppem = (FT_Pos)(y_ppem << 6);
176    
177          bsize->height = (FT_Short)( height*y_ppem   + em_size/2 ) / em_size;          bsize->height = (FT_Short)( height*y_ppem   + em_size / 2 ) / em_size;
178          bsize->width  = (FT_Short)( avgwidth*y_ppem + em_size/2 ) / em_size;          bsize->width  = (FT_Short)( avgwidth*y_ppem + em_size / 2 ) / em_size;
179          bsize->size   = bsize->y_ppem;          bsize->size   = bsize->y_ppem;
180    
181          p += 48;          p += 48;
# Line 178  Line 183 
183    
184        face->root.face_flags     |= FT_FACE_FLAG_FIXED_SIZES;        face->root.face_flags     |= FT_FACE_FLAG_FIXED_SIZES;
185        face->root.num_fixed_sizes = count;        face->root.num_fixed_sizes = count;
   
186      }      }
187    
188    Exit:    Exit:
# Line 196  Line 200 
200    {    {
201      FT_Stream  stream = face->root.stream;      FT_Stream  stream = face->root.stream;
202    
203    
204      FT_FRAME_RELEASE( face->sbit_table );      FT_FRAME_RELEASE( face->sbit_table );
205      face->sbit_table_size  = 0;      face->sbit_table_size  = 0;
206      face->sbit_num_strikes = 0;      face->sbit_num_strikes = 0;
# Line 212  Line 217 
217      FT_Byte*  p;      FT_Byte*  p;
218      FT_Byte*  p_limit;      FT_Byte*  p_limit;
219    
220      if ( x_ppem > 255 ||  
221        if ( x_ppem > 255               ||
222           y_ppem < 1 || y_ppem > 255 )           y_ppem < 1 || y_ppem > 255 )
223        return SFNT_Err_Invalid_PPem;        return SFNT_Err_Invalid_PPem;
224    
225      p       = face->sbit_table + 8;      p       = face->sbit_table + 8;
226      p_limit = p + face->sbit_table_size;      p_limit = p + face->sbit_table_size;
227      count   = face->sbit_num_strikes;      count   = face->sbit_num_strikes;
228    
229      for ( nn = 0; nn < count; nn++ )      for ( nn = 0; nn < count; nn++ )
230      {      {
231        if ( x_ppem == (FT_UInt)p[44] && y_ppem == (FT_UInt)p[45] )        if ( x_ppem == (FT_UInt)p[44] && y_ppem == (FT_UInt)p[45] )
# Line 233  Line 240 
240    }    }
241    
242    
   
243    typedef struct    typedef struct
244    {    {
245      TT_Face          face;      TT_Face          face;
# Line 265  Line 271 
271      FT_Stream  stream     = face->root.stream;      FT_Stream  stream     = face->root.stream;
272      FT_ULong   ebdt_size;      FT_ULong   ebdt_size;
273    
274    
275      error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );      error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
276      if ( error )      if ( error )
277        error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );        error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
278      if (error)      if ( error )
279        goto Exit;        goto Exit;
280    
281      decoder->face       = face;      decoder->face    = face;
282      decoder->stream     = stream;      decoder->stream  = stream;
283      decoder->bitmap     = &face->root.glyph->bitmap;      decoder->bitmap  = &face->root.glyph->bitmap;
284      decoder->metrics    = metrics;      decoder->metrics = metrics;
285    
286      decoder->metrics_loaded   = 0;      decoder->metrics_loaded   = 0;
287      decoder->bitmap_allocated = 0;      decoder->bitmap_allocated = 0;
# Line 285  Line 292 
292      decoder->eblc_base  = face->sbit_table;      decoder->eblc_base  = face->sbit_table;
293      decoder->eblc_limit = face->sbit_table + face->sbit_table_size;      decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
294    
295     /* now find the strike corresponding to the index      /* now find the strike corresponding to the index */
     */  
296      {      {
297        FT_Byte*  p = decoder->eblc_base + 8 + 48*strike_index;        FT_Byte*  p = decoder->eblc_base + 8 + 48 * strike_index;
298    
299    
300        decoder->strike_index_array = FT_NEXT_ULONG(p);        decoder->strike_index_array = FT_NEXT_ULONG( p );
301        p                          += 4;        p                          += 4;
302        decoder->strike_index_count = FT_NEXT_ULONG(p);        decoder->strike_index_count = FT_NEXT_ULONG( p );
303        p                          += 34;        p                          += 34;
304        decoder->bit_depth          = *p;        decoder->bit_depth          = *p;
305      }      }
# Line 305  Line 312 
312    static void    static void
313    tt_sbit_decoder_done( TT_SBitDecoder  decoder )    tt_sbit_decoder_done( TT_SBitDecoder  decoder )
314    {    {
315      FT_UNUSED(decoder);      FT_UNUSED( decoder );
316    }    }
317    
318    
   
319    static FT_Error    static FT_Error
320    tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder  decoder )    tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder  decoder )
321    {    {
322      FT_Error    error = 0;      FT_Error    error = SFNT_Err_Ok;
323      FT_UInt     width, height;      FT_UInt     width, height;
324      FT_Bitmap*  map = decoder->bitmap;      FT_Bitmap*  map = decoder->bitmap;
325      FT_Long     size;      FT_Long     size;
326    
327    
328      if ( !decoder->metrics_loaded )      if ( !decoder->metrics_loaded )
329      {      {
330        error = FT_Err_Invalid_Argument;        error = SFNT_Err_Invalid_Argument;
331        goto Exit;        goto Exit;
332      }      }
333    
334      width  = decoder->metrics->width;      width  = decoder->metrics->width;
335      height = decoder->metrics->height;      height = decoder->metrics->height;
336    
337      map->width = (int) width;      map->width = (int)width;
338      map->rows  = (int) height;      map->rows  = (int)height;
339    
340      switch ( decoder->bit_depth )      switch ( decoder->bit_depth )
341      {      {
342      case 1:      case 1:
343          map->pixel_mode = FT_PIXEL_MODE_MONO;        map->pixel_mode = FT_PIXEL_MODE_MONO;
344          map->pitch      = ( map->width + 7 ) >> 3;        map->pitch      = ( map->width + 7 ) >> 3;
345          break;        break;
346    
347      case 2:      case 2:
348          map->pixel_mode = FT_PIXEL_MODE_GRAY2;        map->pixel_mode = FT_PIXEL_MODE_GRAY2;
349          map->pitch      = ( map->width + 3 ) >> 2;        map->pitch      = ( map->width + 3 ) >> 2;
350          break;        break;
351    
352      case 4:      case 4:
353          map->pixel_mode = FT_PIXEL_MODE_GRAY4;        map->pixel_mode = FT_PIXEL_MODE_GRAY4;
354          map->pitch      = ( map->width + 1 ) >> 1;        map->pitch      = ( map->width + 1 ) >> 1;
355          break;        break;
356    
357      case 8:      case 8:
358          map->pixel_mode = FT_PIXEL_MODE_GRAY;        map->pixel_mode = FT_PIXEL_MODE_GRAY;
359          map->pitch      = map->width;        map->pitch      = map->width;
360          break;        break;
361    
362      default:      default:
363        error = SFNT_Err_Invalid_File_Format;        error = SFNT_Err_Invalid_File_Format;
# Line 364  Line 371 
371        goto Exit;     /* exit successfully! */        goto Exit;     /* exit successfully! */
372    
373      error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );      error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
374      if (error)      if ( error )
375        goto Exit;        goto Exit;
376    
377      decoder->bitmap_allocated = 1;      decoder->bitmap_allocated = 1;
# Line 383  Line 390 
390      FT_Byte*         p       = *pp;      FT_Byte*         p       = *pp;
391      TT_SBit_Metrics  metrics = decoder->metrics;      TT_SBit_Metrics  metrics = decoder->metrics;
392    
393      if ( p+5 > limit )  
394        if ( p + 5 > limit )
395        goto Fail;        goto Fail;
396    
397      if ( !decoder->metrics_loaded )      if ( !decoder->metrics_loaded )
398      {      {
399        metrics->height       = p[0];        metrics->height       = p[0];
400        metrics->width        = p[1];        metrics->width        = p[1];
401        metrics->horiBearingX = (FT_Char) p[2];        metrics->horiBearingX = (FT_Char)p[2];
402        metrics->horiBearingY = (FT_Char) p[3];        metrics->horiBearingY = (FT_Char)p[3];
403        metrics->horiAdvance  = p[4];        metrics->horiAdvance  = p[4];
404      }      }
405    
406      p += 5;      p += 5;
407      if ( big )      if ( big )
408      {      {
409        if ( p+3 > limit )        if ( p + 3 > limit )
410          goto Fail;          goto Fail;
411    
412        if ( !decoder->metrics_loaded )        if ( !decoder->metrics_loaded )
413        {        {
414          metrics->vertBearingX = (FT_Char) p[0];          metrics->vertBearingX = (FT_Char)p[0];
415          metrics->vertBearingY = (FT_Char) p[1];          metrics->vertBearingY = (FT_Char)p[1];
416          metrics->vertAdvance  = p[2];          metrics->vertAdvance  = p[2];
417        }        }
418    
# Line 416  Line 424 
424      return 0;      return 0;
425    
426    Fail:    Fail:
427      return FT_Err_Invalid_Argument;      return SFNT_Err_Invalid_Argument;
428    }    }
429    
430    
431      /* forward declaration */
   
   
  /* forward declaration */  
432    static FT_Error    static FT_Error
433    tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,    tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
434                                FT_UInt         glyph_index,                                FT_UInt         glyph_index,
# Line 437  Line 442 
442                                                  FT_Int          y_pos );                                                  FT_Int          y_pos );
443    
444    
   
   
445    static FT_Error    static FT_Error
446    tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder  decoder,    tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder  decoder,
447                                       FT_Byte*        p,                                       FT_Byte*        p,
# Line 446  Line 449 
449                                       FT_Int          x_pos,                                       FT_Int          x_pos,
450                                       FT_Int          y_pos )                                       FT_Int          y_pos )
451    {    {
452      FT_Error    error = 0;      FT_Error    error = SFNT_Err_Ok;
453      FT_Byte*    line;      FT_Byte*    line;
454      FT_Int      bit_height, bit_width, pitch, width, height, h;      FT_Int      bit_height, bit_width, pitch, width, height, h;
455      FT_Bitmap*  bitmap;      FT_Bitmap*  bitmap;
456      FT_UInt     rval;      FT_UInt     rval;
457    
458    
459      if ( !decoder->bitmap_allocated )      if ( !decoder->bitmap_allocated )
460      {      {
461        error = tt_sbit_decoder_alloc_bitmap( decoder );        error = tt_sbit_decoder_alloc_bitmap( decoder );
462        if (error)        if ( error )
463          goto Exit;          goto Exit;
464      }      }
465    
466     /* check that we can write the glyph into the bitmap      /* check that we can write the glyph into the bitmap */
     */  
467      bitmap     = decoder->bitmap;      bitmap     = decoder->bitmap;
468      bit_width  = bitmap->width;      bit_width  = bitmap->width;
469      bit_height = bitmap->rows;      bit_height = bitmap->rows;
# Line 469  Line 472 
472      width  = decoder->metrics->width;      width  = decoder->metrics->width;
473      height = decoder->metrics->height;      height = decoder->metrics->height;
474    
475      if ( x_pos < 0 || x_pos+width > bit_width   ||      if ( x_pos < 0 || x_pos + width > bit_width   ||
476           y_pos < 0 || y_pos+height > bit_height )           y_pos < 0 || y_pos + height > bit_height )
477      {      {
478        error = FT_Err_Invalid_File_Format;        error = SFNT_Err_Invalid_File_Format;
479        goto Exit;        goto Exit;
480      }      }
481    
482      if ( p+((width+7)>>3)*height > limit )      if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
483      {      {
484        error = FT_Err_Invalid_File_Format;        error = SFNT_Err_Invalid_File_Format;
485        goto Exit;        goto Exit;
486      }      }
487    
488     /* now do the blit      /* now do the blit */
489      */      line  += y_pos * pitch + ( x_pos >> 3 );
     line  += y_pos*pitch + (x_pos >> 3);  
490      x_pos &= 7;      x_pos &= 7;
491    
492      if ( x_pos == 0 )  /* the easy one */      if ( x_pos == 0 )  /* the easy one */
# Line 494  Line 496 
496          FT_Byte*  write = line;          FT_Byte*  write = line;
497          FT_Int    w;          FT_Int    w;
498    
499    
500          for ( w = width; w >= 8; w -= 8 )          for ( w = width; w >= 8; w -= 8 )
501          {          {
502            write[0] = (FT_Byte)(write[0] | *p++);            write[0] = (FT_Byte)( write[0] | *p++ );
503            write   += 1;            write   += 1;
504          }          }
505    
506          if ( w > 0 )          if ( w > 0 )
507            write[0] = (FT_Byte)(write[0] | (*p++ & (0xFF00 >> w)));            write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );
508        }        }
509      }      }
510      else  /* x_pos > 0 */      else  /* x_pos > 0 */
# Line 512  Line 515 
515          FT_Int    w;          FT_Int    w;
516          FT_UInt   wval = 0;          FT_UInt   wval = 0;
517    
518    
519          for ( w = width; w >= 8; w -= 8 )          for ( w = width; w >= 8; w -= 8 )
520          {          {
521            wval      = (FT_UInt)(wval | *p++);            wval      = (FT_UInt)( wval | *p++ );
522            write[0]  = (FT_Byte)(write[0] | (wval >> x_pos));            write[0]  = (FT_Byte)( write[0] | ( wval >> x_pos ) );
523            write    += 1;            write    += 1;
524            wval    <<= 8;            wval    <<= 8;
525          }          }
526    
527          if ( w > 0 )          if ( w > 0 )
528            wval = (FT_UInt)(wval | (*p++ & (0xFF00 >> w)));            wval = (FT_UInt)(wval | ( *p++ & ( 0xFF00U >> w ) ) );
529    
530          write[0] = (FT_Byte)(write[0] | (wval >> x_pos));          write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
531        }        }
532      }      }
533    
# Line 539  Line 543 
543                                       FT_Int          x_pos,                                       FT_Int          x_pos,
544                                       FT_Int          y_pos )                                       FT_Int          y_pos )
545    {    {
546      FT_Error    error = 0;      FT_Error    error = SFNT_Err_Ok;
547      FT_Byte*    line;      FT_Byte*    line;
548      FT_Int      bit_height, bit_width, pitch, width, height, h;      FT_Int      bit_height, bit_width, pitch, width, height, h;
549      FT_Bitmap*  bitmap;      FT_Bitmap*  bitmap;
550      FT_UInt32   rval;      FT_UInt32   rval;
551    
552    
553      if ( !decoder->bitmap_allocated )      if ( !decoder->bitmap_allocated )
554      {      {
555        error = tt_sbit_decoder_alloc_bitmap( decoder );        error = tt_sbit_decoder_alloc_bitmap( decoder );
556        if (error)        if ( error )
557          goto Exit;          goto Exit;
558      }      }
559    
560     /* check that we can write the glyph into the bitmap      /* check that we can write the glyph into the bitmap */
     */  
561      bitmap     = decoder->bitmap;      bitmap     = decoder->bitmap;
562      bit_width  = bitmap->width;      bit_width  = bitmap->width;
563      bit_height = bitmap->rows;      bit_height = bitmap->rows;
# Line 562  Line 566 
566      width  = decoder->metrics->width;      width  = decoder->metrics->width;
567      height = decoder->metrics->height;      height = decoder->metrics->height;
568    
569      if ( x_pos < 0 || x_pos+width  > bit_width  ||      if ( x_pos < 0 || x_pos + width  > bit_width  ||
570           y_pos < 0 || y_pos+height > bit_height )           y_pos < 0 || y_pos + height > bit_height )
571      {      {
572        error = FT_Err_Invalid_File_Format;        error = SFNT_Err_Invalid_File_Format;
573        goto Exit;        goto Exit;
574      }      }
575    
576      if ( p+((width+7)>>3)*height > limit )      if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
577      {      {
578        error = FT_Err_Invalid_File_Format;        error = SFNT_Err_Invalid_File_Format;
579        goto Exit;        goto Exit;
580      }      }
581    
582     /* now do the blit      /* now do the blit */
583      */      line  += y_pos * pitch + ( x_pos >> 3 );
     line  += y_pos*pitch + (x_pos >> 3);  
584      x_pos &= 7;      x_pos &= 7;
585      rval   = 0x10000;      rval   = 0x10000UL;
586    
587      for ( h = height; h > 0; h--, line += pitch )      for ( h = height; h > 0; h--, line += pitch )
588      {      {
# Line 587  Line 590 
590        FT_UInt32  wval  = 0x100 << x_pos;        FT_UInt32  wval  = 0x100 << x_pos;
591        FT_Int     w;        FT_Int     w;
592    
593    
594        for ( w = width; w >= 8; w -= 8 )        for ( w = width; w >= 8; w -= 8 )
595        {        {
596          if ( rval & 0x10000 )          if ( rval & 0x10000UL )
597            rval = 0x100 | *p++;            rval = 0x100 | *p++;
598    
599          wval |= (rval & 0x80);          wval |= rval & 0x80;
600    
601          wval <<= 1;          wval <<= 1;
602          rval <<= 1;          rval <<= 1;
603    
604          if ( wval & 0x10000 )          if ( wval & 0x10000UL )
605          {          {
606            write[0] = (FT_Byte)(write[0] | (wval >> 8));            write[0] = (FT_Byte)( write[0] | ( wval >> 8 ) );
607            write   += 1;            write   += 1;
608            wval     = 0x100;            wval     = 0x100;
609          }          }
# Line 610  Line 614 
614          while ( wval > 0x1FF )          while ( wval > 0x1FF )
615            wval >>= 1;            wval >>= 1;
616    
617          write[0] = (FT_Byte)(write[0] | wval);          write[0] = (FT_Byte)( write[0] | wval );
618        }        }
619      }      }
620    
# Line 630  Line 634 
634      FT_UInt   num_components, nn;      FT_UInt   num_components, nn;
635    
636    
637      if ( p+2 > limit )      if ( p + 2 > limit )
638        goto Fail;        goto Fail;
639    
640      num_components = FT_NEXT_USHORT(p);      num_components = FT_NEXT_USHORT( p );
641      if ( p+4*num_components > limit )      if ( p + 4 * num_components > limit )
642        goto Fail;        goto Fail;
643    
644      for ( nn = 0; nn < num_components; nn++ )      for ( nn = 0; nn < num_components; nn++ )
645      {      {
646        FT_UInt   gindex = FT_NEXT_USHORT(p);        FT_UInt   gindex = FT_NEXT_USHORT( p );
647        FT_Byte   dx     = FT_NEXT_BYTE(p);        FT_Byte   dx     = FT_NEXT_BYTE( p );
648        FT_Byte   dy     = FT_NEXT_BYTE(p);        FT_Byte   dy     = FT_NEXT_BYTE( p );
649    
650    
651        /* NB: a recursive call */        /* NB: a recursive call */
652        error = tt_sbit_decoder_load_image( decoder, gindex, x_pos+dx, y_pos+dy );        error = tt_sbit_decoder_load_image( decoder, gindex,
653                                              x_pos + dx, y_pos + dy );
654        if ( error )        if ( error )
655          break;          break;
656      }      }
# Line 653  Line 659 
659      return error;      return error;
660    
661    Fail:    Fail:
662      error = FT_Err_Invalid_File_Format;      error = SFNT_Err_Invalid_File_Format;
663      goto Exit;      goto Exit;
664    }    }
665    
# Line 672  Line 678 
678      FT_Byte*   p_limit;      FT_Byte*   p_limit;
679      FT_Byte*   data;      FT_Byte*   data;
680    
681     /* seek into the EBDT table now  
682      */      /* seek into the EBDT table now */
683      if ( glyph_start + glyph_size > decoder->ebdt_size )      if ( glyph_start + glyph_size > decoder->ebdt_size )
684      {      {
685        error = FT_Err_Invalid_Argument;        error = SFNT_Err_Invalid_Argument;
686        goto Exit;        goto Exit;
687      }      }
688    
689      if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||      if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
690           FT_FRAME_EXTRACT( glyph_size, data )                 )           FT_FRAME_EXTRACT( glyph_size, data )                )
691        goto Exit;        goto Exit;
692    
693      p       = data;      p       = data;
694      p_limit = p + glyph_size;      p_limit = p + glyph_size;
695    
696     /* read the data, depending on the glyph format      /* read the data, depending on the glyph format */
     */  
697      switch ( glyph_format )      switch ( glyph_format )
698      {      {
699      case 1: case 2: case 8:      case 1:
700        case 2:
701        case 8:
702        error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );        error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
703        break;        break;
704    
705      case 6: case 7: case 9:      case 6:
706        case 7:
707        case 9:
708        error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );        error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
709        break;        break;
710    
711      default:      default:
712        error = 0;        error = SFNT_Err_Ok;
713      }      }
714    
715      if ( error )      if ( error )
# Line 709  Line 718 
718      {      {
719        TT_SBitDecoder_LoadFunc  loader;        TT_SBitDecoder_LoadFunc  loader;
720    
721    
722        switch ( glyph_format )        switch ( glyph_format )
723        {        {
724        case 1: case 6:        case 1:
725            loader = tt_sbit_decoder_load_byte_aligned;        case 6:
726            break;          loader = tt_sbit_decoder_load_byte_aligned;
727            break;
728        case 2: case 5: case 7:  
729            loader = tt_sbit_decoder_load_bit_aligned;        case 2:
730            break;        case 5:
731          case 7:
732            loader = tt_sbit_decoder_load_bit_aligned;
733            break;
734    
735        case 8:        case 8:
736            if ( p+1 > p_limit )          if ( p + 1 > p_limit )
737              goto Fail;            goto Fail;
738    
739            p += 1;  /* skip padding */          p += 1;  /* skip padding */
740            /* fall-through */          /* fall-through */
741    
742        case 9:        case 9:
743            loader = tt_sbit_decoder_load_compound;          loader = tt_sbit_decoder_load_compound;
744            break;          break;
745    
746        default:        default:
747            goto Fail;          goto Fail;
748        }        }
749    
750        error = loader( decoder, p, p_limit, x_pos, y_pos );        error = loader( decoder, p, p_limit, x_pos, y_pos );
# Line 751  Line 764 
764                                FT_Int          x_pos,                                FT_Int          x_pos,
765                                FT_Int          y_pos )                                FT_Int          y_pos )
766    {    {
767     /* first, we find the correct strike range that applies to this      /*
768      * glyph index.       *  First, we find the correct strike range that applies to this
769      */       *  glyph index.
770         */
771    
772      FT_Byte*  p          = decoder->eblc_base + decoder->strike_index_array;      FT_Byte*  p          = decoder->eblc_base + decoder->strike_index_array;
773      FT_Byte*  p_limit    = decoder->eblc_limit;      FT_Byte*  p_limit    = decoder->eblc_limit;
774      FT_ULong  num_ranges = decoder->strike_index_count;      FT_ULong  num_ranges = decoder->strike_index_count;
775      FT_UInt   start, end, offset, index_format, image_format;      FT_UInt   start, end, offset, index_format, image_format;
776      FT_ULong  image_start, image_end, image_offset;      FT_ULong  image_start, image_end, image_offset;
777    
778      if ( p+8*num_ranges > p_limit )  
779        if ( p + 8 * num_ranges > p_limit )
780        goto NoBitmap;        goto NoBitmap;
781    
782      for ( ; num_ranges > 0; num_ranges-- )      for ( ; num_ranges > 0; num_ranges-- )
783      {      {
784        start = FT_NEXT_USHORT(p);        start = FT_NEXT_USHORT( p );
785        end   = FT_NEXT_USHORT(p);        end   = FT_NEXT_USHORT( p );
786    
787        if ( glyph_index >= start && glyph_index <= end )        if ( glyph_index >= start && glyph_index <= end )
788          goto FoundRange;          goto FoundRange;
# Line 776  Line 792 
792      goto NoBitmap;      goto NoBitmap;
793    
794    FoundRange:    FoundRange:
795      p = decoder->eblc_base + decoder->strike_index_array + FT_NEXT_ULONG(p);      p = decoder->eblc_base + decoder->strike_index_array + FT_NEXT_ULONG( p );
796      if ( p+8 > p_limit )      if ( p + 8 > p_limit )
797        goto NoBitmap;        goto NoBitmap;
798    
799     /* now, we're going to find the glyph's location and extend within      /* now find the glyph's location and extend within the ebdt table */
800      * the ebdt table      index_format = FT_NEXT_USHORT( p );
801      */      image_format = FT_NEXT_USHORT( p );
802      index_format = FT_NEXT_USHORT(p);      image_offset = FT_NEXT_ULONG ( p );
     image_format = FT_NEXT_USHORT(p);  
     image_offset = FT_NEXT_ULONG(p);  
803    
804      switch ( index_format )      switch ( index_format )
805      {      {
806      case 1: /* 4-byte offsets relative to 'image_offset' */      case 1: /* 4-byte offsets relative to `image_offset' */
807          {        {
808            p += 4*(glyph_index-start);          p += 4 * ( glyph_index - start );
809            if ( p+8 > p_limit )          if ( p + 8 > p_limit )
810              goto NoBitmap;            goto NoBitmap;
811    
812            image_start = FT_NEXT_ULONG(p);          image_start = FT_NEXT_ULONG( p );
813            image_end   = FT_NEXT_ULONG(p);          image_end   = FT_NEXT_ULONG( p );
814    
815            if ( image_start == image_end )  /* missing glyph */          if ( image_start == image_end )  /* missing glyph */
816              goto NoBitmap;            goto NoBitmap;
817          }        }
818          break;        break;
819    
820      case 2: /* big metrics, constant image size */      case 2: /* big metrics, constant image size */
821          {        {
822            FT_ULong  image_size;          FT_ULong  image_size;
823    
           if ( p+12 > p_limit )  
             goto NoBitmap;  
824    
825            image_size = FT_NEXT_ULONG(p);          if ( p + 12 > p_limit )
826              goto NoBitmap;
827    
828            if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )          image_size = FT_NEXT_ULONG( p );
             goto NoBitmap;  
829    
830            image_start = image_offset + image_size*(glyph_index-start);          if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
831            image_end   = image_start  + image_size;            goto NoBitmap;
832          }  
833          break;          image_start = image_offset + image_size * ( glyph_index - start );
834            image_end   = image_start  + image_size;
835          }
836          break;
837    
838      case 3: /* 2-byte offsets relative to 'image_offset' */      case 3: /* 2-byte offsets relative to 'image_offset' */
839          {        {
840            p += 2*(glyph_index-start);          p += 2 * ( glyph_index - start );
841            if ( p+4 > p_limit )          if ( p + 4 > p_limit )
842              goto NoBitmap;            goto NoBitmap;
843    
844            image_start = FT_NEXT_USHORT(p);          image_start = FT_NEXT_USHORT( p );
845            image_end   = FT_NEXT_USHORT(p);          image_end   = FT_NEXT_USHORT( p );
846    
847            if ( image_start == image_end )  /* missing glyph */          if ( image_start == image_end )  /* missing glyph */
848              goto NoBitmap;            goto NoBitmap;
849          }        }
850          break;        break;
851    
852      case 4: /* sparse glyph array with (glyph,offset) pairs */      case 4: /* sparse glyph array with (glyph,offset) pairs */
853          {        {
854            FT_ULong  mm, num_glyphs;          FT_ULong  mm, num_glyphs;
855    
           if ( p+4 > p_limit )  
             goto NoBitmap;  
856    
857            num_glyphs = FT_NEXT_ULONG(p);          if ( p + 4 > p_limit )
858            if ( p+(num_glyphs+1)*4 > p_limit )            goto NoBitmap;
             goto NoBitmap;  
859    
860            for ( mm = 0; mm < num_glyphs; mm++ )          num_glyphs = FT_NEXT_ULONG( p );
861            {          if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
862              FT_UInt  gindex = FT_NEXT_USHORT(p);            goto NoBitmap;
863    
864            for ( mm = 0; mm < num_glyphs; mm++ )
865            {
866              FT_UInt  gindex = FT_NEXT_USHORT( p );
867    
             if ( gindex == glyph_index )  
             {  
               image_start = FT_NEXT_USHORT(p);  
               p          += 2;  
               image_end   = FT_PEEK_USHORT(p);  
               break;  
             }  
             p += 2;  
           }  
868    
869            if ( mm >= num_glyphs )            if ( gindex == glyph_index )
870              goto NoBitmap;            {
871                image_start = FT_NEXT_USHORT( p );
872                p          += 2;
873                image_end   = FT_PEEK_USHORT( p );
874                break;
875              }
876              p += 2;
877          }          }
878          break;  
879            if ( mm >= num_glyphs )
880              goto NoBitmap;
881          }
882          break;
883    
884      case 5: /* constant metrics with sparse glyph codes */      case 5: /* constant metrics with sparse glyph codes */
885          {        {
886            FT_ULong  image_size, mm, num_glyphs;          FT_ULong  image_size, mm, num_glyphs;
887    
           if ( p+16 > p_limit )  
             goto NoBitmap;  
888    
889            image_size = FT_NEXT_ULONG(p);          if ( p + 16 > p_limit )
890              goto NoBitmap;
891    
892            if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )          image_size = FT_NEXT_ULONG( p );
             goto NoBitmap;  
893    
894            num_glyphs = FT_NEXT_ULONG(p);          if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
895            if ( p + 2*num_glyphs > p_limit )            goto NoBitmap;
             goto NoBitmap;  
896    
897            for ( mm = 0; mm < num_glyphs; mm++ )          num_glyphs = FT_NEXT_ULONG( p );
898            {          if ( p + 2 * num_glyphs > p_limit )
899              FT_UInt  gindex = FT_NEXT_USHORT(p);            goto NoBitmap;
900    
901              if ( gindex == glyph_index )          for ( mm = 0; mm < num_glyphs; mm++ )
902                break;          {
903            }            FT_UInt  gindex = FT_NEXT_USHORT( p );
904    
           if ( mm >= num_glyphs )  
             goto NoBitmap;  
905    
906            image_start = image_offset + image_size*mm;            if ( gindex == glyph_index )
907            image_end   = image_start + image_size;              break;
908          }          }
909          break;  
910            if ( mm >= num_glyphs )
911              goto NoBitmap;
912    
913            image_start = image_offset + image_size*mm;
914            image_end   = image_start + image_size;
915          }
916          break;
917    
918      default:      default:
919          goto NoBitmap;        goto NoBitmap;
920      }      }
921    
922      if ( image_start > image_end )      if ( image_start > image_end )
# Line 906  Line 925 
925      image_end  -= image_start;      image_end  -= image_start;
926      image_start = image_offset + image_start;      image_start = image_offset + image_start;
927    
   
928      return tt_sbit_decoder_load_bitmap( decoder,      return tt_sbit_decoder_load_bitmap( decoder,
929                                          image_format,                                          image_format,
930                                          image_offset + image_start,                                          image_offset + image_start,
931                                          image_end,                                          image_end,
932                                          x_pos,                                          x_pos,
933                                          y_pos );                                          y_pos );
934    
935    NoBitmap:    NoBitmap:
936      return FT_Err_Invalid_Argument;      return SFNT_Err_Invalid_Argument;
937    }    }
938    
939    
   
   
940    FT_LOCAL( FT_Error )    FT_LOCAL( FT_Error )
941    tt_face_load_sbit_image( TT_Face              face,    tt_face_load_sbit_image( TT_Face              face,
942                             FT_ULong             strike_index,                             FT_ULong             strike_index,
# Line 932  Line 949 
949      TT_SBitDecoderRec  decoder[1];      TT_SBitDecoderRec  decoder[1];
950      FT_Error           error;      FT_Error           error;
951    
952    
953      error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );      error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
954      if ( !error )      if ( !error )
955      {      {
# Line 941  Line 959 
959    
960      return error;      return error;
961    }    }
962    
963    /* EOF */

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26