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