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 )
tt_face_load_sbit(TT_Face face,FT_Stream stream)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 )
tt_face_free_sbit(TT_Face face)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 )
tt_face_set_sbit_strike(TT_Face face,FT_Size_Request req,FT_ULong * astrike_index)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 )
tt_face_load_strike_metrics(TT_Face face,FT_ULong strike_index,FT_Size_Metrics * metrics)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] << 6;  /* hori.ascender  */
258         metrics->descender = (FT_Char)strike[17] << 6;  /* 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                                                      ) << 6;
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
tt_sbit_decoder_init(TT_SBitDecoder decoder,TT_Face face,FT_ULong strike_index,TT_SBit_MetricsRec * metrics)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
tt_sbit_decoder_done(TT_SBitDecoder decoder)415   tt_sbit_decoder_done( TT_SBitDecoder  decoder )
416   {
417     FT_UNUSED( decoder );
418   }
419 
420 
421   static FT_Error
tt_sbit_decoder_alloc_bitmap(TT_SBitDecoder decoder)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
tt_sbit_decoder_load_metrics(TT_SBitDecoder decoder,FT_Byte ** pp,FT_Byte * limit,FT_Bool big)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
tt_sbit_decoder_load_byte_aligned(TT_SBitDecoder decoder,FT_Byte * p,FT_Byte * limit,FT_Int x_pos,FT_Int y_pos)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
tt_sbit_decoder_load_bit_aligned(TT_SBitDecoder decoder,FT_Byte * p,FT_Byte * limit,FT_Int x_pos,FT_Int y_pos)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
tt_sbit_decoder_load_compound(TT_SBitDecoder decoder,FT_Byte * p,FT_Byte * limit,FT_Int x_pos,FT_Int y_pos)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
tt_sbit_decoder_load_png(TT_SBitDecoder decoder,FT_Byte * p,FT_Byte * limit,FT_Int x_pos,FT_Int y_pos)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
tt_sbit_decoder_load_bitmap(TT_SBitDecoder decoder,FT_UInt glyph_format,FT_ULong glyph_start,FT_ULong glyph_size,FT_Int x_pos,FT_Int y_pos)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
tt_sbit_decoder_load_image(TT_SBitDecoder decoder,FT_UInt glyph_index,FT_Int x_pos,FT_Int y_pos)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
tt_face_load_sbix_image(TT_Face face,FT_ULong strike_index,FT_UInt glyph_index,FT_Stream stream,FT_Bitmap * map,TT_SBit_MetricsRec * metrics)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 )
tt_face_load_sbit_image(TT_Face face,FT_ULong strike_index,FT_UInt glyph_index,FT_UInt load_flags,FT_Stream stream,FT_Bitmap * map,TT_SBit_MetricsRec * metrics)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