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