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