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