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

📄 cidafm.c

📁 qt-embedded-2.3.8.tar.gz源码
💻 C
字号:
/***************************************************************************//*                                                                         *//*  cidafm.c                                                               *//*                                                                         *//*    AFM support for CID-keyed fonts (body).                              *//*                                                                         *//*  Copyright 1996-2000 by                                                 *//*  David Turner, Robert Wilhelm, and Werner Lemberg.                      *//*                                                                         *//*  This file is part of the FreeType project, and may only be used,       *//*  modified, and distributed under the terms of the FreeType project      *//*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     *//*  this file you indicate that you have read the license and              *//*  understand and accept it fully.                                        *//*                                                                         *//***************************************************************************/#ifdef FT_FLAT_COMPILE#include "cidafm.h"#else#include <cid/cidafm.h>#endif#include <freetype/internal/ftstream.h>#include <freetype/internal/t1types.h>#include <freetype/internal/t1errors.h>#include <stdlib.h>  /* for qsort()   */#include <string.h>  /* for strcmp()  */#include <ctype.h>   /* for isalnum() */  /*************************************************************************/  /*                                                                       */  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */  /* messages during execution.                                            */  /*                                                                       */#undef  FT_COMPONENT#define FT_COMPONENT  trace_cidafm  FT_LOCAL_DEF  void  CID_Done_AFM( FT_Memory  memory,                      CID_AFM*   afm )  {    FREE( afm->kern_pairs );    afm->num_pairs = 0;  }#undef  IS_KERN_PAIR#define IS_KERN_PAIR( p )  ( p[0] == 'K' && p[1] == 'P' )#define IS_ALPHANUM( c )  ( isalnum( c ) || \                            c == '_'     || \                            c == '.'     )  /* read a glyph name and return the equivalent glyph index */  static  FT_UInt  afm_atoindex( FT_Byte**  start,                         FT_Byte*   limit,                         T1_Font*   type1 )  {    FT_Byte*  p = *start;    FT_Int    len;    FT_UInt   result = 0;    char      temp[64];    /* skip whitespace */    while ( ( *p == ' ' || *p == '\t' || *p == ':' || *p == ';' ) &&            p < limit                                             )      p++;    *start = p;    /* now, read glyph name */    while ( IS_ALPHANUM( *p ) && p < limit )      p++;    len = p - *start;    if ( len > 0 && len < 64 )    {      FT_Int  n;      /* copy glyph name to intermediate array */      MEM_Copy( temp, *start, len );      temp[len] = 0;      /* lookup glyph name in face array */      for ( n = 0; n < type1->num_glyphs; n++ )      {        char*  gname = (char*)type1->glyph_names[n];        if ( gname && gname[0] == temp[0] && strcmp( gname, temp ) == 0 )        {          result = n;          break;        }      }    }    *start = p;    return result;  }  /* read an integer */  static  int  afm_atoi( FT_Byte**  start,                 FT_Byte*   limit )  {    FT_Byte*  p    = *start;    int       sum  = 0;    int       sign = 1;    /* skip everything that is not a number */    while ( p < limit && !isdigit( *p ) )    {      sign = 1;      if ( *p == '-' )        sign = -1;      p++;    }    while ( p < limit && isdigit( *p ) )    {      sum = sum * 10 + ( *p - '0' );      p++;    }    *start = p;    return sum * sign;  }#undef  KERN_INDEX#define KERN_INDEX( g1, g2 )  ( ( (FT_ULong)g1 << 16 ) | g2 )  /* compare two kerning pairs */  static  int  compare_kern_pairs( const void*  a,                           const void*  b )  {    CID_Kern_Pair*  pair1 = (CID_Kern_Pair*)a;    CID_Kern_Pair*  pair2 = (CID_Kern_Pair*)b;    FT_ULong  index1 = KERN_INDEX( pair1->glyph1, pair1->glyph2 );    FT_ULong  index2 = KERN_INDEX( pair2->glyph1, pair2->glyph2 );    return ( index1 - index2 );  }  /* parse an AFM file -- for now, only read the kerning pairs */  FT_LOCAL_DEF  FT_Error  CID_Read_AFM( FT_Face    cid_face,                          FT_Stream  stream )  {    FT_Error        error;    FT_Memory       memory = stream->memory;    FT_Byte*        start;    FT_Byte*        limit;    FT_Byte*        p;    FT_Int          count = 0;    CID_Kern_Pair*  pair;    T1_Font*        type1 = &((T1_Face)t1_face)->type1;    CID_AFM*        afm   = 0;    if ( ACCESS_Frame( stream->size ) )      return error;    start = (FT_Byte*)stream->cursor;    limit = (FT_Byte*)stream->limit;    p     = start;    /* we are now going to count the occurrences of `KP' or `KPX' in */    /* the AFM file.                                                 */    count = 0;    for ( p = start; p < limit - 3; p++ )    {      if ( IS_KERN_PAIR( p ) )        count++;    }    /* Actually, kerning pairs are simply optional! */    if ( count == 0 )      goto Exit;    /* allocate the pairs */    if ( ALLOC( afm, sizeof ( *afm ) )                        ||         ALLOC_ARRAY( afm->kern_pairs, count, CID_Kern_Pair ) )      goto Exit;    /* now, read each kern pair */    pair           = afm->kern_pairs;    afm->num_pairs = count;    /* save in face object */    ((T1_Face)t1_face)->afm_data = afm;    for ( p = start; p < limit - 3; p++ )    {      if ( IS_KERN_PAIR( p ) )      {        FT_Byte*  q;        /* skip keyword (`KP' or `KPX') */        q = p + 2;        if ( *q == 'X' )          q++;        pair->glyph1    = afm_atoindex( &q, limit, type1 );        pair->glyph2    = afm_atoindex( &q, limit, type1 );        pair->kerning.x = afm_atoi( &q, limit );        pair->kerning.y = 0;        if ( p[2] != 'X' )          pair->kerning.y = afm_atoi( &q, limit );        pair++;      }    }    /* now, sort the kern pairs according to their glyph indices */    qsort( afm->kern_pairs, count, sizeof ( CID_Kern_Pair ),           compare_kern_pairs );  Exit:    if ( error )      FREE( afm );    FORGET_Frame();    return error;  }  /* find the kerning for a given glyph pair */  FT_LOCAL_DEF  void  CID_Get_Kerning( CID_AFM*    afm,                         FT_UInt     glyph1,                         FT_UInt     glyph2,                         FT_Vector*  kerning )  {    CID_Kern_Pair  *min, *mid, *max;    FT_ULong       index = KERN_INDEX( glyph1, glyph2 );    /* simple binary search */    min = afm->kern_pairs;    max = min + afm->num_pairs - 1;    while ( min <= max )    {      FT_ULong  midi;      mid = min + ( max - min ) / 2;      midi = KERN_INDEX( mid->glyph1, mid->glyph2 );      if ( midi == index )      {        *kerning = mid->kerning;        return;      }      if ( midi < index )        min = mid + 1;      else        max = mid - 1;    }    kerning->x = 0;    kerning->y = 0;  }/* END */

⌨️ 快捷键说明

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