⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pfrload.c

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    PFR_CHECK( item->pair_count * item->pair_size );#endif    /* load first and last pairs into the item to speed up */    /* lookup later...                                     */    if ( item->pair_count > 0 )    {      FT_UInt   char1, char2;      FT_Byte*  q;      if ( item->flags & PFR_KERN_2BYTE_CHAR )      {        q     = p;        char1 = PFR_NEXT_USHORT( q );        char2 = PFR_NEXT_USHORT( q );        item->pair1 = PFR_KERN_INDEX( char1, char2 );        q = p + item->pair_size * ( item->pair_count - 1 );        char1 = PFR_NEXT_USHORT( q );        char2 = PFR_NEXT_USHORT( q );        item->pair2 = PFR_KERN_INDEX( char1, char2 );      }      else      {        q     = p;        char1 = PFR_NEXT_BYTE( q );        char2 = PFR_NEXT_BYTE( q );        item->pair1 = PFR_KERN_INDEX( char1, char2 );        q = p + item->pair_size * ( item->pair_count - 1 );        char1 = PFR_NEXT_BYTE( q );        char2 = PFR_NEXT_BYTE( q );        item->pair2 = PFR_KERN_INDEX( char1, char2 );      }      /* add new item to the current list */      item->next                 = NULL;      *phy_font->kern_items_tail = item;      phy_font->kern_items_tail  = &item->next;      phy_font->num_kern_pairs  += item->pair_count;    }    else    {      /* empty item! */      FT_FREE( item );    }  Exit:    return error;  Too_Short:    FT_FREE( item );    error = PFR_Err_Invalid_Table;    FT_ERROR(( "pfr_extra_item_load_kerning_pairs: "               "invalid kerning pairs table\n" ));    goto Exit;  }#ifndef FT_OPTIMIZE_MEMORY  /*   *  The kerning data embedded in a PFR font are (charcode,charcode)   *  pairs; we need to translate them to (gindex,gindex) and sort   *  the resulting array.   */  static FT_UInt  pfr_get_gindex( PFR_Char  chars,                  FT_UInt   count,                  FT_UInt   charcode )  {    FT_UInt  min = 0;    FT_UInt  max = count;    while ( min < max )    {      FT_UInt   mid = ( min + max ) >> 1;      PFR_Char  c   = chars + mid;      if ( c->char_code == charcode )        return mid + 1;      if ( c->char_code < charcode )        min = mid + 1;      else        max = mid;    }    return 0;  }  FT_CALLBACK_DEF( int )  pfr_compare_kern_pairs( const void*  pair1,                          const void*  pair2 )  {    FT_UInt32  p1 = PFR_KERN_PAIR_INDEX( (PFR_KernPair)pair1 );    FT_UInt32  p2 = PFR_KERN_PAIR_INDEX( (PFR_KernPair)pair2 );    if ( p1 < p2 )      return -1;    if ( p1 > p2 )      return 1;    return 0;  }  static FT_Error  pfr_sort_kerning_pairs( FT_Stream    stream,                          PFR_PhyFont  phy_font )  {    FT_Error      error;    FT_Memory     memory = stream->memory;    PFR_KernPair  pairs;    PFR_KernItem  item;    PFR_Char      chars     = phy_font->chars;    FT_UInt       num_chars = phy_font->num_chars;    FT_UInt       count;    /* create kerning pairs array */    if ( FT_NEW_ARRAY( phy_font->kern_pairs, phy_font->num_kern_pairs ) )      goto Exit;    /*     *  load all kerning items into the array,     *  converting character codes into glyph indices     */    pairs = phy_font->kern_pairs;    item  = phy_font->kern_items;    count = 0;    for ( ; item; item = item->next )    {      FT_UInt   limit = count + item->pair_count;      FT_Byte*  p;      if ( limit > phy_font->num_kern_pairs )      {        error = PFR_Err_Invalid_Table;        goto Exit;      }      if ( FT_STREAM_SEEK( item->offset )                       ||           FT_FRAME_ENTER( item->pair_count * item->pair_size ) )        goto Exit;      p = stream->cursor;      for ( ; count < limit; count++ )      {        PFR_KernPair  pair = pairs + count;        FT_UInt       char1, char2;        FT_Int        kerning;        if ( item->flags & PFR_KERN_2BYTE_CHAR )        {          char1 = FT_NEXT_USHORT( p );          char2 = FT_NEXT_USHORT( p );        }        else        {          char1 = FT_NEXT_BYTE( p );          char2 = FT_NEXT_BYTE( p );        }        if ( item->flags & PFR_KERN_2BYTE_ADJ )          kerning = item->base_adj + FT_NEXT_SHORT( p );        else          kerning = item->base_adj + FT_NEXT_BYTE( p );        pair->glyph1  = pfr_get_gindex( chars, num_chars, char1 );        pair->glyph2  = pfr_get_gindex( chars, num_chars, char2 );        pair->kerning = kerning;      }      FT_FRAME_EXIT();    }    /* sort the resulting array */    ft_qsort( pairs, count,              sizeof ( PFR_KernPairRec ),              pfr_compare_kern_pairs );  Exit:    if ( error )    {     /* disable kerning data in case of error      */      phy_font->num_kern_pairs = 0;    }    return error;  }#endif /* !FT_OPTIMIZE_MEMORY */  static const PFR_ExtraItemRec  pfr_phy_font_extra_items[] =  {    { 1, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_bitmap_info },    { 2, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_font_id },    { 3, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_stem_snaps },    { 4, (PFR_ExtraItem_ParseFunc)pfr_extra_item_load_kerning_pairs },    { 0, NULL }  };  /* Loads a name from the auxiliary data.  Since this extracts undocumented   * strings from the font file, we need to be careful here.   */  static FT_Error  pfr_aux_name_load( FT_Byte*     p,                     FT_UInt      len,                     FT_Memory    memory,                     FT_String*  *astring )  {    FT_Error    error = 0;    FT_String*  result = NULL;    FT_UInt     n, ok;    if ( len > 0 && p[len - 1] == 0 )      len--;    /* check that each character is ASCII for making sure not to       load garbage     */    ok = ( len > 0 );    for ( n = 0; n < len; n++ )      if ( p[n] < 32 || p[n] > 127 )      {        ok = 0;        break;      }    if ( ok )    {      if ( FT_ALLOC( result, len + 1 ) )        goto Exit;      FT_MEM_COPY( result, p, len );      result[len] = 0;    }  Exit:    *astring = result;    return error;  }  FT_LOCAL_DEF( void )  pfr_phy_font_done( PFR_PhyFont  phy_font,                     FT_Memory    memory )  {    FT_FREE( phy_font->font_id );    FT_FREE( phy_font->family_name );    FT_FREE( phy_font->style_name );    FT_FREE( phy_font->vertical.stem_snaps );    phy_font->vertical.num_stem_snaps = 0;    phy_font->horizontal.stem_snaps     = NULL;    phy_font->horizontal.num_stem_snaps = 0;    FT_FREE( phy_font->strikes );    phy_font->num_strikes = 0;    phy_font->max_strikes = 0;    FT_FREE( phy_font->chars );    phy_font->num_chars    = 0;    phy_font->chars_offset = 0;    FT_FREE( phy_font->blue_values );    phy_font->num_blue_values = 0;#ifndef FT_OPTIMIZE_MEMORY    FT_FREE( phy_font->kern_pairs );#endif    {      PFR_KernItem  item, next;      item = phy_font->kern_items;      while ( item )      {        next = item->next;        FT_FREE( item );        item = next;      }      phy_font->kern_items      = NULL;      phy_font->kern_items_tail = NULL;    }    phy_font->num_kern_pairs = 0;  }  FT_LOCAL_DEF( FT_Error )  pfr_phy_font_load( PFR_PhyFont  phy_font,                     FT_Stream    stream,                     FT_UInt32    offset,                     FT_UInt32    size )  {    FT_Error   error;    FT_Memory  memory = stream->memory;    FT_UInt    flags, num_aux;    FT_Byte*   p;    FT_Byte*   limit;    phy_font->memory = memory;    phy_font->offset = offset;    phy_font->kern_items      = NULL;    phy_font->kern_items_tail = &phy_font->kern_items;    if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( size ) )      goto Exit;    phy_font->cursor = stream->cursor;    p     = stream->cursor;    limit = p + size;    PFR_CHECK( 15 );    phy_font->font_ref_number    = PFR_NEXT_USHORT( p );    phy_font->outline_resolution = PFR_NEXT_USHORT( p );    phy_font->metrics_resolution = PFR_NEXT_USHORT( p );    phy_font->bbox.xMin          = PFR_NEXT_SHORT( p );    phy_font->bbox.yMin          = PFR_NEXT_SHORT( p );    phy_font->bbox.xMax          = PFR_NEXT_SHORT( p );    phy_font->bbox.yMax          = PFR_NEXT_SHORT( p );    phy_font->flags      = flags = PFR_NEXT_BYTE( p );    /* get the standard advance for non-proprotional fonts */    if ( !(flags & PFR_PHY_PROPORTIONAL) )    {      PFR_CHECK( 2 );      phy_font->standard_advance = PFR_NEXT_SHORT( p );    }    /* load the extra items when present */    if ( flags & PFR_PHY_EXTRA_ITEMS )    {      error =  pfr_extra_items_parse( &p, limit,                                      pfr_phy_font_extra_items, phy_font );      if ( error )        goto Fail;    }    /* In certain fonts, the auxiliary bytes contain interesting  */    /* information. These are not in the specification but can be */    /* guessed by looking at the content of a few PFR0 fonts.     */    PFR_CHECK( 3 );    num_aux = PFR_NEXT_ULONG( p );    if ( num_aux > 0 )    {      FT_Byte*  q = p;      FT_Byte*  q2;      PFR_CHECK( num_aux );      p += num_aux;      while ( num_aux > 0 )      {        FT_UInt  length, type;        if ( q + 4 > p )          break;        length = PFR_NEXT_USHORT( q );        if ( length < 4 || length > num_aux )          break;        q2   = q + length - 2;        type = PFR_NEXT_USHORT( q );        switch ( type )        {        case 1:          /* this seems to correspond to the font's family name,           * padded to 16-bits with one zero when necessary           */          error = pfr_aux_name_load( q, length - 4U, memory,                                     &phy_font->family_name );          if ( error )            goto Exit;          break;        case 2:          if ( q + 32 > q2 )            break;          q += 10;          phy_font->ascent  = PFR_NEXT_SHORT( q );          phy_font->descent = PFR_NEXT_SHORT( q );          phy_font->leading = PFR_NEXT_SHORT( q );          q += 16;          break;        case 3:          /* this seems to correspond to the font's style name,           * padded to 16-bits with one zero when necessary           */          error = pfr_aux_name_load( q, length - 4U, memory,                                     &phy_font->style_name );          if ( error )            goto Exit;          break;        default:          ;        }        q        = q2;        num_aux -= length;      }    }    /* read the blue values */    {      FT_UInt  n, count;      PFR_CHECK( 1 );      phy_font->num_blue_values = count = PFR_NEXT_BYTE( p );      PFR_CHECK( count * 2 );      if ( FT_NEW_ARRAY( phy_font->blue_values, count ) )        goto Fail;      for ( n = 0; n < count; n++ )        phy_font->blue_values[n] = PFR_NEXT_SHORT( p );    }    PFR_CHECK( 8 );    phy_font->blue_fuzz  = PFR_NEXT_BYTE( p );    phy_font->blue_scale = PFR_NEXT_BYTE( p );    phy_font->vertical.standard   = PFR_NEXT_USHORT( p );    phy_font->horizontal.standard = PFR_NEXT_USHORT( p );    /* read the character descriptors */    {      FT_UInt  n, count, Size;      phy_font->num_chars    = count = PFR_NEXT_USHORT( p );      phy_font->chars_offset = offset + ( p - stream->cursor );      if ( FT_NEW_ARRAY( phy_font->chars, count ) )        goto Fail;      Size = 1 + 1 + 2;      if ( flags & PFR_PHY_2BYTE_CHARCODE )        Size += 1;      if ( flags & PFR_PHY_PROPORTIONAL )        Size += 2;      if ( flags & PFR_PHY_ASCII_CODE )        Size += 1;      if ( flags & PFR_PHY_2BYTE_GPS_SIZE )        Size += 1;      if ( flags & PFR_PHY_3BYTE_GPS_OFFSET )        Size += 1;      PFR_CHECK( count * Size );      for ( n = 0; n < count; n++ )      {        PFR_Char  cur = &phy_font->chars[n];        cur->char_code = ( flags & PFR_PHY_2BYTE_CHARCODE )                         ? PFR_NEXT_USHORT( p )                         : PFR_NEXT_BYTE( p );        cur->advance   = ( flags & PFR_PHY_PROPORTIONAL )                         ? PFR_NEXT_SHORT( p )                         : (FT_Int) phy_font->standard_advance;#if 0        cur->ascii     = ( flags & PFR_PHY_ASCII_CODE )                         ? PFR_NEXT_BYTE( p )                         : 0;#else        if ( flags & PFR_PHY_ASCII_CODE )          p += 1;#endif        cur->gps_size  = ( flags & PFR_PHY_2BYTE_GPS_SIZE )                         ? PFR_NEXT_USHORT( p )                         : PFR_NEXT_BYTE( p );        cur->gps_offset = ( flags & PFR_PHY_3BYTE_GPS_OFFSET )                          ? PFR_NEXT_ULONG( p )                          : PFR_NEXT_USHORT( p );      }    }    /* that's it! */  Fail:    FT_FRAME_EXIT();    /* save position of bitmap info */    phy_font->bct_offset = FT_STREAM_POS();    phy_font->cursor     = NULL;#ifndef FT_OPTIMIZE_MEMORY    /* now sort kerning pairs */    error = pfr_sort_kerning_pairs( stream, phy_font );#endif  Exit:    return error;  Too_Short:    error = PFR_Err_Invalid_Table;    FT_ERROR(( "pfr_phy_font_load: invalid physical font table\n" ));    goto Fail;  }/* END */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -