ttsbit0.c
上传用户:yisoukefu
上传日期:2020-08-09
资源大小:39506k
文件大小:25k
源码类别:

其他游戏

开发平台:

Visual C++

  1. /***************************************************************************/
  2. /*                                                                         */
  3. /*  ttsbit0.c                                                              */
  4. /*                                                                         */
  5. /*    TrueType and OpenType embedded bitmap support (body).                */
  6. /*    This is a heap-optimized version.                                    */
  7. /*                                                                         */
  8. /*  Copyright 2005, 2006, 2007 by                                          */
  9. /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
  10. /*                                                                         */
  11. /*  This file is part of the FreeType project, and may only be used,       */
  12. /*  modified, and distributed under the terms of the FreeType project      */
  13. /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
  14. /*  this file you indicate that you have read the license and              */
  15. /*  understand and accept it fully.                                        */
  16. /*                                                                         */
  17. /***************************************************************************/
  18. /* This file is included by ttsbit.c */
  19. #include <ft2build.h>
  20. #include FT_INTERNAL_DEBUG_H
  21. #include FT_INTERNAL_STREAM_H
  22. #include FT_TRUETYPE_TAGS_H
  23. #include "ttsbit.h"
  24. #include "sferrors.h"
  25.   /*************************************************************************/
  26.   /*                                                                       */
  27.   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
  28.   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
  29.   /* messages during execution.                                            */
  30.   /*                                                                       */
  31. #undef  FT_COMPONENT
  32. #define FT_COMPONENT  trace_ttsbit
  33.     static const FT_Frame_Field  tt_sbit_line_metrics_fields[] =
  34.     {
  35. #undef  FT_STRUCTURE
  36. #define FT_STRUCTURE  TT_SBit_LineMetricsRec
  37.       /* no FT_FRAME_START */
  38.         FT_FRAME_CHAR( ascender ),
  39.         FT_FRAME_CHAR( descender ),
  40.         FT_FRAME_BYTE( max_width ),
  41.         FT_FRAME_CHAR( caret_slope_numerator ),
  42.         FT_FRAME_CHAR( caret_slope_denominator ),
  43.         FT_FRAME_CHAR( caret_offset ),
  44.         FT_FRAME_CHAR( min_origin_SB ),
  45.         FT_FRAME_CHAR( min_advance_SB ),
  46.         FT_FRAME_CHAR( max_before_BL ),
  47.         FT_FRAME_CHAR( min_after_BL ),
  48.         FT_FRAME_CHAR( pads[0] ),
  49.         FT_FRAME_CHAR( pads[1] ),
  50.       FT_FRAME_END
  51.     };
  52.     static const FT_Frame_Field  tt_strike_start_fields[] =
  53.     {
  54. #undef  FT_STRUCTURE
  55. #define FT_STRUCTURE  TT_SBit_StrikeRec
  56.       /* no FT_FRAME_START */
  57.         FT_FRAME_ULONG( ranges_offset ),
  58.         FT_FRAME_SKIP_LONG,
  59.         FT_FRAME_ULONG( num_ranges ),
  60.         FT_FRAME_ULONG( color_ref ),
  61.       FT_FRAME_END
  62.     };
  63.     static const FT_Frame_Field  tt_strike_end_fields[] =
  64.     {
  65.       /* no FT_FRAME_START */
  66.         FT_FRAME_USHORT( start_glyph ),
  67.         FT_FRAME_USHORT( end_glyph ),
  68.         FT_FRAME_BYTE  ( x_ppem ),
  69.         FT_FRAME_BYTE  ( y_ppem ),
  70.         FT_FRAME_BYTE  ( bit_depth ),
  71.         FT_FRAME_CHAR  ( flags ),
  72.       FT_FRAME_END
  73.     };
  74.   FT_LOCAL_DEF( FT_Error )
  75.   tt_face_load_eblc( TT_Face    face,
  76.                      FT_Stream  stream )
  77.   {
  78.     FT_Error   error  = SFNT_Err_Ok;
  79.     FT_Fixed   version;
  80.     FT_ULong   num_strikes, table_size;
  81.     FT_Byte*   p;
  82.     FT_Byte*   p_limit;
  83.     FT_UInt    count;
  84.     face->sbit_num_strikes = 0;
  85.     /* this table is optional */
  86.     error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
  87.     if ( error )
  88.       error = face->goto_table( face, TTAG_bloc, stream, &table_size );
  89.     if ( error )
  90.       goto Exit;
  91.     if ( table_size < 8 )
  92.     {
  93.       FT_ERROR(( "%s: table too short!n", "tt_face_load_sbit_strikes" ));
  94.       error = SFNT_Err_Invalid_File_Format;
  95.       goto Exit;
  96.     }
  97.     if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
  98.       goto Exit;
  99.     face->sbit_table_size = table_size;
  100.     p       = face->sbit_table;
  101.     p_limit = p + table_size;
  102.     version     = FT_NEXT_ULONG( p );
  103.     num_strikes = FT_NEXT_ULONG( p );
  104.     if ( version != 0x00020000UL || num_strikes >= 0x10000UL )
  105.     {
  106.       FT_ERROR(( "%s: invalid table version!n",
  107.                  "tt_face_load_sbit_strikes" ));
  108.       error = SFNT_Err_Invalid_File_Format;
  109.       goto Fail;
  110.     }
  111.     /*
  112.      *  Count the number of strikes available in the table.  We are a bit
  113.      *  paranoid there and don't trust the data.
  114.      */
  115.     count = (FT_UInt)num_strikes;
  116.     if ( 8 + 48UL * count > table_size )
  117.       count = (FT_UInt)( ( p_limit - p ) / 48 );
  118.     face->sbit_num_strikes = count;
  119.     FT_TRACE3(( "sbit_num_strikes: %un", count ));
  120.   Exit:
  121.     return error;
  122.   Fail:
  123.     FT_FRAME_RELEASE( face->sbit_table );
  124.     face->sbit_table_size = 0;
  125.     goto Exit;
  126.   }
  127.   FT_LOCAL_DEF( void )
  128.   tt_face_free_eblc( TT_Face  face )
  129.   {
  130.     FT_Stream  stream = face->root.stream;
  131.     FT_FRAME_RELEASE( face->sbit_table );
  132.     face->sbit_table_size  = 0;
  133.     face->sbit_num_strikes = 0;
  134.   }
  135.   FT_LOCAL_DEF( FT_Error )
  136.   tt_face_set_sbit_strike( TT_Face          face,
  137.                            FT_Size_Request  req,
  138.                            FT_ULong*        astrike_index )
  139.   {
  140.     return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
  141.   }
  142.   FT_LOCAL_DEF( FT_Error )
  143.   tt_face_load_strike_metrics( TT_Face           face,
  144.                                FT_ULong          strike_index,
  145.                                FT_Size_Metrics*  metrics )
  146.   {
  147.     FT_Byte*         strike;
  148.     if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
  149.       return SFNT_Err_Invalid_Argument;
  150.     strike = face->sbit_table + 8 + strike_index * 48;
  151.     metrics->x_ppem = (FT_UShort)strike[44];
  152.     metrics->y_ppem = (FT_UShort)strike[45];
  153.     metrics->ascender  = (FT_Char)strike[16] << 6;  /* hori.ascender  */
  154.     metrics->descender = (FT_Char)strike[17] << 6;  /* hori.descender */
  155.     metrics->height    = metrics->ascender - metrics->descender;
  156.     /* XXX: Is this correct? */
  157.     metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB  */
  158.                                       strike[18] + /* max_width      */
  159.                              (FT_Char)strike[23]   /* min_advance_SB */
  160.                                                  ) << 6;
  161.     return SFNT_Err_Ok;
  162.   }
  163.   typedef struct
  164.   {
  165.     TT_Face          face;
  166.     FT_Stream        stream;
  167.     FT_Bitmap*       bitmap;
  168.     TT_SBit_Metrics  metrics;
  169.     FT_Bool          metrics_loaded;
  170.     FT_Bool          bitmap_allocated;
  171.     FT_Byte          bit_depth;
  172.     FT_ULong         ebdt_start;
  173.     FT_ULong         ebdt_size;
  174.     FT_ULong         strike_index_array;
  175.     FT_ULong         strike_index_count;
  176.     FT_Byte*         eblc_base;
  177.     FT_Byte*         eblc_limit;
  178.   } TT_SBitDecoderRec, *TT_SBitDecoder;
  179.   static FT_Error
  180.   tt_sbit_decoder_init( TT_SBitDecoder       decoder,
  181.                         TT_Face              face,
  182.                         FT_ULong             strike_index,
  183.                         TT_SBit_MetricsRec*  metrics )
  184.   {
  185.     FT_Error   error;
  186.     FT_Stream  stream = face->root.stream;
  187.     FT_ULong   ebdt_size;
  188.     error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
  189.     if ( error )
  190.       error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
  191.     if ( error )
  192.       goto Exit;
  193.     decoder->face    = face;
  194.     decoder->stream  = stream;
  195.     decoder->bitmap  = &face->root.glyph->bitmap;
  196.     decoder->metrics = metrics;
  197.     decoder->metrics_loaded   = 0;
  198.     decoder->bitmap_allocated = 0;
  199.     decoder->ebdt_start = FT_STREAM_POS();
  200.     decoder->ebdt_size  = ebdt_size;
  201.     decoder->eblc_base  = face->sbit_table;
  202.     decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
  203.     /* now find the strike corresponding to the index */
  204.     {
  205.       FT_Byte*  p;
  206.       if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
  207.       {
  208.         error = SFNT_Err_Invalid_File_Format;
  209.         goto Exit;
  210.       }
  211.       p = decoder->eblc_base + 8 + 48 * strike_index;
  212.       decoder->strike_index_array = FT_NEXT_ULONG( p );
  213.       p                          += 4;
  214.       decoder->strike_index_count = FT_NEXT_ULONG( p );
  215.       p                          += 34;
  216.       decoder->bit_depth          = *p;
  217.       if ( decoder->strike_index_array > face->sbit_table_size             ||
  218.            decoder->strike_index_array + 8 * decoder->strike_index_count >
  219.              face->sbit_table_size                                         )
  220.         error = SFNT_Err_Invalid_File_Format;
  221.     }
  222.   Exit:
  223.     return error;
  224.   }
  225.   static void
  226.   tt_sbit_decoder_done( TT_SBitDecoder  decoder )
  227.   {
  228.     FT_UNUSED( decoder );
  229.   }
  230.   static FT_Error
  231.   tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder  decoder )
  232.   {
  233.     FT_Error    error = SFNT_Err_Ok;
  234.     FT_UInt     width, height;
  235.     FT_Bitmap*  map = decoder->bitmap;
  236.     FT_Long     size;
  237.     if ( !decoder->metrics_loaded )
  238.     {
  239.       error = SFNT_Err_Invalid_Argument;
  240.       goto Exit;
  241.     }
  242.     width  = decoder->metrics->width;
  243.     height = decoder->metrics->height;
  244.     map->width = (int)width;
  245.     map->rows  = (int)height;
  246.     switch ( decoder->bit_depth )
  247.     {
  248.     case 1:
  249.       map->pixel_mode = FT_PIXEL_MODE_MONO;
  250.       map->pitch      = ( map->width + 7 ) >> 3;
  251.       break;
  252.     case 2:
  253.       map->pixel_mode = FT_PIXEL_MODE_GRAY2;
  254.       map->pitch      = ( map->width + 3 ) >> 2;
  255.       break;
  256.     case 4:
  257.       map->pixel_mode = FT_PIXEL_MODE_GRAY4;
  258.       map->pitch      = ( map->width + 1 ) >> 1;
  259.       break;
  260.     case 8:
  261.       map->pixel_mode = FT_PIXEL_MODE_GRAY;
  262.       map->pitch      = map->width;
  263.       break;
  264.     default:
  265.       error = SFNT_Err_Invalid_File_Format;
  266.       goto Exit;
  267.     }
  268.     size = map->rows * map->pitch;
  269.     /* check that there is no empty image */
  270.     if ( size == 0 )
  271.       goto Exit;     /* exit successfully! */
  272.     error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
  273.     if ( error )
  274.       goto Exit;
  275.     decoder->bitmap_allocated = 1;
  276.   Exit:
  277.     return error;
  278.   }
  279.   static FT_Error
  280.   tt_sbit_decoder_load_metrics( TT_SBitDecoder  decoder,
  281.                                 FT_Byte*       *pp,
  282.                                 FT_Byte*        limit,
  283.                                 FT_Bool         big )
  284.   {
  285.     FT_Byte*         p       = *pp;
  286.     TT_SBit_Metrics  metrics = decoder->metrics;
  287.     if ( p + 5 > limit )
  288.       goto Fail;
  289.     if ( !decoder->metrics_loaded )
  290.     {
  291.       metrics->height       = p[0];
  292.       metrics->width        = p[1];
  293.       metrics->horiBearingX = (FT_Char)p[2];
  294.       metrics->horiBearingY = (FT_Char)p[3];
  295.       metrics->horiAdvance  = p[4];
  296.     }
  297.     p += 5;
  298.     if ( big )
  299.     {
  300.       if ( p + 3 > limit )
  301.         goto Fail;
  302.       if ( !decoder->metrics_loaded )
  303.       {
  304.         metrics->vertBearingX = (FT_Char)p[0];
  305.         metrics->vertBearingY = (FT_Char)p[1];
  306.         metrics->vertAdvance  = p[2];
  307.       }
  308.       p += 3;
  309.     }
  310.     decoder->metrics_loaded = 1;
  311.     *pp = p;
  312.     return 0;
  313.   Fail:
  314.     return SFNT_Err_Invalid_Argument;
  315.   }
  316.   /* forward declaration */
  317.   static FT_Error
  318.   tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
  319.                               FT_UInt         glyph_index,
  320.                               FT_Int          x_pos,
  321.                               FT_Int          y_pos );
  322.   typedef FT_Error  (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder  decoder,
  323.                                                 FT_Byte*        p,
  324.                                                 FT_Byte*        plimit,
  325.                                                 FT_Int          x_pos,
  326.                                                 FT_Int          y_pos );
  327.   static FT_Error
  328.   tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder  decoder,
  329.                                      FT_Byte*        p,
  330.                                      FT_Byte*        limit,
  331.                                      FT_Int          x_pos,
  332.                                      FT_Int          y_pos )
  333.   {
  334.     FT_Error    error = SFNT_Err_Ok;
  335.     FT_Byte*    line;
  336.     FT_Int      bit_height, bit_width, pitch, width, height, h;
  337.     FT_Bitmap*  bitmap;
  338.     if ( !decoder->bitmap_allocated )
  339.     {
  340.       error = tt_sbit_decoder_alloc_bitmap( decoder );
  341.       if ( error )
  342.         goto Exit;
  343.     }
  344.     /* check that we can write the glyph into the bitmap */
  345.     bitmap     = decoder->bitmap;
  346.     bit_width  = bitmap->width;
  347.     bit_height = bitmap->rows;
  348.     pitch      = bitmap->pitch;
  349.     line       = bitmap->buffer;
  350.     width  = decoder->metrics->width;
  351.     height = decoder->metrics->height;
  352.     if ( x_pos < 0 || x_pos + width > bit_width   ||
  353.          y_pos < 0 || y_pos + height > bit_height )
  354.     {
  355.       error = SFNT_Err_Invalid_File_Format;
  356.       goto Exit;
  357.     }
  358.     if ( p + ( ( width + 7 ) >> 3 ) * height > limit )
  359.     {
  360.       error = SFNT_Err_Invalid_File_Format;
  361.       goto Exit;
  362.     }
  363.     /* now do the blit */
  364.     line  += y_pos * pitch + ( x_pos >> 3 );
  365.     x_pos &= 7;
  366.     if ( x_pos == 0 )  /* the easy one */
  367.     {
  368.       for ( h = height; h > 0; h--, line += pitch )
  369.       {
  370.         FT_Byte*  write = line;
  371.         FT_Int    w;
  372.         for ( w = width; w >= 8; w -= 8 )
  373.         {
  374.           write[0] = (FT_Byte)( write[0] | *p++ );
  375.           write   += 1;
  376.         }
  377.         if ( w > 0 )
  378.           write[0] = (FT_Byte)( write[0] | ( *p++ & ( 0xFF00U >> w ) ) );
  379.       }
  380.     }
  381.     else  /* x_pos > 0 */
  382.     {
  383.       for ( h = height; h > 0; h--, line += pitch )
  384.       {
  385.         FT_Byte*  write = line;
  386.         FT_Int    w;
  387.         FT_UInt   wval = 0;
  388.         for ( w = width; w >= 8; w -= 8 )
  389.         {
  390.           wval      = (FT_UInt)( wval | *p++ );
  391.           write[0]  = (FT_Byte)( write[0] | ( wval >> x_pos ) );
  392.           write    += 1;
  393.           wval    <<= 8;
  394.         }
  395.         if ( w > 0 )
  396.           wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
  397.         /* all bits read and there are ( x_pos + w ) bits to be written */
  398.         write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
  399.         if ( x_pos + w > 8 )
  400.         {
  401.           write++;
  402.           wval   <<= 8;
  403.           write[0] = (FT_Byte)( write[0] | ( wval >> x_pos ) );
  404.         }
  405.       }
  406.     }
  407.   Exit:
  408.     return error;
  409.   }
  410.   static FT_Error
  411.   tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder  decoder,
  412.                                     FT_Byte*        p,
  413.                                     FT_Byte*        limit,
  414.                                     FT_Int          x_pos,
  415.                                     FT_Int          y_pos )
  416.   {
  417.     FT_Error    error = SFNT_Err_Ok;
  418.     FT_Byte*    line;
  419.     FT_Int      bit_height, bit_width, pitch, width, height, h, nbits;
  420.     FT_Bitmap*  bitmap;
  421.     FT_UShort   rval;
  422.     if ( !decoder->bitmap_allocated )
  423.     {
  424.       error = tt_sbit_decoder_alloc_bitmap( decoder );
  425.       if ( error )
  426.         goto Exit;
  427.     }
  428.     /* check that we can write the glyph into the bitmap */
  429.     bitmap     = decoder->bitmap;
  430.     bit_width  = bitmap->width;
  431.     bit_height = bitmap->rows;
  432.     pitch      = bitmap->pitch;
  433.     line       = bitmap->buffer;
  434.     width  = decoder->metrics->width;
  435.     height = decoder->metrics->height;
  436.     if ( x_pos < 0 || x_pos + width  > bit_width  ||
  437.          y_pos < 0 || y_pos + height > bit_height )
  438.     {
  439.       error = SFNT_Err_Invalid_File_Format;
  440.       goto Exit;
  441.     }
  442.     if ( p + ( ( width * height + 7 ) >> 3 ) > limit )
  443.     {
  444.       error = SFNT_Err_Invalid_File_Format;
  445.       goto Exit;
  446.     }
  447.     /* now do the blit */
  448.     line  += y_pos * pitch + ( x_pos >> 3 );
  449.     x_pos &= 7;
  450.     /* the higher byte of `rval' is used as a buffer */
  451.     rval  = 0;
  452.     nbits = 0;
  453.     for ( h = height; h > 0; h--, line += pitch )
  454.     {
  455.       FT_Byte*  write = line;
  456.       FT_Int    w = width;
  457.       if ( x_pos )
  458.       {
  459.         w = ( width < 8 - x_pos ) ? width : 8 - x_pos;
  460.         if ( nbits < w )
  461.         {
  462.           rval  |= *p++;
  463.           nbits += 8 - w;
  464.         }
  465.         else
  466.         {
  467.           rval  >>= 8;
  468.           nbits  -= w;
  469.         }
  470.         *write++ |= ( ( rval >> nbits ) & 0xFF ) & ~( 0xFF << w );
  471.         rval    <<= 8;
  472.         w = width - w;
  473.       }
  474.       for ( ; w >= 8; w -= 8 )
  475.       {
  476.         rval     |= *p++;
  477.         *write++ |= ( rval >> nbits ) & 0xFF;
  478.         rval <<= 8;
  479.       }
  480.       if ( w > 0 )
  481.       {
  482.         if ( nbits < w )
  483.         {
  484.           rval   |= *p++;
  485.           *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
  486.           nbits  += 8 - w;
  487.           rval <<= 8;
  488.         }
  489.         else
  490.         {
  491.           *write |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
  492.           nbits  -= w;
  493.         }
  494.       }
  495.     }
  496.   Exit:
  497.     return error;
  498.   }
  499.   static FT_Error
  500.   tt_sbit_decoder_load_compound( TT_SBitDecoder  decoder,
  501.                                  FT_Byte*        p,
  502.                                  FT_Byte*        limit,
  503.                                  FT_Int          x_pos,
  504.                                  FT_Int          y_pos )
  505.   {
  506.     FT_Error  error = SFNT_Err_Ok;
  507.     FT_UInt   num_components, nn;
  508.     if ( p + 2 > limit )
  509.       goto Fail;
  510.     num_components = FT_NEXT_USHORT( p );
  511.     if ( p + 4 * num_components > limit )
  512.       goto Fail;
  513.     for ( nn = 0; nn < num_components; nn++ )
  514.     {
  515.       FT_UInt  gindex = FT_NEXT_USHORT( p );
  516.       FT_Byte  dx     = FT_NEXT_BYTE( p );
  517.       FT_Byte  dy     = FT_NEXT_BYTE( p );
  518.       /* NB: a recursive call */
  519.       error = tt_sbit_decoder_load_image( decoder, gindex,
  520.                                           x_pos + dx, y_pos + dy );
  521.       if ( error )
  522.         break;
  523.     }
  524.   Exit:
  525.     return error;
  526.   Fail:
  527.     error = SFNT_Err_Invalid_File_Format;
  528.     goto Exit;
  529.   }
  530.   static FT_Error
  531.   tt_sbit_decoder_load_bitmap( TT_SBitDecoder  decoder,
  532.                                FT_UInt         glyph_format,
  533.                                FT_ULong        glyph_start,
  534.                                FT_ULong        glyph_size,
  535.                                FT_Int          x_pos,
  536.                                FT_Int          y_pos )
  537.   {
  538.     FT_Error   error;
  539.     FT_Stream  stream = decoder->stream;
  540.     FT_Byte*   p;
  541.     FT_Byte*   p_limit;
  542.     FT_Byte*   data;
  543.     /* seek into the EBDT table now */
  544.     if ( glyph_start + glyph_size > decoder->ebdt_size )
  545.     {
  546.       error = SFNT_Err_Invalid_Argument;
  547.       goto Exit;
  548.     }
  549.     if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
  550.          FT_FRAME_EXTRACT( glyph_size, data )                )
  551.       goto Exit;
  552.     p       = data;
  553.     p_limit = p + glyph_size;
  554.     /* read the data, depending on the glyph format */
  555.     switch ( glyph_format )
  556.     {
  557.     case 1:
  558.     case 2:
  559.     case 8:
  560.       error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
  561.       break;
  562.     case 6:
  563.     case 7:
  564.     case 9:
  565.       error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
  566.       break;
  567.     default:
  568.       error = SFNT_Err_Ok;
  569.     }
  570.     if ( error )
  571.       goto Fail;
  572.     {
  573.       TT_SBitDecoder_LoadFunc  loader;
  574.       switch ( glyph_format )
  575.       {
  576.       case 1:
  577.       case 6:
  578.         loader = tt_sbit_decoder_load_byte_aligned;
  579.         break;
  580.       case 2:
  581.       case 5:
  582.       case 7:
  583.         loader = tt_sbit_decoder_load_bit_aligned;
  584.         break;
  585.       case 8:
  586.         if ( p + 1 > p_limit )
  587.           goto Fail;
  588.         p += 1;  /* skip padding */
  589.         /* fall-through */
  590.       case 9:
  591.         loader = tt_sbit_decoder_load_compound;
  592.         break;
  593.       default:
  594.         goto Fail;
  595.       }
  596.       error = loader( decoder, p, p_limit, x_pos, y_pos );
  597.     }
  598.   Fail:
  599.     FT_FRAME_RELEASE( data );
  600.   Exit:
  601.     return error;
  602.   }
  603.   static FT_Error
  604.   tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
  605.                               FT_UInt         glyph_index,
  606.                               FT_Int          x_pos,
  607.                               FT_Int          y_pos )
  608.   {
  609.     /*
  610.      *  First, we find the correct strike range that applies to this
  611.      *  glyph index.
  612.      */
  613.     FT_Byte*  p          = decoder->eblc_base + decoder->strike_index_array;
  614.     FT_Byte*  p_limit    = decoder->eblc_limit;
  615.     FT_ULong  num_ranges = decoder->strike_index_count;
  616.     FT_UInt   start, end, index_format, image_format;
  617.     FT_ULong  image_start = 0, image_end = 0, image_offset;
  618.     for ( ; num_ranges > 0; num_ranges-- )
  619.     {
  620.       start = FT_NEXT_USHORT( p );
  621.       end   = FT_NEXT_USHORT( p );
  622.       if ( glyph_index >= start && glyph_index <= end )
  623.         goto FoundRange;
  624.       p += 4;  /* ignore index offset */
  625.     }
  626.     goto NoBitmap;
  627.   FoundRange:
  628.     image_offset = FT_NEXT_ULONG( p );
  629.     /* overflow check */
  630.     if ( decoder->eblc_base + decoder->strike_index_array + image_offset <
  631.            decoder->eblc_base )
  632.       goto Failure;
  633.     p = decoder->eblc_base + decoder->strike_index_array + image_offset;
  634.     if ( p + 8 > p_limit )
  635.       goto NoBitmap;
  636.     /* now find the glyph's location and extend within the ebdt table */
  637.     index_format = FT_NEXT_USHORT( p );
  638.     image_format = FT_NEXT_USHORT( p );
  639.     image_offset = FT_NEXT_ULONG ( p );
  640.     switch ( index_format )
  641.     {
  642.     case 1: /* 4-byte offsets relative to `image_offset' */
  643.       {
  644.         p += 4 * ( glyph_index - start );
  645.         if ( p + 8 > p_limit )
  646.           goto NoBitmap;
  647.         image_start = FT_NEXT_ULONG( p );
  648.         image_end   = FT_NEXT_ULONG( p );
  649.         if ( image_start == image_end )  /* missing glyph */
  650.           goto NoBitmap;
  651.       }
  652.       break;
  653.     case 2: /* big metrics, constant image size */
  654.       {
  655.         FT_ULong  image_size;
  656.         if ( p + 12 > p_limit )
  657.           goto NoBitmap;
  658.         image_size = FT_NEXT_ULONG( p );
  659.         if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
  660.           goto NoBitmap;
  661.         image_start = image_size * ( glyph_index - start );
  662.         image_end   = image_start + image_size;
  663.       }
  664.       break;
  665.     case 3: /* 2-byte offsets relative to 'image_offset' */
  666.       {
  667.         p += 2 * ( glyph_index - start );
  668.         if ( p + 4 > p_limit )
  669.           goto NoBitmap;
  670.         image_start = FT_NEXT_USHORT( p );
  671.         image_end   = FT_NEXT_USHORT( p );
  672.         if ( image_start == image_end )  /* missing glyph */
  673.           goto NoBitmap;
  674.       }
  675.       break;
  676.     case 4: /* sparse glyph array with (glyph,offset) pairs */
  677.       {
  678.         FT_ULong  mm, num_glyphs;
  679.         if ( p + 4 > p_limit )
  680.           goto NoBitmap;
  681.         num_glyphs = FT_NEXT_ULONG( p );
  682.         /* overflow check */
  683.         if ( p + ( num_glyphs + 1 ) * 4 < p )
  684.           goto Failure;
  685.         if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
  686.           goto NoBitmap;
  687.         for ( mm = 0; mm < num_glyphs; mm++ )
  688.         {
  689.           FT_UInt  gindex = FT_NEXT_USHORT( p );
  690.           if ( gindex == glyph_index )
  691.           {
  692.             image_start = FT_NEXT_USHORT( p );
  693.             p          += 2;
  694.             image_end   = FT_PEEK_USHORT( p );
  695.             break;
  696.           }
  697.           p += 2;
  698.         }
  699.         if ( mm >= num_glyphs )
  700.           goto NoBitmap;
  701.       }
  702.       break;
  703.     case 5: /* constant metrics with sparse glyph codes */
  704.       {
  705.         FT_ULong  image_size, mm, num_glyphs;
  706.         if ( p + 16 > p_limit )
  707.           goto NoBitmap;
  708.         image_size = FT_NEXT_ULONG( p );
  709.         if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
  710.           goto NoBitmap;
  711.         num_glyphs = FT_NEXT_ULONG( p );
  712.         /* overflow check */
  713.         if ( p + 2 * num_glyphs < p )
  714.           goto Failure;
  715.         if ( p + 2 * num_glyphs > p_limit )
  716.           goto NoBitmap;
  717.         for ( mm = 0; mm < num_glyphs; mm++ )
  718.         {
  719.           FT_UInt  gindex = FT_NEXT_USHORT( p );
  720.           if ( gindex == glyph_index )
  721.             break;
  722.         }
  723.         if ( mm >= num_glyphs )
  724.           goto NoBitmap;
  725.         image_start = image_size * mm;
  726.         image_end   = image_start + image_size;
  727.       }
  728.       break;
  729.     default:
  730.       goto NoBitmap;
  731.     }
  732.     if ( image_start > image_end )
  733.       goto NoBitmap;
  734.     image_end  -= image_start;
  735.     image_start = image_offset + image_start;
  736.     return tt_sbit_decoder_load_bitmap( decoder,
  737.                                         image_format,
  738.                                         image_start,
  739.                                         image_end,
  740.                                         x_pos,
  741.                                         y_pos );
  742.   Failure:
  743.     return SFNT_Err_Invalid_Table;
  744.   NoBitmap:
  745.     return SFNT_Err_Invalid_Argument;
  746.   }
  747.   FT_LOCAL( FT_Error )
  748.   tt_face_load_sbit_image( TT_Face              face,
  749.                            FT_ULong             strike_index,
  750.                            FT_UInt              glyph_index,
  751.                            FT_UInt              load_flags,
  752.                            FT_Stream            stream,
  753.                            FT_Bitmap           *map,
  754.                            TT_SBit_MetricsRec  *metrics )
  755.   {
  756.     TT_SBitDecoderRec  decoder[1];
  757.     FT_Error           error;
  758.     FT_UNUSED( load_flags );
  759.     FT_UNUSED( stream );
  760.     FT_UNUSED( map );
  761.     error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
  762.     if ( !error )
  763.     {
  764.       error = tt_sbit_decoder_load_image( decoder, glyph_index, 0, 0 );
  765.       tt_sbit_decoder_done( decoder );
  766.     }
  767.     return error;
  768.   }
  769. /* EOF */