Home | History | Annotate | Download | only in sfnt
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  ttsbit.c                                                               */
      4 /*                                                                         */
      5 /*    TrueType and OpenType embedded bitmap support (body).                */
      6 /*                                                                         */
      7 /*  Copyright 2005-2009, 2013, 2014 by                                     */
      8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
      9 /*                                                                         */
     10 /*  Copyright 2013 by Google, Inc.                                         */
     11 /*  Google Author(s): Behdad Esfahbod.                                     */
     12 /*                                                                         */
     13 /*  This file is part of the FreeType project, and may only be used,       */
     14 /*  modified, and distributed under the terms of the FreeType project      */
     15 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
     16 /*  this file you indicate that you have read the license and              */
     17 /*  understand and accept it fully.                                        */
     18 /*                                                                         */
     19 /***************************************************************************/
     20 
     21 
     22 #include <ft2build.h>
     23 #include FT_INTERNAL_DEBUG_H
     24 #include FT_INTERNAL_STREAM_H
     25 #include FT_TRUETYPE_TAGS_H
     26 #include FT_BITMAP_H
     27 #include "ttsbit.h"
     28 
     29 #include "sferrors.h"
     30 
     31 #include "ttmtx.h"
     32 #include "pngshim.h"
     33 
     34 
     35   /*************************************************************************/
     36   /*                                                                       */
     37   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     38   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     39   /* messages during execution.                                            */
     40   /*                                                                       */
     41 #undef  FT_COMPONENT
     42 #define FT_COMPONENT  trace_ttsbit
     43 
     44 
     45   FT_LOCAL_DEF( FT_Error )
     46   tt_face_load_sbit( TT_Face    face,
     47                      FT_Stream  stream )
     48   {
     49     FT_Error  error;
     50     FT_ULong  table_size;
     51 
     52 
     53     face->sbit_table       = NULL;
     54     face->sbit_table_size  = 0;
     55     face->sbit_table_type  = TT_SBIT_TABLE_TYPE_NONE;
     56     face->sbit_num_strikes = 0;
     57 
     58     error = face->goto_table( face, TTAG_CBLC, stream, &table_size );
     59     if ( !error )
     60       face->sbit_table_type = TT_SBIT_TABLE_TYPE_CBLC;
     61     else
     62     {
     63       error = face->goto_table( face, TTAG_EBLC, stream, &table_size );
     64       if ( error )
     65         error = face->goto_table( face, TTAG_bloc, stream, &table_size );
     66       if ( !error )
     67         face->sbit_table_type = TT_SBIT_TABLE_TYPE_EBLC;
     68     }
     69 
     70     if ( error )
     71     {
     72       error = face->goto_table( face, TTAG_sbix, stream, &table_size );
     73       if ( !error )
     74         face->sbit_table_type = TT_SBIT_TABLE_TYPE_SBIX;
     75     }
     76     if ( error )
     77       goto Exit;
     78 
     79     if ( table_size < 8 )
     80     {
     81       FT_ERROR(( "tt_face_load_sbit_strikes: table too short\n" ));
     82       error = FT_THROW( Invalid_File_Format );
     83       goto Exit;
     84     }
     85 
     86     switch ( (FT_UInt)face->sbit_table_type )
     87     {
     88     case TT_SBIT_TABLE_TYPE_EBLC:
     89     case TT_SBIT_TABLE_TYPE_CBLC:
     90       {
     91         FT_Byte*  p;
     92         FT_Fixed  version;
     93         FT_ULong  num_strikes;
     94         FT_UInt   count;
     95 
     96 
     97         if ( FT_FRAME_EXTRACT( table_size, face->sbit_table ) )
     98           goto Exit;
     99 
    100         face->sbit_table_size = table_size;
    101 
    102         p = face->sbit_table;
    103 
    104         version     = FT_NEXT_ULONG( p );
    105         num_strikes = FT_NEXT_ULONG( p );
    106 
    107         if ( ( version & 0xFFFF0000UL ) != 0x00020000UL )
    108         {
    109           error = FT_THROW( Unknown_File_Format );
    110           goto Exit;
    111         }
    112 
    113         if ( num_strikes >= 0x10000UL )
    114         {
    115           error = FT_THROW( Invalid_File_Format );
    116           goto Exit;
    117         }
    118 
    119         /*
    120          *  Count the number of strikes available in the table.  We are a bit
    121          *  paranoid there and don't trust the data.
    122          */
    123         count = (FT_UInt)num_strikes;
    124         if ( 8 + 48UL * count > table_size )
    125           count = (FT_UInt)( ( table_size - 8 ) / 48 );
    126 
    127         face->sbit_num_strikes = count;
    128       }
    129       break;
    130 
    131     case TT_SBIT_TABLE_TYPE_SBIX:
    132       {
    133         FT_UShort  version;
    134         FT_UShort  flags;
    135         FT_ULong   num_strikes;
    136         FT_UInt    count;
    137 
    138 
    139         if ( FT_FRAME_ENTER( 8 ) )
    140           goto Exit;
    141 
    142         version     = FT_GET_USHORT();
    143         flags       = FT_GET_USHORT();
    144         num_strikes = FT_GET_ULONG();
    145 
    146         FT_FRAME_EXIT();
    147 
    148         if ( version < 1 )
    149         {
    150           error = FT_THROW( Unknown_File_Format );
    151           goto Exit;
    152         }
    153         if ( flags != 0x0001 || num_strikes >= 0x10000UL )
    154         {
    155           error = FT_THROW( Invalid_File_Format );
    156           goto Exit;
    157         }
    158 
    159         /*
    160          *  Count the number of strikes available in the table.  We are a bit
    161          *  paranoid there and don't trust the data.
    162          */
    163         count = (FT_UInt)num_strikes;
    164         if ( 8 + 4UL * count > table_size )
    165           count = (FT_UInt)( ( table_size - 8 ) / 4 );
    166 
    167         if ( FT_STREAM_SEEK( FT_STREAM_POS() - 8 ) )
    168           goto Exit;
    169 
    170         face->sbit_table_size = 8 + count * 4;
    171         if ( FT_FRAME_EXTRACT( face->sbit_table_size, face->sbit_table ) )
    172           goto Exit;
    173 
    174         face->sbit_num_strikes = count;
    175       }
    176       break;
    177 
    178     default:
    179       error = FT_THROW( Unknown_File_Format );
    180       break;
    181     }
    182 
    183     if ( !error )
    184       FT_TRACE3(( "sbit_num_strikes: %u\n", face->sbit_num_strikes ));
    185 
    186     return FT_Err_Ok;
    187 
    188   Exit:
    189     if ( error )
    190     {
    191       if ( face->sbit_table )
    192         FT_FRAME_RELEASE( face->sbit_table );
    193       face->sbit_table_size = 0;
    194       face->sbit_table_type = TT_SBIT_TABLE_TYPE_NONE;
    195     }
    196 
    197     return error;
    198   }
    199 
    200 
    201   FT_LOCAL_DEF( void )
    202   tt_face_free_sbit( TT_Face  face )
    203   {
    204     FT_Stream  stream = face->root.stream;
    205 
    206 
    207     FT_FRAME_RELEASE( face->sbit_table );
    208     face->sbit_table_size  = 0;
    209     face->sbit_table_type  = TT_SBIT_TABLE_TYPE_NONE;
    210     face->sbit_num_strikes = 0;
    211   }
    212 
    213 
    214   FT_LOCAL_DEF( FT_Error )
    215   tt_face_set_sbit_strike( TT_Face          face,
    216                            FT_Size_Request  req,
    217                            FT_ULong*        astrike_index )
    218   {
    219     return FT_Match_Size( (FT_Face)face, req, 0, astrike_index );
    220   }
    221 
    222 
    223   FT_LOCAL_DEF( FT_Error )
    224   tt_face_load_strike_metrics( TT_Face           face,
    225                                FT_ULong          strike_index,
    226                                FT_Size_Metrics*  metrics )
    227   {
    228     if ( strike_index >= (FT_ULong)face->sbit_num_strikes )
    229       return FT_THROW( Invalid_Argument );
    230 
    231     switch ( (FT_UInt)face->sbit_table_type )
    232     {
    233     case TT_SBIT_TABLE_TYPE_EBLC:
    234     case TT_SBIT_TABLE_TYPE_CBLC:
    235       {
    236         FT_Byte*  strike;
    237 
    238 
    239         strike = face->sbit_table + 8 + strike_index * 48;
    240 
    241         metrics->x_ppem = (FT_UShort)strike[44];
    242         metrics->y_ppem = (FT_UShort)strike[45];
    243 
    244         metrics->ascender  = (FT_Char)strike[16] << 6;  /* hori.ascender  */
    245         metrics->descender = (FT_Char)strike[17] << 6;  /* hori.descender */
    246         metrics->height    = metrics->ascender - metrics->descender;
    247 
    248         /* Is this correct? */
    249         metrics->max_advance = ( (FT_Char)strike[22] + /* min_origin_SB  */
    250                                           strike[18] + /* max_width      */
    251                                  (FT_Char)strike[23]   /* min_advance_SB */
    252                                                      ) << 6;
    253         return FT_Err_Ok;
    254       }
    255 
    256     case TT_SBIT_TABLE_TYPE_SBIX:
    257       {
    258         FT_Stream       stream = face->root.stream;
    259         FT_UInt         offset, upem;
    260         FT_UShort       ppem, resolution;
    261         TT_HoriHeader  *hori;
    262         FT_ULong        table_size;
    263 
    264         FT_Error  error;
    265         FT_Byte*  p;
    266 
    267 
    268         p      = face->sbit_table + 8 + 4 * strike_index;
    269         offset = FT_NEXT_ULONG( p );
    270 
    271         error = face->goto_table( face, TTAG_sbix, stream, &table_size );
    272         if ( error )
    273           return error;
    274 
    275         if ( offset + 4  > table_size )
    276           return FT_THROW( Invalid_File_Format );
    277 
    278         if ( FT_STREAM_SEEK( FT_STREAM_POS() + offset ) ||
    279              FT_FRAME_ENTER( 4 )                        )
    280           return error;
    281 
    282         ppem       = FT_GET_USHORT();
    283         resolution = FT_GET_USHORT();
    284 
    285         FT_UNUSED( resolution ); /* What to do with this? */
    286 
    287         FT_FRAME_EXIT();
    288 
    289         upem = face->header.Units_Per_EM;
    290         hori = &face->horizontal;
    291 
    292         metrics->x_ppem = ppem;
    293         metrics->y_ppem = ppem;
    294 
    295         metrics->ascender    = ppem * hori->Ascender * 64 / upem;
    296         metrics->descender   = ppem * hori->Descender * 64 / upem;
    297         metrics->height      = ppem * ( hori->Ascender -
    298                                         hori->Descender +
    299                                         hori->Line_Gap ) * 64 / upem;
    300         metrics->max_advance = ppem * hori->advance_Width_Max * 64 / upem;
    301 
    302         return error;
    303       }
    304 
    305     default:
    306       return FT_THROW( Unknown_File_Format );
    307     }
    308   }
    309 
    310 
    311   typedef struct  TT_SBitDecoderRec_
    312   {
    313     TT_Face          face;
    314     FT_Stream        stream;
    315     FT_Bitmap*       bitmap;
    316     TT_SBit_Metrics  metrics;
    317     FT_Bool          metrics_loaded;
    318     FT_Bool          bitmap_allocated;
    319     FT_Byte          bit_depth;
    320 
    321     FT_ULong         ebdt_start;
    322     FT_ULong         ebdt_size;
    323 
    324     FT_ULong         strike_index_array;
    325     FT_ULong         strike_index_count;
    326     FT_Byte*         eblc_base;
    327     FT_Byte*         eblc_limit;
    328 
    329   } TT_SBitDecoderRec, *TT_SBitDecoder;
    330 
    331 
    332   static FT_Error
    333   tt_sbit_decoder_init( TT_SBitDecoder       decoder,
    334                         TT_Face              face,
    335                         FT_ULong             strike_index,
    336                         TT_SBit_MetricsRec*  metrics )
    337   {
    338     FT_Error   error;
    339     FT_Stream  stream = face->root.stream;
    340     FT_ULong   ebdt_size;
    341 
    342 
    343     error = face->goto_table( face, TTAG_CBDT, stream, &ebdt_size );
    344     if ( error )
    345       error = face->goto_table( face, TTAG_EBDT, stream, &ebdt_size );
    346     if ( error )
    347       error = face->goto_table( face, TTAG_bdat, stream, &ebdt_size );
    348     if ( error )
    349       goto Exit;
    350 
    351     decoder->face    = face;
    352     decoder->stream  = stream;
    353     decoder->bitmap  = &face->root.glyph->bitmap;
    354     decoder->metrics = metrics;
    355 
    356     decoder->metrics_loaded   = 0;
    357     decoder->bitmap_allocated = 0;
    358 
    359     decoder->ebdt_start = FT_STREAM_POS();
    360     decoder->ebdt_size  = ebdt_size;
    361 
    362     decoder->eblc_base  = face->sbit_table;
    363     decoder->eblc_limit = face->sbit_table + face->sbit_table_size;
    364 
    365     /* now find the strike corresponding to the index */
    366     {
    367       FT_Byte*  p;
    368 
    369 
    370       if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
    371       {
    372         error = FT_THROW( Invalid_File_Format );
    373         goto Exit;
    374       }
    375 
    376       p = decoder->eblc_base + 8 + 48 * strike_index;
    377 
    378       decoder->strike_index_array = FT_NEXT_ULONG( p );
    379       p                          += 4;
    380       decoder->strike_index_count = FT_NEXT_ULONG( p );
    381       p                          += 34;
    382       decoder->bit_depth          = *p;
    383 
    384       if ( decoder->strike_index_array > face->sbit_table_size             ||
    385            decoder->strike_index_array + 8 * decoder->strike_index_count >
    386              face->sbit_table_size                                         )
    387         error = FT_THROW( Invalid_File_Format );
    388     }
    389 
    390   Exit:
    391     return error;
    392   }
    393 
    394 
    395   static void
    396   tt_sbit_decoder_done( TT_SBitDecoder  decoder )
    397   {
    398     FT_UNUSED( decoder );
    399   }
    400 
    401 
    402   static FT_Error
    403   tt_sbit_decoder_alloc_bitmap( TT_SBitDecoder  decoder )
    404   {
    405     FT_Error    error = FT_Err_Ok;
    406     FT_UInt     width, height;
    407     FT_Bitmap*  map = decoder->bitmap;
    408     FT_Long     size;
    409 
    410 
    411     if ( !decoder->metrics_loaded )
    412     {
    413       error = FT_THROW( Invalid_Argument );
    414       goto Exit;
    415     }
    416 
    417     width  = decoder->metrics->width;
    418     height = decoder->metrics->height;
    419 
    420     map->width = (int)width;
    421     map->rows  = (int)height;
    422 
    423     switch ( decoder->bit_depth )
    424     {
    425     case 1:
    426       map->pixel_mode = FT_PIXEL_MODE_MONO;
    427       map->pitch      = ( map->width + 7 ) >> 3;
    428       map->num_grays  = 2;
    429       break;
    430 
    431     case 2:
    432       map->pixel_mode = FT_PIXEL_MODE_GRAY2;
    433       map->pitch      = ( map->width + 3 ) >> 2;
    434       map->num_grays  = 4;
    435       break;
    436 
    437     case 4:
    438       map->pixel_mode = FT_PIXEL_MODE_GRAY4;
    439       map->pitch      = ( map->width + 1 ) >> 1;
    440       map->num_grays  = 16;
    441       break;
    442 
    443     case 8:
    444       map->pixel_mode = FT_PIXEL_MODE_GRAY;
    445       map->pitch      = map->width;
    446       map->num_grays  = 256;
    447       break;
    448 
    449     case 32:
    450       map->pixel_mode = FT_PIXEL_MODE_BGRA;
    451       map->pitch      = map->width * 4;
    452       map->num_grays  = 256;
    453       break;
    454 
    455     default:
    456       error = FT_THROW( Invalid_File_Format );
    457       goto Exit;
    458     }
    459 
    460     size = map->rows * map->pitch;
    461 
    462     /* check that there is no empty image */
    463     if ( size == 0 )
    464       goto Exit;     /* exit successfully! */
    465 
    466     error = ft_glyphslot_alloc_bitmap( decoder->face->root.glyph, size );
    467     if ( error )
    468       goto Exit;
    469 
    470     decoder->bitmap_allocated = 1;
    471 
    472   Exit:
    473     return error;
    474   }
    475 
    476 
    477   static FT_Error
    478   tt_sbit_decoder_load_metrics( TT_SBitDecoder  decoder,
    479                                 FT_Byte*       *pp,
    480                                 FT_Byte*        limit,
    481                                 FT_Bool         big )
    482   {
    483     FT_Byte*         p       = *pp;
    484     TT_SBit_Metrics  metrics = decoder->metrics;
    485 
    486 
    487     if ( p + 5 > limit )
    488       goto Fail;
    489 
    490     metrics->height       = p[0];
    491     metrics->width        = p[1];
    492     metrics->horiBearingX = (FT_Char)p[2];
    493     metrics->horiBearingY = (FT_Char)p[3];
    494     metrics->horiAdvance  = p[4];
    495 
    496     p += 5;
    497     if ( big )
    498     {
    499       if ( p + 3 > limit )
    500         goto Fail;
    501 
    502       metrics->vertBearingX = (FT_Char)p[0];
    503       metrics->vertBearingY = (FT_Char)p[1];
    504       metrics->vertAdvance  = p[2];
    505 
    506       p += 3;
    507     }
    508 
    509     decoder->metrics_loaded = 1;
    510     *pp = p;
    511     return FT_Err_Ok;
    512 
    513   Fail:
    514     FT_TRACE1(( "tt_sbit_decoder_load_metrics: broken table" ));
    515     return FT_THROW( Invalid_Argument );
    516   }
    517 
    518 
    519   /* forward declaration */
    520   static FT_Error
    521   tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
    522                               FT_UInt         glyph_index,
    523                               FT_Int          x_pos,
    524                               FT_Int          y_pos );
    525 
    526   typedef FT_Error  (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder  decoder,
    527                                                 FT_Byte*        p,
    528                                                 FT_Byte*        plimit,
    529                                                 FT_Int          x_pos,
    530                                                 FT_Int          y_pos );
    531 
    532 
    533   static FT_Error
    534   tt_sbit_decoder_load_byte_aligned( TT_SBitDecoder  decoder,
    535                                      FT_Byte*        p,
    536                                      FT_Byte*        limit,
    537                                      FT_Int          x_pos,
    538                                      FT_Int          y_pos )
    539   {
    540     FT_Error    error = FT_Err_Ok;
    541     FT_Byte*    line;
    542     FT_Int      bit_height, bit_width, pitch, width, height, line_bits, h;
    543     FT_Bitmap*  bitmap;
    544 
    545 
    546     /* check that we can write the glyph into the bitmap */
    547     bitmap     = decoder->bitmap;
    548     bit_width  = bitmap->width;
    549     bit_height = bitmap->rows;
    550     pitch      = bitmap->pitch;
    551     line       = bitmap->buffer;
    552 
    553     width  = decoder->metrics->width;
    554     height = decoder->metrics->height;
    555 
    556     line_bits = width * decoder->bit_depth;
    557 
    558     if ( x_pos < 0 || x_pos + width > bit_width   ||
    559          y_pos < 0 || y_pos + height > bit_height )
    560     {
    561       FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned:"
    562                   " invalid bitmap dimensions\n" ));
    563       error = FT_THROW( Invalid_File_Format );
    564       goto Exit;
    565     }
    566 
    567     if ( p + ( ( line_bits + 7 ) >> 3 ) * height > limit )
    568     {
    569       FT_TRACE1(( "tt_sbit_decoder_load_byte_aligned: broken bitmap\n" ));
    570       error = FT_THROW( Invalid_File_Format );
    571       goto Exit;
    572     }
    573 
    574     /* now do the blit */
    575     line  += y_pos * pitch + ( x_pos >> 3 );
    576     x_pos &= 7;
    577 
    578     if ( x_pos == 0 )  /* the easy one */
    579     {
    580       for ( h = height; h > 0; h--, line += pitch )
    581       {
    582         FT_Byte*  pwrite = line;
    583         FT_Int    w;
    584 
    585 
    586         for ( w = line_bits; w >= 8; w -= 8 )
    587         {
    588           pwrite[0] = (FT_Byte)( pwrite[0] | *p++ );
    589           pwrite   += 1;
    590         }
    591 
    592         if ( w > 0 )
    593           pwrite[0] = (FT_Byte)( pwrite[0] | ( *p++ & ( 0xFF00U >> w ) ) );
    594       }
    595     }
    596     else  /* x_pos > 0 */
    597     {
    598       for ( h = height; h > 0; h--, line += pitch )
    599       {
    600         FT_Byte*  pwrite = line;
    601         FT_Int    w;
    602         FT_UInt   wval = 0;
    603 
    604 
    605         for ( w = line_bits; w >= 8; w -= 8 )
    606         {
    607           wval       = (FT_UInt)( wval | *p++ );
    608           pwrite[0]  = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
    609           pwrite    += 1;
    610           wval     <<= 8;
    611         }
    612 
    613         if ( w > 0 )
    614           wval = (FT_UInt)( wval | ( *p++ & ( 0xFF00U >> w ) ) );
    615 
    616         /* all bits read and there are `x_pos + w' bits to be written */
    617 
    618         pwrite[0] = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
    619 
    620         if ( x_pos + w > 8 )
    621         {
    622           pwrite++;
    623           wval     <<= 8;
    624           pwrite[0]  = (FT_Byte)( pwrite[0] | ( wval >> x_pos ) );
    625         }
    626       }
    627     }
    628 
    629   Exit:
    630     if ( !error )
    631       FT_TRACE3(( "tt_sbit_decoder_load_byte_aligned: loaded\n" ));
    632     return error;
    633   }
    634 
    635 
    636   /*
    637    * Load a bit-aligned bitmap (with pointer `p') into a line-aligned bitmap
    638    * (with pointer `pwrite').  In the example below, the width is 3 pixel,
    639    * and `x_pos' is 1 pixel.
    640    *
    641    *       p                               p+1
    642    *     |                               |                               |
    643    *     | 7   6   5   4   3   2   1   0 | 7   6   5   4   3   2   1   0 |...
    644    *     |                               |                               |
    645    *       +-------+   +-------+   +-------+ ...
    646    *           .           .           .
    647    *           .           .           .
    648    *           v           .           .
    649    *       +-------+       .           .
    650    * |                               | .
    651    * | 7   6   5   4   3   2   1   0 | .
    652    * |                               | .
    653    *   pwrite              .           .
    654    *                       .           .
    655    *                       v           .
    656    *                   +-------+       .
    657    *             |                               |
    658    *             | 7   6   5   4   3   2   1   0 |
    659    *             |                               |
    660    *               pwrite+1            .
    661    *                                   .
    662    *                                   v
    663    *                               +-------+
    664    *                         |                               |
    665    *                         | 7   6   5   4   3   2   1   0 |
    666    *                         |                               |
    667    *                           pwrite+2
    668    *
    669    */
    670 
    671   static FT_Error
    672   tt_sbit_decoder_load_bit_aligned( TT_SBitDecoder  decoder,
    673                                     FT_Byte*        p,
    674                                     FT_Byte*        limit,
    675                                     FT_Int          x_pos,
    676                                     FT_Int          y_pos )
    677   {
    678     FT_Error    error = FT_Err_Ok;
    679     FT_Byte*    line;
    680     FT_Int      bit_height, bit_width, pitch, width, height, line_bits, h, nbits;
    681     FT_Bitmap*  bitmap;
    682     FT_UShort   rval;
    683 
    684 
    685     /* check that we can write the glyph into the bitmap */
    686     bitmap     = decoder->bitmap;
    687     bit_width  = bitmap->width;
    688     bit_height = bitmap->rows;
    689     pitch      = bitmap->pitch;
    690     line       = bitmap->buffer;
    691 
    692     width  = decoder->metrics->width;
    693     height = decoder->metrics->height;
    694 
    695     line_bits = width * decoder->bit_depth;
    696 
    697     if ( x_pos < 0 || x_pos + width  > bit_width  ||
    698          y_pos < 0 || y_pos + height > bit_height )
    699     {
    700       FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned:"
    701                   " invalid bitmap dimensions\n" ));
    702       error = FT_THROW( Invalid_File_Format );
    703       goto Exit;
    704     }
    705 
    706     if ( p + ( ( line_bits * height + 7 ) >> 3 ) > limit )
    707     {
    708       FT_TRACE1(( "tt_sbit_decoder_load_bit_aligned: broken bitmap\n" ));
    709       error = FT_THROW( Invalid_File_Format );
    710       goto Exit;
    711     }
    712 
    713     /* now do the blit */
    714 
    715     /* adjust `line' to point to the first byte of the bitmap */
    716     line  += y_pos * pitch + ( x_pos >> 3 );
    717     x_pos &= 7;
    718 
    719     /* the higher byte of `rval' is used as a buffer */
    720     rval  = 0;
    721     nbits = 0;
    722 
    723     for ( h = height; h > 0; h--, line += pitch )
    724     {
    725       FT_Byte*  pwrite = line;
    726       FT_Int    w      = line_bits;
    727 
    728 
    729       /* handle initial byte (in target bitmap) specially if necessary */
    730       if ( x_pos )
    731       {
    732         w = ( line_bits < 8 - x_pos ) ? line_bits : 8 - x_pos;
    733 
    734         if ( h == height )
    735         {
    736           rval  = *p++;
    737           nbits = x_pos;
    738         }
    739         else if ( nbits < w )
    740         {
    741           if ( p < limit )
    742             rval |= *p++;
    743           nbits += 8 - w;
    744         }
    745         else
    746         {
    747           rval  >>= 8;
    748           nbits  -= w;
    749         }
    750 
    751         *pwrite++ |= ( ( rval >> nbits ) & 0xFF ) &
    752                      ( ~( 0xFF << w ) << ( 8 - w - x_pos ) );
    753         rval     <<= 8;
    754 
    755         w = line_bits - w;
    756       }
    757 
    758       /* handle medial bytes */
    759       for ( ; w >= 8; w -= 8 )
    760       {
    761         rval      |= *p++;
    762         *pwrite++ |= ( rval >> nbits ) & 0xFF;
    763 
    764         rval <<= 8;
    765       }
    766 
    767       /* handle final byte if necessary */
    768       if ( w > 0 )
    769       {
    770         if ( nbits < w )
    771         {
    772           if ( p < limit )
    773             rval |= *p++;
    774           *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
    775           nbits   += 8 - w;
    776 
    777           rval <<= 8;
    778         }
    779         else
    780         {
    781           *pwrite |= ( ( rval >> nbits ) & 0xFF ) & ( 0xFF00U >> w );
    782           nbits   -= w;
    783         }
    784       }
    785     }
    786 
    787   Exit:
    788     if ( !error )
    789       FT_TRACE3(( "tt_sbit_decoder_load_bit_aligned: loaded\n" ));
    790     return error;
    791   }
    792 
    793 
    794   static FT_Error
    795   tt_sbit_decoder_load_compound( TT_SBitDecoder  decoder,
    796                                  FT_Byte*        p,
    797                                  FT_Byte*        limit,
    798                                  FT_Int          x_pos,
    799                                  FT_Int          y_pos )
    800   {
    801     FT_Error  error = FT_Err_Ok;
    802     FT_UInt   num_components, nn;
    803 
    804     FT_Char  horiBearingX = (FT_Char)decoder->metrics->horiBearingX;
    805     FT_Char  horiBearingY = (FT_Char)decoder->metrics->horiBearingY;
    806     FT_Byte  horiAdvance  = (FT_Byte)decoder->metrics->horiAdvance;
    807     FT_Char  vertBearingX = (FT_Char)decoder->metrics->vertBearingX;
    808     FT_Char  vertBearingY = (FT_Char)decoder->metrics->vertBearingY;
    809     FT_Byte  vertAdvance  = (FT_Byte)decoder->metrics->vertAdvance;
    810 
    811 
    812     if ( p + 2 > limit )
    813       goto Fail;
    814 
    815     num_components = FT_NEXT_USHORT( p );
    816     if ( p + 4 * num_components > limit )
    817     {
    818       FT_TRACE1(( "tt_sbit_decoder_load_compound: broken table\n" ));
    819       goto Fail;
    820     }
    821 
    822     FT_TRACE3(( "tt_sbit_decoder_load_compound: loading %d components\n",
    823                 num_components ));
    824 
    825     for ( nn = 0; nn < num_components; nn++ )
    826     {
    827       FT_UInt  gindex = FT_NEXT_USHORT( p );
    828       FT_Byte  dx     = FT_NEXT_BYTE( p );
    829       FT_Byte  dy     = FT_NEXT_BYTE( p );
    830 
    831 
    832       /* NB: a recursive call */
    833       error = tt_sbit_decoder_load_image( decoder, gindex,
    834                                           x_pos + dx, y_pos + dy );
    835       if ( error )
    836         break;
    837     }
    838 
    839     FT_TRACE3(( "tt_sbit_decoder_load_compound: done\n" ));
    840 
    841     decoder->metrics->horiBearingX = horiBearingX;
    842     decoder->metrics->horiBearingY = horiBearingY;
    843     decoder->metrics->horiAdvance  = horiAdvance;
    844     decoder->metrics->vertBearingX = vertBearingX;
    845     decoder->metrics->vertBearingY = vertBearingY;
    846     decoder->metrics->vertAdvance  = vertAdvance;
    847     decoder->metrics->width        = (FT_Byte)decoder->bitmap->width;
    848     decoder->metrics->height       = (FT_Byte)decoder->bitmap->rows;
    849 
    850   Exit:
    851     return error;
    852 
    853   Fail:
    854     error = FT_THROW( Invalid_File_Format );
    855     goto Exit;
    856   }
    857 
    858 
    859 #ifdef FT_CONFIG_OPTION_USE_PNG
    860 
    861   static FT_Error
    862   tt_sbit_decoder_load_png( TT_SBitDecoder  decoder,
    863                             FT_Byte*        p,
    864                             FT_Byte*        limit,
    865                             FT_Int          x_pos,
    866                             FT_Int          y_pos )
    867   {
    868     FT_Error  error = FT_Err_Ok;
    869     FT_ULong  png_len;
    870 
    871 
    872     if ( limit - p < 4 )
    873     {
    874       FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
    875       error = FT_THROW( Invalid_File_Format );
    876       goto Exit;
    877     }
    878 
    879     png_len = FT_NEXT_ULONG( p );
    880     if ( (FT_ULong)( limit - p ) < png_len )
    881     {
    882       FT_TRACE1(( "tt_sbit_decoder_load_png: broken bitmap\n" ));
    883       error = FT_THROW( Invalid_File_Format );
    884       goto Exit;
    885     }
    886 
    887     error = Load_SBit_Png( decoder->face->root.glyph,
    888                            x_pos,
    889                            y_pos,
    890                            decoder->bit_depth,
    891                            decoder->metrics,
    892                            decoder->stream->memory,
    893                            p,
    894                            png_len,
    895                            FALSE );
    896 
    897   Exit:
    898     if ( !error )
    899       FT_TRACE3(( "tt_sbit_decoder_load_png: loaded\n" ));
    900     return error;
    901   }
    902 
    903 #endif /* FT_CONFIG_OPTION_USE_PNG */
    904 
    905 
    906   static FT_Error
    907   tt_sbit_decoder_load_bitmap( TT_SBitDecoder  decoder,
    908                                FT_UInt         glyph_format,
    909                                FT_ULong        glyph_start,
    910                                FT_ULong        glyph_size,
    911                                FT_Int          x_pos,
    912                                FT_Int          y_pos )
    913   {
    914     FT_Error   error;
    915     FT_Stream  stream = decoder->stream;
    916     FT_Byte*   p;
    917     FT_Byte*   p_limit;
    918     FT_Byte*   data;
    919 
    920 
    921     /* seek into the EBDT table now */
    922     if ( glyph_start + glyph_size > decoder->ebdt_size )
    923     {
    924       error = FT_THROW( Invalid_Argument );
    925       goto Exit;
    926     }
    927 
    928     if ( FT_STREAM_SEEK( decoder->ebdt_start + glyph_start ) ||
    929          FT_FRAME_EXTRACT( glyph_size, data )                )
    930       goto Exit;
    931 
    932     p       = data;
    933     p_limit = p + glyph_size;
    934 
    935     /* read the data, depending on the glyph format */
    936     switch ( glyph_format )
    937     {
    938     case 1:
    939     case 2:
    940     case 8:
    941     case 17:
    942       error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 0 );
    943       break;
    944 
    945     case 6:
    946     case 7:
    947     case 9:
    948     case 18:
    949       error = tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 );
    950       break;
    951 
    952     default:
    953       error = FT_Err_Ok;
    954     }
    955 
    956     if ( error )
    957       goto Fail;
    958 
    959     {
    960       TT_SBitDecoder_LoadFunc  loader;
    961 
    962 
    963       switch ( glyph_format )
    964       {
    965       case 1:
    966       case 6:
    967         loader = tt_sbit_decoder_load_byte_aligned;
    968         break;
    969 
    970       case 2:
    971       case 7:
    972         {
    973           /* Don't trust `glyph_format'.  For example, Apple's main Korean */
    974           /* system font, `AppleMyungJo.ttf' (version 7.0d2e6), uses glyph */
    975           /* format 7, but the data is format 6.  We check whether we have */
    976           /* an excessive number of bytes in the image: If it is equal to  */
    977           /* the value for a byte-aligned glyph, use the other loading     */
    978           /* routine.                                                      */
    979           /*                                                               */
    980           /* Note that for some (width,height) combinations, where the     */
    981           /* width is not a multiple of 8, the sizes for bit- and          */
    982           /* byte-aligned data are equal, for example (7,7) or (15,6).  We */
    983           /* then prefer what `glyph_format' specifies.                    */
    984 
    985           FT_UInt  width  = decoder->metrics->width;
    986           FT_UInt  height = decoder->metrics->height;
    987 
    988           FT_UInt  bit_size  = ( width * height + 7 ) >> 3;
    989           FT_UInt  byte_size = height * ( ( width + 7 ) >> 3 );
    990 
    991 
    992           if ( bit_size < byte_size                  &&
    993                byte_size == (FT_UInt)( p_limit - p ) )
    994             loader = tt_sbit_decoder_load_byte_aligned;
    995           else
    996             loader = tt_sbit_decoder_load_bit_aligned;
    997         }
    998         break;
    999 
   1000       case 5:
   1001         loader = tt_sbit_decoder_load_bit_aligned;
   1002         break;
   1003 
   1004       case 8:
   1005         if ( p + 1 > p_limit )
   1006           goto Fail;
   1007 
   1008         p += 1;  /* skip padding */
   1009         /* fall-through */
   1010 
   1011       case 9:
   1012         loader = tt_sbit_decoder_load_compound;
   1013         break;
   1014 
   1015       case 17: /* small metrics, PNG image data   */
   1016       case 18: /* big metrics, PNG image data     */
   1017       case 19: /* metrics in EBLC, PNG image data */
   1018 #ifdef FT_CONFIG_OPTION_USE_PNG
   1019         loader = tt_sbit_decoder_load_png;
   1020         break;
   1021 #else
   1022         error = FT_THROW( Unimplemented_Feature );
   1023         goto Fail;
   1024 #endif /* FT_CONFIG_OPTION_USE_PNG */
   1025 
   1026       default:
   1027         error = FT_THROW( Invalid_Table );
   1028         goto Fail;
   1029       }
   1030 
   1031       if ( !decoder->bitmap_allocated )
   1032       {
   1033         error = tt_sbit_decoder_alloc_bitmap( decoder );
   1034         if ( error )
   1035           goto Fail;
   1036       }
   1037 
   1038       error = loader( decoder, p, p_limit, x_pos, y_pos );
   1039     }
   1040 
   1041   Fail:
   1042     FT_FRAME_RELEASE( data );
   1043 
   1044   Exit:
   1045     return error;
   1046   }
   1047 
   1048 
   1049   static FT_Error
   1050   tt_sbit_decoder_load_image( TT_SBitDecoder  decoder,
   1051                               FT_UInt         glyph_index,
   1052                               FT_Int          x_pos,
   1053                               FT_Int          y_pos )
   1054   {
   1055     /*
   1056      *  First, we find the correct strike range that applies to this
   1057      *  glyph index.
   1058      */
   1059 
   1060     FT_Byte*  p          = decoder->eblc_base + decoder->strike_index_array;
   1061     FT_Byte*  p_limit    = decoder->eblc_limit;
   1062     FT_ULong  num_ranges = decoder->strike_index_count;
   1063     FT_UInt   start, end, index_format, image_format;
   1064     FT_ULong  image_start = 0, image_end = 0, image_offset;
   1065 
   1066 
   1067     for ( ; num_ranges > 0; num_ranges-- )
   1068     {
   1069       start = FT_NEXT_USHORT( p );
   1070       end   = FT_NEXT_USHORT( p );
   1071 
   1072       if ( glyph_index >= start && glyph_index <= end )
   1073         goto FoundRange;
   1074 
   1075       p += 4;  /* ignore index offset */
   1076     }
   1077     goto NoBitmap;
   1078 
   1079   FoundRange:
   1080     image_offset = FT_NEXT_ULONG( p );
   1081 
   1082     /* overflow check */
   1083     p = decoder->eblc_base + decoder->strike_index_array;
   1084     if ( image_offset > (FT_ULong)( p_limit - p ) )
   1085       goto Failure;
   1086 
   1087     p += image_offset;
   1088     if ( p + 8 > p_limit )
   1089       goto NoBitmap;
   1090 
   1091     /* now find the glyph's location and extend within the ebdt table */
   1092     index_format = FT_NEXT_USHORT( p );
   1093     image_format = FT_NEXT_USHORT( p );
   1094     image_offset = FT_NEXT_ULONG ( p );
   1095 
   1096     switch ( index_format )
   1097     {
   1098     case 1: /* 4-byte offsets relative to `image_offset' */
   1099       p += 4 * ( glyph_index - start );
   1100       if ( p + 8 > p_limit )
   1101         goto NoBitmap;
   1102 
   1103       image_start = FT_NEXT_ULONG( p );
   1104       image_end   = FT_NEXT_ULONG( p );
   1105 
   1106       if ( image_start == image_end )  /* missing glyph */
   1107         goto NoBitmap;
   1108       break;
   1109 
   1110     case 2: /* big metrics, constant image size */
   1111       {
   1112         FT_ULong  image_size;
   1113 
   1114 
   1115         if ( p + 12 > p_limit )
   1116           goto NoBitmap;
   1117 
   1118         image_size = FT_NEXT_ULONG( p );
   1119 
   1120         if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
   1121           goto NoBitmap;
   1122 
   1123         image_start = image_size * ( glyph_index - start );
   1124         image_end   = image_start + image_size;
   1125       }
   1126       break;
   1127 
   1128     case 3: /* 2-byte offsets relative to 'image_offset' */
   1129       p += 2 * ( glyph_index - start );
   1130       if ( p + 4 > p_limit )
   1131         goto NoBitmap;
   1132 
   1133       image_start = FT_NEXT_USHORT( p );
   1134       image_end   = FT_NEXT_USHORT( p );
   1135 
   1136       if ( image_start == image_end )  /* missing glyph */
   1137         goto NoBitmap;
   1138       break;
   1139 
   1140     case 4: /* sparse glyph array with (glyph,offset) pairs */
   1141       {
   1142         FT_ULong  mm, num_glyphs;
   1143 
   1144 
   1145         if ( p + 4 > p_limit )
   1146           goto NoBitmap;
   1147 
   1148         num_glyphs = FT_NEXT_ULONG( p );
   1149 
   1150         /* overflow check for p + ( num_glyphs + 1 ) * 4 */
   1151         if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) )
   1152           goto NoBitmap;
   1153 
   1154         for ( mm = 0; mm < num_glyphs; mm++ )
   1155         {
   1156           FT_UInt  gindex = FT_NEXT_USHORT( p );
   1157 
   1158 
   1159           if ( gindex == glyph_index )
   1160           {
   1161             image_start = FT_NEXT_USHORT( p );
   1162             p          += 2;
   1163             image_end   = FT_PEEK_USHORT( p );
   1164             break;
   1165           }
   1166           p += 2;
   1167         }
   1168 
   1169         if ( mm >= num_glyphs )
   1170           goto NoBitmap;
   1171       }
   1172       break;
   1173 
   1174     case 5: /* constant metrics with sparse glyph codes */
   1175     case 19:
   1176       {
   1177         FT_ULong  image_size, mm, num_glyphs;
   1178 
   1179 
   1180         if ( p + 16 > p_limit )
   1181           goto NoBitmap;
   1182 
   1183         image_size = FT_NEXT_ULONG( p );
   1184 
   1185         if ( tt_sbit_decoder_load_metrics( decoder, &p, p_limit, 1 ) )
   1186           goto NoBitmap;
   1187 
   1188         num_glyphs = FT_NEXT_ULONG( p );
   1189 
   1190         /* overflow check for p + 2 * num_glyphs */
   1191         if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) )
   1192           goto NoBitmap;
   1193 
   1194         for ( mm = 0; mm < num_glyphs; mm++ )
   1195         {
   1196           FT_UInt  gindex = FT_NEXT_USHORT( p );
   1197 
   1198 
   1199           if ( gindex == glyph_index )
   1200             break;
   1201         }
   1202 
   1203         if ( mm >= num_glyphs )
   1204           goto NoBitmap;
   1205 
   1206         image_start = image_size * mm;
   1207         image_end   = image_start + image_size;
   1208       }
   1209       break;
   1210 
   1211     default:
   1212       goto NoBitmap;
   1213     }
   1214 
   1215     if ( image_start > image_end )
   1216       goto NoBitmap;
   1217 
   1218     image_end  -= image_start;
   1219     image_start = image_offset + image_start;
   1220 
   1221     FT_TRACE3(( "tt_sbit_decoder_load_image:"
   1222                 " found sbit (format %d) for glyph index %d\n",
   1223                 image_format, glyph_index ));
   1224 
   1225     return tt_sbit_decoder_load_bitmap( decoder,
   1226                                         image_format,
   1227                                         image_start,
   1228                                         image_end,
   1229                                         x_pos,
   1230                                         y_pos );
   1231 
   1232   Failure:
   1233     return FT_THROW( Invalid_Table );
   1234 
   1235   NoBitmap:
   1236     FT_TRACE4(( "tt_sbit_decoder_load_image:"
   1237                 " no sbit found for glyph index %d\n", glyph_index ));
   1238 
   1239     return FT_THROW( Invalid_Argument );
   1240   }
   1241 
   1242 
   1243   static FT_Error
   1244   tt_face_load_sbix_image( TT_Face              face,
   1245                            FT_ULong             strike_index,
   1246                            FT_UInt              glyph_index,
   1247                            FT_Stream            stream,
   1248                            FT_Bitmap           *map,
   1249                            TT_SBit_MetricsRec  *metrics )
   1250   {
   1251     FT_UInt   sbix_pos, strike_offset, glyph_start, glyph_end;
   1252     FT_ULong  table_size;
   1253     FT_Int    originOffsetX, originOffsetY;
   1254     FT_Tag    graphicType;
   1255     FT_Int    recurse_depth = 0;
   1256 
   1257     FT_Error  error;
   1258     FT_Byte*  p;
   1259 
   1260     FT_UNUSED( map );
   1261 
   1262 
   1263     metrics->width  = 0;
   1264     metrics->height = 0;
   1265 
   1266     p = face->sbit_table + 8 + 4 * strike_index;
   1267     strike_offset = FT_NEXT_ULONG( p );
   1268 
   1269     error = face->goto_table( face, TTAG_sbix, stream, &table_size );
   1270     if ( error )
   1271       return error;
   1272     sbix_pos = FT_STREAM_POS();
   1273 
   1274   retry:
   1275     if ( glyph_index > (FT_UInt)face->root.num_glyphs )
   1276       return FT_THROW( Invalid_Argument );
   1277 
   1278     if ( strike_offset >= table_size                          ||
   1279          table_size - strike_offset < 4 + glyph_index * 4 + 8 )
   1280       return FT_THROW( Invalid_File_Format );
   1281 
   1282     if ( FT_STREAM_SEEK( sbix_pos + strike_offset + 4 + glyph_index * 4 ) ||
   1283          FT_FRAME_ENTER( 8 )                                              )
   1284       return error;
   1285 
   1286     glyph_start = FT_GET_ULONG();
   1287     glyph_end   = FT_GET_ULONG();
   1288 
   1289     FT_FRAME_EXIT();
   1290 
   1291     if ( glyph_start == glyph_end )
   1292       return FT_THROW( Invalid_Argument );
   1293     if ( glyph_start > glyph_end                ||
   1294          glyph_end - glyph_start < 8            ||
   1295          table_size - strike_offset < glyph_end )
   1296       return FT_THROW( Invalid_File_Format );
   1297 
   1298     if ( FT_STREAM_SEEK( sbix_pos + strike_offset + glyph_start ) ||
   1299          FT_FRAME_ENTER( glyph_end - glyph_start )                )
   1300       return error;
   1301 
   1302     originOffsetX = FT_GET_SHORT();
   1303     originOffsetY = FT_GET_SHORT();
   1304 
   1305     graphicType = FT_GET_TAG4();
   1306 
   1307     switch ( graphicType )
   1308     {
   1309     case FT_MAKE_TAG( 'd', 'u', 'p', 'e' ):
   1310       if ( recurse_depth < 4 )
   1311       {
   1312         glyph_index = FT_GET_USHORT();
   1313         FT_FRAME_EXIT();
   1314         recurse_depth++;
   1315         goto retry;
   1316       }
   1317       error = FT_THROW( Invalid_File_Format );
   1318       break;
   1319 
   1320     case FT_MAKE_TAG( 'p', 'n', 'g', ' ' ):
   1321 #ifdef FT_CONFIG_OPTION_USE_PNG
   1322       error = Load_SBit_Png( face->root.glyph,
   1323                              0,
   1324                              0,
   1325                              32,
   1326                              metrics,
   1327                              stream->memory,
   1328                              stream->cursor,
   1329                              glyph_end - glyph_start - 8,
   1330                              TRUE );
   1331 #else
   1332       error = FT_THROW( Unimplemented_Feature );
   1333 #endif
   1334       break;
   1335 
   1336     case FT_MAKE_TAG( 'j', 'p', 'g', ' ' ):
   1337     case FT_MAKE_TAG( 't', 'i', 'f', 'f' ):
   1338       error = FT_THROW( Unknown_File_Format );
   1339       break;
   1340 
   1341     default:
   1342       error = FT_THROW( Unimplemented_Feature );
   1343       break;
   1344     }
   1345 
   1346     FT_FRAME_EXIT();
   1347 
   1348     if ( !error )
   1349     {
   1350       FT_Short   abearing;
   1351       FT_UShort  aadvance;
   1352 
   1353 
   1354       tt_face_get_metrics( face, FALSE, glyph_index, &abearing, &aadvance );
   1355 
   1356       metrics->horiBearingX = (FT_Short)originOffsetX;
   1357       metrics->horiBearingY = (FT_Short)( -originOffsetY + metrics->height );
   1358       metrics->horiAdvance  = (FT_Short)( aadvance *
   1359                                           face->root.size->metrics.x_ppem /
   1360                                           face->header.Units_Per_EM );
   1361     }
   1362 
   1363     return error;
   1364   }
   1365 
   1366   FT_LOCAL( FT_Error )
   1367   tt_face_load_sbit_image( TT_Face              face,
   1368                            FT_ULong             strike_index,
   1369                            FT_UInt              glyph_index,
   1370                            FT_UInt              load_flags,
   1371                            FT_Stream            stream,
   1372                            FT_Bitmap           *map,
   1373                            TT_SBit_MetricsRec  *metrics )
   1374   {
   1375     FT_Error  error = FT_Err_Ok;
   1376 
   1377 
   1378     switch ( (FT_UInt)face->sbit_table_type )
   1379     {
   1380     case TT_SBIT_TABLE_TYPE_EBLC:
   1381     case TT_SBIT_TABLE_TYPE_CBLC:
   1382       {
   1383         TT_SBitDecoderRec  decoder[1];
   1384 
   1385 
   1386         error = tt_sbit_decoder_init( decoder, face, strike_index, metrics );
   1387         if ( !error )
   1388         {
   1389           error = tt_sbit_decoder_load_image( decoder,
   1390                                               glyph_index,
   1391                                               0,
   1392                                               0 );
   1393           tt_sbit_decoder_done( decoder );
   1394         }
   1395       }
   1396       break;
   1397 
   1398     case TT_SBIT_TABLE_TYPE_SBIX:
   1399       error = tt_face_load_sbix_image( face,
   1400                                        strike_index,
   1401                                        glyph_index,
   1402                                        stream,
   1403                                        map,
   1404                                        metrics );
   1405       break;
   1406 
   1407     default:
   1408       error = FT_THROW( Unknown_File_Format );
   1409       break;
   1410     }
   1411 
   1412     /* Flatten color bitmaps if color was not requested. */
   1413     if ( !error                                &&
   1414          !( load_flags & FT_LOAD_COLOR )       &&
   1415          map->pixel_mode == FT_PIXEL_MODE_BGRA )
   1416     {
   1417       FT_Bitmap   new_map;
   1418       FT_Library  library = face->root.glyph->library;
   1419 
   1420 
   1421       FT_Bitmap_New( &new_map );
   1422 
   1423       /* Convert to 8bit grayscale. */
   1424       error = FT_Bitmap_Convert( library, map, &new_map, 1 );
   1425       if ( error )
   1426         FT_Bitmap_Done( library, &new_map );
   1427       else
   1428       {
   1429         map->pixel_mode = new_map.pixel_mode;
   1430         map->pitch      = new_map.pitch;
   1431         map->num_grays  = new_map.num_grays;
   1432 
   1433         ft_glyphslot_set_bitmap( face->root.glyph, new_map.buffer );
   1434         face->root.glyph->internal->flags |= FT_GLYPH_OWN_BITMAP;
   1435       }
   1436     }
   1437 
   1438     return error;
   1439   }
   1440 
   1441 
   1442 /* EOF */
   1443