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