xref: /aosp_15_r20/external/freetype/src/pfr/pfrsbit.c (revision 63949dbd25bcc50c4e1178497ff9e9574d44fc5a)
1 /****************************************************************************
2  *
3  * pfrsbit.c
4  *
5  *   FreeType PFR bitmap loader (body).
6  *
7  * Copyright (C) 2002-2023 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 <freetype/internal/ftdebug.h>
22 #include <freetype/internal/ftstream.h>
23 
24 #include "pfrerror.h"
25 
26 #undef  FT_COMPONENT
27 #define FT_COMPONENT  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, mid, 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         FT_TRACE0(( "                       "
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             FT_TRACE0(( "                       "
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     mid = min + ( max - min ) / 2;
353 
354     /* binary search */
355     while ( min < max )
356     {
357       FT_UInt  code;
358 
359 
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       /* reasonable prediction in a continuous block */
375       mid += char_code - code;
376       if ( mid >= max || mid < min )
377         mid = min + ( max - min ) / 2;
378     }
379 
380   Fail:
381     /* Not found */
382     *found_size   = 0;
383     *found_offset = 0;
384     return;
385 
386   Found_It:
387     if ( *flags & PFR_BITMAP_2BYTE_SIZE )
388       *found_size = PFR_NEXT_USHORT( buff );
389     else
390       *found_size = PFR_NEXT_BYTE( buff );
391 
392     if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
393       *found_offset = PFR_NEXT_ULONG( buff );
394     else
395       *found_offset = PFR_NEXT_USHORT( buff );
396   }
397 
398 
399   /* load bitmap metrics.  `*aadvance' must be set to the default value */
400   /* before calling this function                                       */
401   /*                                                                    */
402   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)403   pfr_load_bitmap_metrics( FT_Byte**  pdata,
404                            FT_Byte*   limit,
405                            FT_Long    scaled_advance,
406                            FT_Long   *axpos,
407                            FT_Long   *aypos,
408                            FT_UInt   *axsize,
409                            FT_UInt   *aysize,
410                            FT_Long   *aadvance,
411                            FT_UInt   *aformat )
412   {
413     FT_Error  error = FT_Err_Ok;
414     FT_Byte   flags;
415     FT_Byte   b;
416     FT_Byte*  p = *pdata;
417     FT_Long   xpos, ypos, advance;
418     FT_UInt   xsize, ysize;
419 
420 
421     PFR_CHECK( 1 );
422     flags = PFR_NEXT_BYTE( p );
423 
424     xpos    = 0;
425     ypos    = 0;
426     xsize   = 0;
427     ysize   = 0;
428     advance = 0;
429 
430     switch ( flags & 3 )
431     {
432     case 0:
433       PFR_CHECK( 1 );
434       b    = PFR_NEXT_BYTE( p );
435       xpos = (FT_Char)b >> 4;
436       ypos = ( (FT_Char)( b << 4 ) ) >> 4;
437       break;
438 
439     case 1:
440       PFR_CHECK( 2 );
441       xpos = PFR_NEXT_INT8( p );
442       ypos = PFR_NEXT_INT8( p );
443       break;
444 
445     case 2:
446       PFR_CHECK( 4 );
447       xpos = PFR_NEXT_SHORT( p );
448       ypos = PFR_NEXT_SHORT( p );
449       break;
450 
451     case 3:
452       PFR_CHECK( 6 );
453       xpos = PFR_NEXT_LONG( p );
454       ypos = PFR_NEXT_LONG( p );
455       break;
456 
457     default:
458       ;
459     }
460 
461     flags >>= 2;
462     switch ( flags & 3 )
463     {
464     case 0:
465       /* blank image */
466       xsize = 0;
467       ysize = 0;
468       break;
469 
470     case 1:
471       PFR_CHECK( 1 );
472       b     = PFR_NEXT_BYTE( p );
473       xsize = ( b >> 4 ) & 0xF;
474       ysize = b & 0xF;
475       break;
476 
477     case 2:
478       PFR_CHECK( 2 );
479       xsize = PFR_NEXT_BYTE( p );
480       ysize = PFR_NEXT_BYTE( p );
481       break;
482 
483     case 3:
484       PFR_CHECK( 4 );
485       xsize = PFR_NEXT_USHORT( p );
486       ysize = PFR_NEXT_USHORT( p );
487       break;
488 
489     default:
490       ;
491     }
492 
493     flags >>= 2;
494     switch ( flags & 3 )
495     {
496     case 0:
497       advance = scaled_advance;
498       break;
499 
500     case 1:
501       PFR_CHECK( 1 );
502       advance = PFR_NEXT_INT8( p ) * 256;
503       break;
504 
505     case 2:
506       PFR_CHECK( 2 );
507       advance = PFR_NEXT_SHORT( p );
508       break;
509 
510     case 3:
511       PFR_CHECK( 3 );
512       advance = PFR_NEXT_LONG( p );
513       break;
514 
515     default:
516       ;
517     }
518 
519     *axpos    = xpos;
520     *aypos    = ypos;
521     *axsize   = xsize;
522     *aysize   = ysize;
523     *aadvance = advance;
524     *aformat  = flags >> 2;
525     *pdata    = p;
526 
527   Exit:
528     return error;
529 
530   Too_Short:
531     error = FT_THROW( Invalid_Table );
532     FT_ERROR(( "pfr_load_bitmap_metrics: invalid glyph data\n" ));
533     goto Exit;
534   }
535 
536 
537   static FT_Error
pfr_load_bitmap_bits(FT_Byte * p,FT_Byte * limit,FT_UInt format,FT_Bool decreasing,FT_Bitmap * target)538   pfr_load_bitmap_bits( FT_Byte*    p,
539                         FT_Byte*    limit,
540                         FT_UInt     format,
541                         FT_Bool     decreasing,
542                         FT_Bitmap*  target )
543   {
544     FT_Error          error = FT_Err_Ok;
545     PFR_BitWriterRec  writer;
546 
547 
548     if ( target->rows > 0 && target->width > 0 )
549     {
550       pfr_bitwriter_init( &writer, target, decreasing );
551 
552       switch ( format )
553       {
554       case 0: /* packed bits */
555         pfr_bitwriter_decode_bytes( &writer, p, limit );
556         break;
557 
558       case 1: /* RLE1 */
559         pfr_bitwriter_decode_rle1( &writer, p, limit );
560         break;
561 
562       case 2: /* RLE2 */
563         pfr_bitwriter_decode_rle2( &writer, p, limit );
564         break;
565 
566       default:
567         ;
568       }
569     }
570 
571     return error;
572   }
573 
574 
575   /*************************************************************************/
576   /*************************************************************************/
577   /*****                                                               *****/
578   /*****                     BITMAP LOADING                            *****/
579   /*****                                                               *****/
580   /*************************************************************************/
581   /*************************************************************************/
582 
583   FT_LOCAL_DEF( FT_Error )
pfr_slot_load_bitmap(PFR_Slot glyph,PFR_Size size,FT_UInt glyph_index,FT_Bool metrics_only)584   pfr_slot_load_bitmap( PFR_Slot  glyph,
585                         PFR_Size  size,
586                         FT_UInt   glyph_index,
587                         FT_Bool   metrics_only )
588   {
589     FT_Error     error;
590     PFR_Face     face   = (PFR_Face) glyph->root.face;
591     FT_Stream    stream = face->root.stream;
592     PFR_PhyFont  phys   = &face->phy_font;
593     FT_ULong     gps_offset;
594     FT_ULong     gps_size;
595     PFR_Char     character;
596     PFR_Strike   strike;
597 
598 
599     character = &phys->chars[glyph_index];
600 
601     /* look up a bitmap strike corresponding to the current */
602     /* character dimensions                                 */
603     {
604       FT_UInt  n;
605 
606 
607       strike = phys->strikes;
608       for ( n = 0; n < phys->num_strikes; n++ )
609       {
610         if ( strike->x_ppm == (FT_UInt)size->root.metrics.x_ppem &&
611              strike->y_ppm == (FT_UInt)size->root.metrics.y_ppem )
612           goto Found_Strike;
613 
614         strike++;
615       }
616 
617       /* couldn't find it */
618       return FT_THROW( Invalid_Argument );
619     }
620 
621   Found_Strike:
622 
623     /* now look up the glyph's position within the file */
624     {
625       FT_UInt  char_len;
626 
627 
628       char_len = 4;
629       if ( strike->flags & PFR_BITMAP_2BYTE_CHARCODE )
630         char_len += 1;
631       if ( strike->flags & PFR_BITMAP_2BYTE_SIZE )
632         char_len += 1;
633       if ( strike->flags & PFR_BITMAP_3BYTE_OFFSET )
634         char_len += 1;
635 
636       /* access data directly in the frame to speed up lookups */
637       if ( FT_STREAM_SEEK( phys->bct_offset + strike->bct_offset ) ||
638            FT_FRAME_ENTER( char_len * strike->num_bitmaps )        )
639         goto Exit;
640 
641       pfr_lookup_bitmap_data( stream->cursor,
642                               stream->limit,
643                               strike->num_bitmaps,
644                               &strike->flags,
645                               character->char_code,
646                               &gps_offset,
647                               &gps_size );
648 
649       FT_FRAME_EXIT();
650 
651       if ( gps_size == 0 )
652       {
653         /* could not find a bitmap program string for this glyph */
654         error = FT_THROW( Invalid_Argument );
655         goto Exit;
656       }
657     }
658 
659     /* get the bitmap metrics */
660     {
661       FT_Long   xpos = 0, ypos = 0, advance = 0;
662       FT_UInt   xsize = 0, ysize = 0, format = 0;
663       FT_Byte*  p;
664 
665 
666       /* compute linear advance */
667       advance = character->advance;
668       if ( phys->metrics_resolution != phys->outline_resolution )
669         advance = FT_MulDiv( advance,
670                              (FT_Long)phys->outline_resolution,
671                              (FT_Long)phys->metrics_resolution );
672 
673       glyph->root.linearHoriAdvance = advance;
674 
675       /* compute default advance, i.e., scaled advance; this can be */
676       /* overridden in the bitmap header of certain glyphs          */
677       advance = FT_MulDiv( (FT_Fixed)size->root.metrics.x_ppem << 8,
678                            character->advance,
679                            (FT_Long)phys->metrics_resolution );
680 
681       if ( FT_STREAM_SEEK( face->header.gps_section_offset + gps_offset ) ||
682            FT_FRAME_ENTER( gps_size )                                     )
683         goto Exit;
684 
685       p     = stream->cursor;
686       error = pfr_load_bitmap_metrics( &p, stream->limit,
687                                        advance,
688                                        &xpos, &ypos,
689                                        &xsize, &ysize,
690                                        &advance, &format );
691       if ( error )
692         goto Exit1;
693 
694       /*
695        * Before allocating the target bitmap, we check whether the given
696        * bitmap dimensions are valid, depending on the image format.
697        *
698        * Format 0: We have a stream of pixels (with 8 pixels per byte).
699        *
700        *             (xsize * ysize + 7) / 8 <= gps_size
701        *
702        * Format 1: Run-length encoding; the high nibble holds the number of
703        *           white bits, the low nibble the number of black bits.  In
704        *           other words, a single byte can represent at most 15
705        *           pixels.
706        *
707        *             xsize * ysize <= 15 * gps_size
708        *
709        * Format 2: Run-length encoding; the high byte holds the number of
710        *           white bits, the low byte the number of black bits.  In
711        *           other words, two bytes can represent at most 255 pixels.
712        *
713        *             xsize * ysize <= 255 * (gps_size + 1) / 2
714        */
715       switch ( format )
716       {
717       case 0:
718         if ( ( (FT_ULong)xsize * ysize + 7 ) / 8 > gps_size )
719           error = FT_THROW( Invalid_Table );
720         break;
721       case 1:
722         if ( (FT_ULong)xsize * ysize > 15 * gps_size )
723           error = FT_THROW( Invalid_Table );
724         break;
725       case 2:
726         if ( (FT_ULong)xsize * ysize > 255 * ( ( gps_size + 1 ) / 2 ) )
727           error = FT_THROW( Invalid_Table );
728         break;
729       default:
730         FT_ERROR(( "pfr_slot_load_bitmap: invalid image type\n" ));
731         error = FT_THROW( Invalid_Table );
732       }
733 
734       if ( error )
735       {
736         if ( FT_ERR_EQ( error, Invalid_Table ) )
737           FT_ERROR(( "pfr_slot_load_bitmap: invalid bitmap dimensions\n" ));
738         goto Exit1;
739       }
740 
741       /*
742        * XXX: on 16bit systems we return an error for huge bitmaps
743        *      that cause size truncation, because truncated
744        *      size properties make bitmap glyphs broken.
745        */
746       if ( xpos > FT_INT_MAX                  ||
747            xpos < FT_INT_MIN                  ||
748            ysize > FT_INT_MAX                 ||
749            ypos > FT_INT_MAX - (FT_Long)ysize ||
750            ypos + (FT_Long)ysize < FT_INT_MIN )
751       {
752         FT_TRACE1(( "pfr_slot_load_bitmap:"
753                     " huge bitmap glyph %ldx%ld over FT_GlyphSlot\n",
754                      xpos, ypos ));
755         error = FT_THROW( Invalid_Pixel_Size );
756       }
757 
758       if ( !error )
759       {
760         glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
761 
762         /* Set up glyph bitmap and metrics */
763 
764         /* XXX: needs casts to fit FT_Bitmap.{width|rows|pitch} */
765         glyph->root.bitmap.width      = xsize;
766         glyph->root.bitmap.rows       = ysize;
767         glyph->root.bitmap.pitch      = (FT_Int)( xsize + 7 ) >> 3;
768         glyph->root.bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
769 
770         /* XXX: needs casts to fit FT_Glyph_Metrics.{width|height} */
771         glyph->root.metrics.width        = (FT_Pos)xsize << 6;
772         glyph->root.metrics.height       = (FT_Pos)ysize << 6;
773         glyph->root.metrics.horiBearingX = xpos * 64;
774         glyph->root.metrics.horiBearingY = ypos * 64;
775         glyph->root.metrics.horiAdvance  = FT_PIX_ROUND( ( advance >> 2 ) );
776         glyph->root.metrics.vertBearingX = - glyph->root.metrics.width >> 1;
777         glyph->root.metrics.vertBearingY = 0;
778         glyph->root.metrics.vertAdvance  = size->root.metrics.height;
779 
780         /* XXX: needs casts fit FT_GlyphSlotRec.bitmap_{left|top} */
781         glyph->root.bitmap_left = (FT_Int)xpos;
782         glyph->root.bitmap_top  = (FT_Int)( ypos + (FT_Long)ysize );
783 
784         if ( metrics_only )
785           goto Exit1;
786 
787         /* Allocate and read bitmap data */
788         {
789           FT_ULong  len = (FT_ULong)glyph->root.bitmap.pitch * ysize;
790 
791 
792           error = ft_glyphslot_alloc_bitmap( &glyph->root, len );
793           if ( !error )
794             error = pfr_load_bitmap_bits(
795                       p,
796                       stream->limit,
797                       format,
798                       FT_BOOL( face->header.color_flags &
799                                PFR_FLAG_INVERT_BITMAP   ),
800                       &glyph->root.bitmap );
801         }
802       }
803 
804     Exit1:
805       FT_FRAME_EXIT();
806     }
807 
808   Exit:
809     return error;
810   }
811 
812 
813 /* END */
814