• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  *
3  * pfrsbit.c
4  *
5  *   FreeType PFR bitmap loader (body).
6  *
7  * Copyright 2002-2018 by
8  * David Turner, Robert Wilhelm, and Werner Lemberg.
9  *
10  * This file is part of the FreeType project, and may only be used,
11  * modified, and distributed under the terms of the FreeType project
12  * license, LICENSE.TXT.  By continuing to use, modify, or distribute
13  * this file you indicate that you have read the license and
14  * understand and accept it fully.
15  *
16  */
17 
18 
19 #include "pfrsbit.h"
20 #include "pfrload.h"
21 #include FT_INTERNAL_DEBUG_H
22 #include FT_INTERNAL_STREAM_H
23 
24 #include "pfrerror.h"
25 
26 #undef  FT_COMPONENT
27 #define FT_COMPONENT  trace_pfr
28 
29 
30   /*************************************************************************/
31   /*************************************************************************/
32   /*****                                                               *****/
33   /*****                      PFR BIT WRITER                           *****/
34   /*****                                                               *****/
35   /*************************************************************************/
36   /*************************************************************************/
37 
38   typedef struct  PFR_BitWriter_
39   {
40     FT_Byte*  line;      /* current line start               */
41     FT_Int    pitch;     /* line size in bytes               */
42     FT_UInt   width;     /* width in pixels/bits             */
43     FT_UInt   rows;      /* number of remaining rows to scan */
44     FT_UInt   total;     /* total number of bits to draw     */
45 
46   } PFR_BitWriterRec, *PFR_BitWriter;
47 
48 
49   static void
pfr_bitwriter_init(PFR_BitWriter writer,FT_Bitmap * target,FT_Bool decreasing)50   pfr_bitwriter_init( PFR_BitWriter  writer,
51                       FT_Bitmap*     target,
52                       FT_Bool        decreasing )
53   {
54     writer->line   = target->buffer;
55     writer->pitch  = target->pitch;
56     writer->width  = target->width;
57     writer->rows   = target->rows;
58     writer->total  = writer->width * writer->rows;
59 
60     if ( !decreasing )
61     {
62       writer->line += writer->pitch * (FT_Int)( target->rows - 1 );
63       writer->pitch = -writer->pitch;
64     }
65   }
66 
67 
68   static void
pfr_bitwriter_decode_bytes(PFR_BitWriter writer,FT_Byte * p,FT_Byte * limit)69   pfr_bitwriter_decode_bytes( PFR_BitWriter  writer,
70                               FT_Byte*       p,
71                               FT_Byte*       limit )
72   {
73     FT_UInt   n, reload;
74     FT_UInt   left = writer->width;
75     FT_Byte*  cur  = writer->line;
76     FT_UInt   mask = 0x80;
77     FT_UInt   val  = 0;
78     FT_UInt   c    = 0;
79 
80 
81     n = (FT_UInt)( limit - p ) * 8;
82     if ( n > writer->total )
83       n = writer->total;
84 
85     reload = n & 7;
86 
87     for ( ; n > 0; n-- )
88     {
89       if ( ( n & 7 ) == reload )
90         val = *p++;
91 
92       if ( val & 0x80 )
93         c |= mask;
94 
95       val  <<= 1;
96       mask >>= 1;
97 
98       if ( --left <= 0 )
99       {
100         cur[0] = (FT_Byte)c;
101         left   = writer->width;
102         mask   = 0x80;
103 
104         writer->line += writer->pitch;
105         cur           = writer->line;
106         c             = 0;
107       }
108       else if ( mask == 0 )
109       {
110         cur[0] = (FT_Byte)c;
111         mask   = 0x80;
112         c      = 0;
113         cur++;
114       }
115     }
116 
117     if ( mask != 0x80 )
118       cur[0] = (FT_Byte)c;
119   }
120 
121 
122   static void
pfr_bitwriter_decode_rle1(PFR_BitWriter writer,FT_Byte * p,FT_Byte * limit)123   pfr_bitwriter_decode_rle1( PFR_BitWriter  writer,
124                              FT_Byte*       p,
125                              FT_Byte*       limit )
126   {
127     FT_Int    phase, count, counts[2];
128     FT_UInt   n, reload;
129     FT_UInt   left = writer->width;
130     FT_Byte*  cur  = writer->line;
131     FT_UInt   mask = 0x80;
132     FT_UInt   c    = 0;
133 
134 
135     n = writer->total;
136 
137     phase     = 1;
138     counts[0] = 0;
139     counts[1] = 0;
140     count     = 0;
141     reload    = 1;
142 
143     for ( ; n > 0; n-- )
144     {
145       if ( reload )
146       {
147         do
148         {
149           if ( phase )
150           {
151             FT_Int  v;
152 
153 
154             if ( p >= limit )
155               break;
156 
157             v         = *p++;
158             counts[0] = v >> 4;
159             counts[1] = v & 15;
160             phase     = 0;
161             count     = counts[0];
162           }
163           else
164           {
165             phase = 1;
166             count = counts[1];
167           }
168 
169         } while ( count == 0 );
170       }
171 
172       if ( phase )
173         c |= mask;
174 
175       mask >>= 1;
176 
177       if ( --left <= 0 )
178       {
179         cur[0] = (FT_Byte)c;
180         left   = writer->width;
181         mask   = 0x80;
182 
183         writer->line += writer->pitch;
184         cur           = writer->line;
185         c             = 0;
186       }
187       else if ( mask == 0 )
188       {
189         cur[0] = (FT_Byte)c;
190         mask   = 0x80;
191         c      = 0;
192         cur++;
193       }
194 
195       reload = ( --count <= 0 );
196     }
197 
198     if ( mask != 0x80 )
199       cur[0] = (FT_Byte) c;
200   }
201 
202 
203   static void
pfr_bitwriter_decode_rle2(PFR_BitWriter writer,FT_Byte * p,FT_Byte * limit)204   pfr_bitwriter_decode_rle2( PFR_BitWriter  writer,
205                              FT_Byte*       p,
206                              FT_Byte*       limit )
207   {
208     FT_Int    phase, count;
209     FT_UInt   n, reload;
210     FT_UInt   left = writer->width;
211     FT_Byte*  cur  = writer->line;
212     FT_UInt   mask = 0x80;
213     FT_UInt   c    = 0;
214 
215 
216     n = writer->total;
217 
218     phase  = 1;
219     count  = 0;
220     reload = 1;
221 
222     for ( ; n > 0; n-- )
223     {
224       if ( reload )
225       {
226         do
227         {
228           if ( p >= limit )
229             break;
230 
231           count = *p++;
232           phase = phase ^ 1;
233 
234         } while ( count == 0 );
235       }
236 
237       if ( phase )
238         c |= mask;
239 
240       mask >>= 1;
241 
242       if ( --left <= 0 )
243       {
244         cur[0] = (FT_Byte)c;
245         c      = 0;
246         mask   = 0x80;
247         left   = writer->width;
248 
249         writer->line += writer->pitch;
250         cur           = writer->line;
251       }
252       else if ( mask == 0 )
253       {
254         cur[0] = (FT_Byte)c;
255         c      = 0;
256         mask   = 0x80;
257         cur++;
258       }
259 
260       reload = ( --count <= 0 );
261     }
262 
263     if ( mask != 0x80 )
264       cur[0] = (FT_Byte) c;
265   }
266 
267 
268   /*************************************************************************/
269   /*************************************************************************/
270   /*****                                                               *****/
271   /*****                  BITMAP DATA DECODING                         *****/
272   /*****                                                               *****/
273   /*************************************************************************/
274   /*************************************************************************/
275 
276   static void
pfr_lookup_bitmap_data(FT_Byte * base,FT_Byte * limit,FT_UInt count,FT_UInt * flags,FT_UInt char_code,FT_ULong * found_offset,FT_ULong * found_size)277   pfr_lookup_bitmap_data( FT_Byte*   base,
278                           FT_Byte*   limit,
279                           FT_UInt    count,
280                           FT_UInt*   flags,
281                           FT_UInt    char_code,
282                           FT_ULong*  found_offset,
283                           FT_ULong*  found_size )
284   {
285     FT_UInt   min, max, char_len;
286     FT_Bool   two = FT_BOOL( *flags & PFR_BITMAP_2BYTE_CHARCODE );
287     FT_Byte*  buff;
288 
289 
290     char_len = 4;
291     if ( two )
292       char_len += 1;
293     if ( *flags & PFR_BITMAP_2BYTE_SIZE )
294       char_len += 1;
295     if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
296       char_len += 1;
297 
298     if ( !( *flags & PFR_BITMAP_CHARCODES_VALIDATED ) )
299     {
300       FT_Byte*  p;
301       FT_Byte*  lim;
302       FT_UInt   code;
303       FT_Long   prev_code;
304 
305 
306       *flags    |= PFR_BITMAP_VALID_CHARCODES;
307       prev_code  = -1;
308       lim        = base + count * char_len;
309 
310       if ( lim > limit )
311       {
312         FT_TRACE0(( "pfr_lookup_bitmap_data:"
313                     " number of bitmap records too large,\n"
314                     "                       "
315                     " thus ignoring all bitmaps in this strike\n" ));
316         *flags &= ~PFR_BITMAP_VALID_CHARCODES;
317       }
318       else
319       {
320         /* check whether records are sorted by code */
321         for ( p = base; p < lim; p += char_len )
322         {
323           if ( two )
324             code = FT_PEEK_USHORT( p );
325           else
326             code = *p;
327 
328           if ( (FT_Long)code <= prev_code )
329           {
330             FT_TRACE0(( "pfr_lookup_bitmap_data:"
331                         " bitmap records are not sorted,\n"
332                         "                       "
333                         " thus ignoring all bitmaps in this strike\n" ));
334             *flags &= ~PFR_BITMAP_VALID_CHARCODES;
335             break;
336           }
337 
338           prev_code = code;
339         }
340       }
341 
342       *flags |= PFR_BITMAP_CHARCODES_VALIDATED;
343     }
344 
345     /* ignore bitmaps in case table is not valid     */
346     /* (this might be sanitized, but PFR is dead...) */
347     if ( !( *flags & PFR_BITMAP_VALID_CHARCODES ) )
348       goto Fail;
349 
350     min = 0;
351     max = count;
352 
353     /* binary search */
354     while ( min < max )
355     {
356       FT_UInt  mid, code;
357 
358 
359       mid  = ( min + max ) >> 1;
360       buff = base + mid * char_len;
361 
362       if ( two )
363         code = PFR_NEXT_USHORT( buff );
364       else
365         code = PFR_NEXT_BYTE( buff );
366 
367       if ( char_code < code )
368         max = mid;
369       else if ( char_code > code )
370         min = mid + 1;
371       else
372         goto Found_It;
373     }
374 
375   Fail:
376     /* Not found */
377     *found_size   = 0;
378     *found_offset = 0;
379     return;
380 
381   Found_It:
382     if ( *flags & PFR_BITMAP_2BYTE_SIZE )
383       *found_size = PFR_NEXT_USHORT( buff );
384     else
385       *found_size = PFR_NEXT_BYTE( buff );
386 
387     if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
388       *found_offset = PFR_NEXT_ULONG( buff );
389     else
390       *found_offset = PFR_NEXT_USHORT( buff );
391   }
392 
393 
394   /* load bitmap metrics.  `*padvance' must be set to the default value */
395   /* before calling this function                                       */
396   /*                                                                    */
397   static FT_Error
pfr_load_bitmap_metrics(FT_Byte ** pdata,FT_Byte * limit,FT_Long scaled_advance,FT_Long * axpos,FT_Long * aypos,FT_UInt * axsize,FT_UInt * aysize,FT_Long * aadvance,FT_UInt * aformat)398   pfr_load_bitmap_metrics( FT_Byte**  pdata,
399                            FT_Byte*   limit,
400                            FT_Long    scaled_advance,
401                            FT_Long   *axpos,
402                            FT_Long   *aypos,
403                            FT_UInt   *axsize,
404                            FT_UInt   *aysize,
405                            FT_Long   *aadvance,
406                            FT_UInt   *aformat )
407   {
408     FT_Error  error = FT_Err_Ok;
409     FT_Byte   flags;
410     FT_Byte   b;
411     FT_Byte*  p = *pdata;
412     FT_Long   xpos, ypos, advance;
413     FT_UInt   xsize, ysize;
414 
415 
416     PFR_CHECK( 1 );
417     flags = PFR_NEXT_BYTE( p );
418 
419     xpos    = 0;
420     ypos    = 0;
421     xsize   = 0;
422     ysize   = 0;
423     advance = 0;
424 
425     switch ( flags & 3 )
426     {
427     case 0:
428       PFR_CHECK( 1 );
429       b    = PFR_NEXT_BYTE( p );
430       xpos = (FT_Char)b >> 4;
431       ypos = ( (FT_Char)( b << 4 ) ) >> 4;
432       break;
433 
434     case 1:
435       PFR_CHECK( 2 );
436       xpos = PFR_NEXT_INT8( p );
437       ypos = PFR_NEXT_INT8( p );
438       break;
439 
440     case 2:
441       PFR_CHECK( 4 );
442       xpos = PFR_NEXT_SHORT( p );
443       ypos = PFR_NEXT_SHORT( p );
444       break;
445 
446     case 3:
447       PFR_CHECK( 6 );
448       xpos = PFR_NEXT_LONG( p );
449       ypos = PFR_NEXT_LONG( p );
450       break;
451 
452     default:
453       ;
454     }
455 
456     flags >>= 2;
457     switch ( flags & 3 )
458     {
459     case 0:
460       /* blank image */
461       xsize = 0;
462       ysize = 0;
463       break;
464 
465     case 1:
466       PFR_CHECK( 1 );
467       b     = PFR_NEXT_BYTE( p );
468       xsize = ( b >> 4 ) & 0xF;
469       ysize = b & 0xF;
470       break;
471 
472     case 2:
473       PFR_CHECK( 2 );
474       xsize = PFR_NEXT_BYTE( p );
475       ysize = PFR_NEXT_BYTE( p );
476       break;
477 
478     case 3:
479       PFR_CHECK( 4 );
480       xsize = PFR_NEXT_USHORT( p );
481       ysize = PFR_NEXT_USHORT( p );
482       break;
483 
484     default:
485       ;
486     }
487 
488     flags >>= 2;
489     switch ( flags & 3 )
490     {
491     case 0:
492       advance = scaled_advance;
493       break;
494 
495     case 1:
496       PFR_CHECK( 1 );
497       advance = PFR_NEXT_INT8( p ) * 256;
498       break;
499 
500     case 2:
501       PFR_CHECK( 2 );
502       advance = PFR_NEXT_SHORT( p );
503       break;
504 
505     case 3:
506       PFR_CHECK( 3 );
507       advance = PFR_NEXT_LONG( p );
508       break;
509 
510     default:
511       ;
512     }
513 
514     *axpos    = xpos;
515     *aypos    = ypos;
516     *axsize   = xsize;
517     *aysize   = ysize;
518     *aadvance = advance;
519     *aformat  = flags >> 2;
520     *pdata    = p;
521 
522   Exit:
523     return error;
524 
525   Too_Short:
526     error = FT_THROW( Invalid_Table );
527     FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" ));
528     goto Exit;
529   }
530 
531 
532   static FT_Error
pfr_load_bitmap_bits(FT_Byte * p,FT_Byte * limit,FT_UInt format,FT_Bool decreasing,FT_Bitmap * target)533   pfr_load_bitmap_bits( FT_Byte*    p,
534                         FT_Byte*    limit,
535                         FT_UInt     format,
536                         FT_Bool     decreasing,
537                         FT_Bitmap*  target )
538   {
539     FT_Error          error = FT_Err_Ok;
540     PFR_BitWriterRec  writer;
541 
542 
543     if ( target->rows > 0 && target->width > 0 )
544     {
545       pfr_bitwriter_init( &writer, target, decreasing );
546 
547       switch ( format )
548       {
549       case 0: /* packed bits */
550         pfr_bitwriter_decode_bytes( &writer, p, limit );
551         break;
552 
553       case 1: /* RLE1 */
554         pfr_bitwriter_decode_rle1( &writer, p, limit );
555         break;
556 
557       case 2: /* RLE2 */
558         pfr_bitwriter_decode_rle2( &writer, p, limit );
559         break;
560 
561       default:
562         ;
563       }
564     }
565 
566     return error;
567   }
568 
569 
570   /*************************************************************************/
571   /*************************************************************************/
572   /*****                                                               *****/
573   /*****                     BITMAP LOADING                            *****/
574   /*****                                                               *****/
575   /*************************************************************************/
576   /*************************************************************************/
577 
578   FT_LOCAL( FT_Error )
pfr_slot_load_bitmap(PFR_Slot glyph,PFR_Size size,FT_UInt glyph_index,FT_Bool metrics_only)579   pfr_slot_load_bitmap( PFR_Slot  glyph,
580                         PFR_Size  size,
581                         FT_UInt   glyph_index,
582                         FT_Bool   metrics_only )
583   {
584     FT_Error     error;
585     PFR_Face     face   = (PFR_Face) glyph->root.face;
586     FT_Stream    stream = face->root.stream;
587     PFR_PhyFont  phys   = &face->phy_font;
588     FT_ULong     gps_offset;
589     FT_ULong     gps_size;
590     PFR_Char     character;
591     PFR_Strike   strike;
592 
593 
594     character = &phys->chars[glyph_index];
595 
596     /* look up a bitmap strike corresponding to the current */
597     /* character dimensions                                 */
598     {
599       FT_UInt  n;
600 
601 
602       strike = phys->strikes;
603       for ( n = 0; n < phys->num_strikes; n++ )
604       {
605         if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem &&
606              strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem )
607           goto Found_Strike;
608 
609         strike++;
610       }
611 
612       /* couldn't find it */
613       return FT_THROW( Invalid_Argument );
614     }
615 
616   Found_Strike:
617 
618     /* now look up the glyph's position within the file */
619     {
620       FT_UInt  char_len;
621 
622 
623       char_len = 4;
624       if ( strike->flags & PFR_BITMAP_2BYTE_CHARCODE )
625         char_len += 1;
626       if ( strike->flags & PFR_BITMAP_2BYTE_SIZE )
627         char_len += 1;
628       if ( strike->flags & PFR_BITMAP_3BYTE_OFFSET )
629         char_len += 1;
630 
631       /* access data directly in the frame to speed lookups */
632       if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) ||
633            FT_FRAME_ENTER( char_len * strike->num_bitmaps )        )
634         goto Exit;
635 
636       pfr_lookup_bitmap_data( stream->cursor,
637                               stream->limit,
638                               strike->num_bitmaps,
639                               &strike->flags,
640                               character->char_code,
641                               &gps_offset,
642                               &gps_size );
643 
644       FT_FRAME_EXIT();
645 
646       if ( gps_size == 0 )
647       {
648         /* could not find a bitmap program string for this glyph */
649         error = FT_THROW( Invalid_Argument );
650         goto Exit;
651       }
652     }
653 
654     /* get the bitmap metrics */
655     {
656       FT_Long   xpos = 0, ypos = 0, advance = 0;
657       FT_UInt   xsize = 0, ysize = 0, format = 0;
658       FT_Byte*  p;
659 
660 
661       /* compute linear advance */
662       advance = character->advance;
663       if ( phys->metrics_resolution != phys->outline_resolution )
664         advance = FT_MulDiv( advance,
665                              (FT_Long)phys->outline_resolution,
666                              (FT_Long)phys->metrics_resolution );
667 
668       glyph->root.linearHoriAdvance = advance;
669 
670       /* compute default advance, i.e., scaled advance; this can be */
671       /* overridden in the bitmap header of certain glyphs          */
672       advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8,
673                            character->advance,
674                            (FT_Long)phys->metrics_resolution );
675 
676       if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) ||
677            FT_FRAME_ENTER( gps_size )                                     )
678         goto Exit;
679 
680       p     = stream->cursor;
681       error = pfr_load_bitmap_metrics( &p, stream->limit,
682                                        advance,
683                                        &xpos, &ypos,
684                                        &xsize, &ysize,
685                                        &advance, &format );
686       if ( error )
687         goto Exit1;
688 
689       /*
690        * Before allocating the target bitmap, we check whether the given
691        * bitmap dimensions are valid, depending on the image format.
692        *
693        * Format 0: We have a stream of pixels (with 8 pixels per byte).
694        *
695        *             (xsize * ysize + 7) / 8 <= gps_size
696        *
697        * Format 1: Run-length encoding; the high nibble holds the number of
698        *           white bits, the low nibble the number of black bits.  In
699        *           other words, a single byte can represent at most 15
700        *           pixels.
701        *
702        *             xsize * ysize <= 15 * gps_size
703        *
704        * Format 2: Run-length encoding; the high byte holds the number of
705        *           white bits, the low byte the number of black bits.  In
706        *           other words, two bytes can represent at most 255 pixels.
707        *
708        *             xsize * ysize <= 255 * (gps_size + 1) / 2
709        */
710       switch ( format )
711       {
712       case 0:
713         if ( ( (FT_ULong)xsize * ysize + 7 ) / 8 > gps_size )
714           error = FT_THROW( Invalid_Table );
715         break;
716       case 1:
717         if ( (FT_ULong)xsize * ysize > 15 * gps_size )
718           error = FT_THROW( Invalid_Table );
719         break;
720       case 2:
721         if ( (FT_ULong)xsize * ysize > 255 * ( ( gps_size + 1 ) / 2 ) )
722           error = FT_THROW( Invalid_Table );
723         break;
724       default:
725         FT_ERROR(( "pfr_slot_load_bitmap: invalid image type\n" ));
726         error = FT_THROW( Invalid_Table );
727       }
728 
729       if ( error )
730       {
731         if ( FT_ERR_EQ( error, Invalid_Table ) )
732           FT_ERROR(( "pfr_slot_load_bitmap: invalid bitmap dimensions\n" ));
733         goto Exit1;
734       }
735 
736       /*
737        * XXX: on 16bit systems we return an error for huge bitmaps
738        *      that cause size truncation, because truncated
739        *      size properties make bitmap glyphs broken.
740        */
741       if ( xpos > FT_INT_MAX                  ||
742            xpos < FT_INT_MIN                  ||
743            ysize > FT_INT_MAX                 ||
744            ypos > FT_INT_MAX - (FT_Long)ysize ||
745            ypos + (FT_Long)ysize < FT_INT_MIN )
746       {
747         FT_TRACE1(( "pfr_slot_load_bitmap:" ));
748         FT_TRACE1(( "huge bitmap glyph %dx%d over FT_GlyphSlot\n",
749                      xpos, ypos ));
750         error = FT_THROW( Invalid_Pixel_Size );
751       }
752 
753       if ( !error )
754       {
755         glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
756 
757         /* Set up glyph bitmap and metrics */
758 
759         /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */
760         glyph->root.bitmap.width      = xsize;
761         glyph->root.bitmap.rows       = ysize;
762         glyph->root.bitmap.pitch      = (FT_Int)( xsize + 7 ) >> 3;
763         glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
764 
765         /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */
766         glyph->root.metrics.width        = (FT_Pos)xsize << 6;
767         glyph->root.metrics.height       = (FT_Pos)ysize << 6;
768         glyph->root.metrics.horiBearingX = xpos * 64;
769         glyph->root.metrics.horiBearingY = ypos * 64;
770         glyph->root.metrics.horiAdvance  = FT_PIX_ROUND( ( advance >> 2 ) );
771         glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1;
772         glyph->root.metrics.vertBearingY = 0;
773         glyph->root.metrics.vertAdvance  = size->root.metrics.height;
774 
775         /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */
776         glyph->root.bitmap_left = (FT_Int)xpos;
777         glyph->root.bitmap_top  = (FT_Int)( ypos + (FT_Long)ysize );
778 
779         if ( metrics_only )
780           goto Exit1;
781 
782         /* Allocate and read bitmap data */
783         {
784           FT_ULong  len = (FT_ULong)glyph->root.bitmap.pitch * ysize;
785 
786 
787           error = ft_glyphslot_alloc_bitmap( &glyph->root, len );
788           if ( !error )
789             error = pfr_load_bitmap_bits(
790                       p,
791                       stream->limit,
792                       format,
793                       FT_BOOL( face->header.color_flags &
794                                PFR_FLAG_INVERT_BITMAP   ),
795                       &glyph->root.bitmap );
796         }
797       }
798 
799     Exit1:
800       FT_FRAME_EXIT();
801     }
802 
803   Exit:
804     return error;
805   }
806 
807 
808 /* END */
809