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

📄 bdf.c

📁 ucgui的矢量字库支持包,可以象windows一样使用truetype的字库了
💻 C
📖 第 1 页 / 共 5 页
字号:

    if ( s == 0 || *s == 0 )
      return 0;

    /* Make sure the radix is something recognizable.  Default to 10. */
    switch ( base )
    {
    case 8:
      dmap = odigits;
      break;
    case 16:
      dmap = hdigits;
      break;
    default:
      base = 10;
      dmap = ddigits;
      break;
    }

    /* Check for a minus sign. */
    neg = 0;
    if ( *s == '-' )
    {
      s++;
      neg = 1;
    }

    /* Check for the special hex prefix. */
    if ( *s == '0'                                  &&
         ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) )
    {
      base = 16;
      dmap = hdigits;
      s   += 2;
    }

    for ( v = 0; isdigok( dmap, *s ); s++ )
      v = v * base + a2i[(int)*s];

    if ( end != 0 )
      *end = s;

    return ( !neg ) ? v : -v;
  }


  /* Routine to convert an ASCII string into an signed short integer. */
  static short
  _bdf_atos( char*   s,
             char**  end,
             int     base )
  {
    short                 v, neg;
    const unsigned char*  dmap;


    if ( s == 0 || *s == 0 )
      return 0;

    /* Make sure the radix is something recognizable.  Default to 10. */
    switch ( base )
    {
    case 8:
      dmap = odigits;
      break;
    case 16:
      dmap = hdigits;
      break;
    default:
      base = 10;
      dmap = ddigits;
      break;
    }

    /* Check for a minus. */
    neg = 0;
    if ( *s == '-' )
    {
      s++;
      neg = 1;
    }

    /* Check for the special hex prefix. */
    if ( *s == '0'                                  &&
         ( *( s + 1 ) == 'x' || *( s + 1 ) == 'X' ) )
    {
      base = 16;
      dmap = hdigits;
      s   += 2;
    }

    for ( v = 0; isdigok( dmap, *s ); s++ )
      v = (short)( v * base + a2i[(int)*s] );

    if ( end != 0 )
      *end = s;

    return (short)( ( !neg ) ? v : -v );
  }


  /* Routine to compare two glyphs by encoding so they can be sorted. */
  static int
  by_encoding( const void*  a,
               const void*  b )
  {
    bdf_glyph_t  *c1, *c2;


    c1 = (bdf_glyph_t *)a;
    c2 = (bdf_glyph_t *)b;

    if ( c1->encoding < c2->encoding )
      return -1;

    if ( c1->encoding > c2->encoding )
      return 1;

    return 0;
  }


  static FT_Error
  bdf_create_property( char*        name,
                       int          format,
                       bdf_font_t*  font )
  {
    unsigned long    n;
    bdf_property_t*  p;
    FT_Memory        memory = font->memory;
    FT_Error         error = BDF_Err_Ok;


    /* First check to see if the property has      */
    /* already been added or not.  If it has, then */
    /* simply ignore it.                           */
    if ( hash_lookup( name, &(font->proptbl) ) )
      goto Exit;

    if ( FT_RENEW_ARRAY( font->user_props,
                         font->nuser_props,
                         font->nuser_props + 1 ) )
      goto Exit;

    p = font->user_props + font->nuser_props;
    FT_ZERO( p );

    n = (unsigned long)( ft_strlen( name ) + 1 );

    if ( FT_NEW_ARRAY( p->name, n ) )
      goto Exit;

    FT_MEM_COPY( (char *)p->name, name, n );

    p->format  = format;
    p->builtin = 0;

    n = _num_bdf_properties + font->nuser_props;

    error = hash_insert( p->name, (void *)n, &(font->proptbl), memory );
    if ( error )
      goto Exit;

    font->nuser_props++;

  Exit:
    return error;
  }


  FT_LOCAL_DEF( bdf_property_t * )
  bdf_get_property( char*        name,
                    bdf_font_t*  font )
  {
    hashnode       hn;
    unsigned long  propid;


    if ( name == 0 || *name == 0 )
      return 0;

    if ( ( hn = hash_lookup( name, &(font->proptbl) ) ) == 0 )
      return 0;

    propid = (unsigned long)hn->data;
    if ( propid >= _num_bdf_properties )
      return font->user_props + ( propid - _num_bdf_properties );

    return (bdf_property_t*)_bdf_properties + propid;
  }


  /*************************************************************************/
  /*                                                                       */
  /* BDF font file parsing flags and functions.                            */
  /*                                                                       */
  /*************************************************************************/


  /* Parse flags. */

