Imported Upstream version 2.9.1
[platform/upstream/freetype2.git] / src / sfnt / ttsbit.c
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( Missing_Bitmap );
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 */