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