#define _BDF_START      0x0001
#define _BDF_FONT_NAME  0x0002
#define _BDF_SIZE       0x0004
#define _BDF_FONT_BBX   0x0008
#define _BDF_PROPS      0x0010
#define _BDF_GLYPHS     0x0020
#define _BDF_GLYPH      0x0040
#define _BDF_ENCODING   0x0080
#define _BDF_SWIDTH     0x0100
#define _BDF_DWIDTH     0x0200
#define _BDF_BBX        0x0400
#define _BDF_BITMAP     0x0800

#define _BDF_SWIDTH_ADJ  0x1000

#define _BDF_GLYPH_BITS ( _BDF_GLYPH    | \
                          _BDF_ENCODING | \
                          _BDF_SWIDTH   | \
                          _BDF_DWIDTH   | \
                          _BDF_BBX      | \
                          _BDF_BITMAP   )

#define _BDF_GLYPH_WIDTH_CHECK   0x40000000UL
#define _BDF_GLYPH_HEIGHT_CHECK  0x80000000UL


  /* Auto correction messages. */
#define ACMSG1   "FONT_ASCENT property missing.  " \
                 "Added \"FONT_ASCENT %hd\".\n"
#define ACMSG2   "FONT_DESCENT property missing.  " \
                 "Added \"FONT_DESCENT %hd\".\n"
#define ACMSG3   "Font width != actual width.  Old: %hd New: %hd.\n"
#define ACMSG4   "Font left bearing != actual left bearing.  " \
                 "Old: %hd New: %hd.\n"
#define ACMSG5   "Font ascent != actual ascent.  Old: %hd New: %hd.\n"
#define ACMSG6   "Font descent != actual descent.  Old: %hd New: %hd.\n"
#define ACMSG7   "Font height != actual height. Old: %hd New: %hd.\n"
#define ACMSG8   "Glyph scalable width (SWIDTH) adjustments made.\n"
#define ACMSG9   "SWIDTH field missing at line %ld.  Set automatically.\n"
#define ACMSG10  "DWIDTH field missing at line %ld.  Set to glyph width.\n"
#define ACMSG11  "SIZE bits per pixel field adjusted to %hd.\n"
#define ACMSG12  "Duplicate encoding %ld (%s) changed to unencoded.\n"
#define ACMSG13  "Glyph %ld extra rows removed.\n"
#define ACMSG14  "Glyph %ld extra columns removed.\n"
#define ACMSG15  "Incorrect glyph count: %ld indicated but %ld found.\n"

  /* Error messages. */
