(root)/
freetype-2.13.2/
src/
pfr/
pfrsbit.c
       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
      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
      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
     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
     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
     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
     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
     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 )
     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 */