#define ERRMSG1  "[line %ld] Missing \"%s\" line.\n"
#define ERRMSG2  "[line %ld] Font header corrupted or missing fields.\n"
#define ERRMSG3  "[line %ld] Font glyphs corrupted or missing fields.\n"
#define ERRMSG4  "[line %ld] BBX too big.\n"


  static FT_Error
  _bdf_add_comment( bdf_font_t*    font,
                    char*          comment,
                    unsigned long  len )
  {
    char*      cp;
    FT_Memory  memory = font->memory;
    FT_Error   error = BDF_Err_Ok;


    if ( FT_RENEW_ARRAY( font->comments,
                         font->comments_len,
                         font->comments_len + len + 1 ) )
      goto Exit;

    cp = font->comments + font->comments_len;

    FT_MEM_COPY( cp, comment, len );
    cp[len] = '\n';

    font->comments_len += len + 1;

  Exit:
    return error;
  }


  /* Set the spacing from the font name if it exists, or set it to the */
  /* default specified in the options.                                 */
  static FT_Error
  _bdf_set_default_spacing( bdf_font_t*     font,
                            bdf_options_t*  opts )
  {
    unsigned long  len;
    char           name[128];
    _bdf_list_t    list;
    FT_Memory      memory;
    FT_Error       error = BDF_Err_Ok;


    if ( font == 0 || font->name == 0 || font->name[0] == 0 )
    {
      error = BDF_Err_Invalid_Argument;
      goto Exit;
    }

    memory = font->memory;

    _bdf_list_init( &list, memory );

    font->spacing = opts->font_spacing;

    len = (unsigned long)( ft_strlen( font->name ) + 1 );
    FT_MEM_COPY( name, font->name, len );

    error = _bdf_list_split( &list, (char *)"-", name, len );
    if ( error )
      goto Fail;

    if ( list.used == 15 )
    {
      switch ( list.field[11][0] )
      {
      case 'C':
      case 'c':
        font->spacing = BDF_CHARCELL;
        break;
      case 'M':
      case 'm':
        font->spacing = BDF_MONOWIDTH;
        break;
      case 'P':
      case 'p':
        font->spacing = BDF_PROPORTIONAL;
        break;
      }
    }

  Fail:
    _bdf_list_done( &list );

  Exit:
    return error;
  }


  /* Determine whether the property is an atom or not.  If it is, then */
  /* clean it up so the double quotes are removed if they exist.       */
  static int
  _bdf_is_atom( char*          line,
                unsigned long  linelen,
                char**         name,
                char**         value,
                bdf_font_t*    font )
  {
    int              hold;
    char             *sp, *ep;
    bdf_property_t*  p;


    *name = sp = ep = line;

    while ( *ep && *ep != ' ' && *ep != '\t' )
      ep++;

    hold = -1;
    if ( *ep )
    {
      hold = *ep;
      *ep  = 0;
    }

    p = bdf_get_property( sp, font );

    /* Restore the character that was saved before any return can happen. */
    if ( hold != -1 )
      *ep = (char)hold;

    /* If the property exists and is not an atom, just return here. */
    if ( p && p->format != BDF_ATOM )
      return 0;

    /* The property is an atom.  Trim all leading and trailing whitespace */
    /* and double quotes for the atom value.                              */
    sp = ep;
    ep = line + linelen;

    /* Trim the leading whitespace if it exists. */
    *sp++ = 0;
    while ( *sp                           &&
            ( *sp == ' ' || *sp == '\t' ) )
      sp++;

    /* Trim the leading double quote if it exists. */
    if ( *sp == '"' )
      sp++;
    *value = sp;

    /* Trim the trailing whitespace if it exists. */
    while ( ep > sp                                       &&
            ( *( ep - 1 ) == ' ' || *( ep - 1 ) == '\t' ) )
      *--ep = 0;

    /* Trim the trailing double quote if it exists. */
    if ( ep > sp && *( ep - 1 ) == '"' )
      *--ep = 0;

    return 1;
  }


  static FT_Error
  _bdf_add_property( bdf_font_t*  font,
                     char*        name,
                     char*        value )
  {
    unsigned long   propid;
    hashnode        hn;
    int             len;
    bdf_property_t  *prop, *fp;
    FT_Memory       memory = font->memory;
    FT_Error        error = BDF_Err_Ok;


    /* First, check to see if the property already exists in the font. */
    if ( ( hn = hash_lookup( name, (hashtable *)font->internal ) ) != 0 )
    {
      /* The property already exists in the font, so simply replace */
      /* the value of the property with the current value.          */
      fp = font->props + (unsigned long)hn->data;

      switch ( fp->format )
      {
      case BDF_ATOM:
        /* Delete the current atom if it exists. */
        FT_FREE( fp->value.atom );

        if ( value == 0 )
          len = 1;
        else
          len = ft_strlen( value ) + 1;

⌨️ 快捷键说明

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