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

📄 bdflib.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
 * Copyright 2000 Computing Research Labs, New Mexico State University
 * Copyright 2001, 2002, 2003, 2004, 2005, 2006 Francesco Zappa Nardelli
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COMPUTING RESEARCH LAB OR NEW MEXICO STATE UNIVERSITY BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
 * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
 * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

  /*************************************************************************/
  /*                                                                       */
  /*  This file is based on bdf.c,v 1.22 2000/03/16 20:08:50               */
  /*                                                                       */
  /*  taken from Mark Leisher's xmbdfed package                            */
  /*                                                                       */
  /*************************************************************************/


#include <ft2build.h>

#include FT_FREETYPE_H
#include FT_INTERNAL_DEBUG_H
#include FT_INTERNAL_STREAM_H
#include FT_INTERNAL_OBJECTS_H

#include "bdf.h"
#include "bdferror.h"


  /*************************************************************************/
  /*                                                                       */
  /* 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_bdflib


  /*************************************************************************/
  /*                                                                       */
  /* Default BDF font options.                                             */
  /*                                                                       */
  /*************************************************************************/


  static const bdf_options_t  _bdf_opts =
  {
    1,                /* Correct metrics.               */
    1,                /* Preserve unencoded glyphs.     */
    0,                /* Preserve comments.             */
    BDF_PROPORTIONAL  /* Default spacing.               */
  };


  /*************************************************************************/
  /*                                                                       */
  /* Builtin BDF font properties.                                          */
  /*                                                                       */
  /*************************************************************************/

  /* List of most properties that might appear in a font.  Doesn't include */
  /* the RAW_* and AXIS_* properties in X11R6 polymorphic fonts.           */

  static const bdf_property_t  _bdf_properties[] =
  {
    { (char *)"ADD_STYLE_NAME",          BDF_ATOM,     1, { 0 } },
    { (char *)"AVERAGE_WIDTH",           BDF_INTEGER,  1, { 0 } },
    { (char *)"AVG_CAPITAL_WIDTH",       BDF_INTEGER,  1, { 0 } },
    { (char *)"AVG_LOWERCASE_WIDTH",     BDF_INTEGER,  1, { 0 } },
    { (char *)"CAP_HEIGHT",              BDF_INTEGER,  1, { 0 } },
    { (char *)"CHARSET_COLLECTIONS",     BDF_ATOM,     1, { 0 } },
    { (char *)"CHARSET_ENCODING",        BDF_ATOM,     1, { 0 } },
    { (char *)"CHARSET_REGISTRY",        BDF_ATOM,     1, { 0 } },
    { (char *)"COMMENT",                 BDF_ATOM,     1, { 0 } },
    { (char *)"COPYRIGHT",               BDF_ATOM,     1, { 0 } },
    { (char *)"DEFAULT_CHAR",            BDF_CARDINAL, 1, { 0 } },
    { (char *)"DESTINATION",             BDF_CARDINAL, 1, { 0 } },
    { (char *)"DEVICE_FONT_NAME",        BDF_ATOM,     1, { 0 } },
    { (char *)"END_SPACE",               BDF_INTEGER,  1, { 0 } },
    { (char *)"FACE_NAME",               BDF_ATOM,     1, { 0 } },
    { (char *)"FAMILY_NAME",             BDF_ATOM,     1, { 0 } },
    { (char *)"FIGURE_WIDTH",            BDF_INTEGER,  1, { 0 } },
    { (char *)"FONT",                    BDF_ATOM,     1, { 0 } },
    { (char *)"FONTNAME_REGISTRY",       BDF_ATOM,     1, { 0 } },
    { (char *)"FONT_ASCENT",             BDF_INTEGER,  1, { 0 } },
    { (char *)"FONT_DESCENT",            BDF_INTEGER,  1, { 0 } },
    { (char *)"FOUNDRY",                 BDF_ATOM,     1, { 0 } },
    { (char *)"FULL_NAME",               BDF_ATOM,     1, { 0 } },
    { (char *)"ITALIC_ANGLE",            BDF_INTEGER,  1, { 0 } },
    { (char *)"MAX_SPACE",               BDF_INTEGER,  1, { 0 } },
    { (char *)"MIN_SPACE",               BDF_INTEGER,  1, { 0 } },
    { (char *)"NORM_SPACE",              BDF_INTEGER,  1, { 0 } },
    { (char *)"NOTICE",                  BDF_ATOM,     1, { 0 } },
    { (char *)"PIXEL_SIZE",              BDF_INTEGER,  1, { 0 } },
    { (char *)"POINT_SIZE",              BDF_INTEGER,  1, { 0 } },
    { (char *)"QUAD_WIDTH",              BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_ASCENT",              BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_AVERAGE_WIDTH",       BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_AVG_CAPITAL_WIDTH",   BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_AVG_LOWERCASE_WIDTH", BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_CAP_HEIGHT",          BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_DESCENT",             BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_END_SPACE",           BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_FIGURE_WIDTH",        BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_MAX_SPACE",           BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_MIN_SPACE",           BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_NORM_SPACE",          BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_PIXEL_SIZE",          BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_POINT_SIZE",          BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_PIXELSIZE",           BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_POINTSIZE",           BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_QUAD_WIDTH",          BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_SMALL_CAP_SIZE",      BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_STRIKEOUT_ASCENT",    BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_STRIKEOUT_DESCENT",   BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_SUBSCRIPT_SIZE",      BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_SUBSCRIPT_X",         BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_SUBSCRIPT_Y",         BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_SUPERSCRIPT_SIZE",    BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_SUPERSCRIPT_X",       BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_SUPERSCRIPT_Y",       BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_UNDERLINE_POSITION",  BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_UNDERLINE_THICKNESS", BDF_INTEGER,  1, { 0 } },
    { (char *)"RAW_X_HEIGHT",            BDF_INTEGER,  1, { 0 } },
    { (char *)"RELATIVE_SETWIDTH",       BDF_CARDINAL, 1, { 0 } },
    { (char *)"RELATIVE_WEIGHT",         BDF_CARDINAL, 1, { 0 } },
    { (char *)"RESOLUTION",              BDF_INTEGER,  1, { 0 } },
    { (char *)"RESOLUTION_X",            BDF_CARDINAL, 1, { 0 } },
    { (char *)"RESOLUTION_Y",            BDF_CARDINAL, 1, { 0 } },
    { (char *)"SETWIDTH_NAME",           BDF_ATOM,     1, { 0 } },
    { (char *)"SLANT",                   BDF_ATOM,     1, { 0 } },
    { (char *)"SMALL_CAP_SIZE",          BDF_INTEGER,  1, { 0 } },
    { (char *)"SPACING",                 BDF_ATOM,     1, { 0 } },
    { (char *)"STRIKEOUT_ASCENT",        BDF_INTEGER,  1, { 0 } },
    { (char *)"STRIKEOUT_DESCENT",       BDF_INTEGER,  1, { 0 } },
    { (char *)"SUBSCRIPT_SIZE",          BDF_INTEGER,  1, { 0 } },
    { (char *)"SUBSCRIPT_X",             BDF_INTEGER,  1, { 0 } },
    { (char *)"SUBSCRIPT_Y",             BDF_INTEGER,  1, { 0 } },
    { (char *)"SUPERSCRIPT_SIZE",        BDF_INTEGER,  1, { 0 } },
    { (char *)"SUPERSCRIPT_X",           BDF_INTEGER,  1, { 0 } },
    { (char *)"SUPERSCRIPT_Y",           BDF_INTEGER,  1, { 0 } },
    { (char *)"UNDERLINE_POSITION",      BDF_INTEGER,  1, { 0 } },
    { (char *)"UNDERLINE_THICKNESS",     BDF_INTEGER,  1, { 0 } },
    { (char *)"WEIGHT",                  BDF_CARDINAL, 1, { 0 } },
    { (char *)"WEIGHT_NAME",             BDF_ATOM,     1, { 0 } },
    { (char *)"X_HEIGHT",                BDF_INTEGER,  1, { 0 } },
    { (char *)"_MULE_BASELINE_OFFSET",   BDF_INTEGER,  1, { 0 } },
    { (char *)"_MULE_RELATIVE_COMPOSE",  BDF_INTEGER,  1, { 0 } },
  };

  static const unsigned long
  _num_bdf_properties = sizeof ( _bdf_properties ) /
                        sizeof ( _bdf_properties[0] );


  /*************************************************************************/
  /*                                                                       */
  /* Hash table utilities for the properties.                              */
  /*                                                                       */
  /*************************************************************************/

  /* XXX: Replace this with FreeType's hash functions */


#define INITIAL_HT_SIZE  241

  typedef void
  (*hash_free_func)( hashnode  node );

  static hashnode*
  hash_bucket( const char*  key,
               hashtable*   ht )
  {
    const char*    kp  = key;
    unsigned long  res = 0;
    hashnode*      bp  = ht->table, *ndp;


    /* Mocklisp hash function. */
    while ( *kp )
      res = ( res << 5 ) - res + *kp++;

    ndp = bp + ( res % ht->size );
    while ( *ndp )
    {
      kp = (*ndp)->key;
      if ( kp[0] == key[0] && ft_strcmp( kp, key ) == 0 )
        break;
      ndp--;
      if ( ndp < bp )
        ndp = bp + ( ht->size - 1 );
    }

    return ndp;
  }


  static FT_Error
  hash_rehash( hashtable*  ht,
               FT_Memory   memory )
  {
    hashnode*  obp = ht->table, *bp, *nbp;
    int        i, sz = ht->size;
    FT_Error   error = BDF_Err_Ok;


    ht->size <<= 1;
    ht->limit  = ht->size / 3;

    if ( FT_NEW_ARRAY( ht->table, ht->size ) )
      goto Exit;

    for ( i = 0, bp = obp; i < sz; i++, bp++ )
    {
      if ( *bp )
      {
        nbp = hash_bucket( (*bp)->key, ht );
        *nbp = *bp;
      }
    }
    FT_FREE( obp );

  Exit:
    return error;
  }


  static FT_Error
  hash_init( hashtable*  ht,
             FT_Memory   memory )
  {
    int       sz = INITIAL_HT_SIZE;
    FT_Error  error = BDF_Err_Ok;


    ht->size  = sz;
    ht->limit = sz / 3;
    ht->used  = 0;

    if ( FT_NEW_ARRAY( ht->table, sz ) )
      goto Exit;

  Exit:
    return error;
  }


  static void
  hash_free( hashtable*  ht,
             FT_Memory   memory )
  {
    if ( ht != 0 )
    {
      int        i, sz = ht->size;
      hashnode*  bp = ht->table;


      for ( i = 0; i < sz; i++, bp++ )
        FT_FREE( *bp );

      FT_FREE( ht->table );
    }
  }


  static FT_Error
  hash_insert( char*       key,
               void*       data,
               hashtable*  ht,
               FT_Memory   memory )
  {
    hashnode  nn, *bp = hash_bucket( key, ht );
    FT_Error  error = BDF_Err_Ok;


    nn = *bp;
    if ( !nn )
    {
      if ( FT_NEW( nn ) )
        goto Exit;
      *bp = nn;

      nn->key  = key;
      nn->data = data;

      if ( ht->used >= ht->limit )
      {
        error = hash_rehash( ht, memory );
        if ( error )
          goto Exit;
      }
      ht->used++;
    }
    else
      nn->data = data;

  Exit:
    return error;
  }


  static hashnode
  hash_lookup( const char* key,
               hashtable*  ht )
  {
    hashnode *np = hash_bucket( key, ht );


    return *np;
  }


  /*************************************************************************/
  /*                                                                       */
  /* Utility types and functions.                                          */
  /*                                                                       */
  /*************************************************************************/


  /* Function type for parsing lines of a BDF font. */

  typedef FT_Error
  (*_bdf_line_func_t)( char*          line,
                       unsigned long  linelen,
                       unsigned long  lineno,
                       void*          call_data,
                       void*          client_data );


  /* List structure for splitting lines into fields. */

  typedef struct  _bdf_list_t_
  {
    char**         field;
    unsigned long  size;
    unsigned long  used;
    FT_Memory      memory;

  } _bdf_list_t;


  /* Structure used while loading BDF fonts. */

  typedef struct  _bdf_parse_t_
  {
    unsigned long   flags;
    unsigned long   cnt;
    unsigned long   row;

    short           minlb;
    short           maxlb;
    short           maxrb;
    short           maxas;
    short           maxds;

    short           rbearing;

    char*           glyph_name;
    long            glyph_enc;

    bdf_font_t*     font;
    bdf_options_t*  opts;

    unsigned long   have[2048];
    _bdf_list_t     list;

    FT_Memory       memory;

  } _bdf_parse_t;


#define setsbit( m, cc )  ( m[(cc) >> 3] |= (FT_Byte)( 1 << ( (cc) & 7 ) ) )
#define sbitset( m, cc )  ( m[(cc) >> 3]  & ( 1 << ( (cc) & 7 ) ) )


  static void
  _bdf_list_init( _bdf_list_t*  list,
                  FT_Memory     memory )
  {
    FT_ZERO( list );
    list->memory = memory;
  }


  static void
  _bdf_list_done( _bdf_list_t*  list )
  {
    FT_Memory  memory = list->memory;


    if ( memory )
    {
      FT_FREE( list->field );
      FT_ZERO( list );
    }
  }


  static FT_Error
  _bdf_list_ensure( _bdf_list_t*  list,
                    int           num_items )
  {
    FT_Error  error = BDF_Err_Ok;


    if ( num_items > (int)list->size )
    {
      int        oldsize = list->size;
      int        newsize = oldsize + ( oldsize >> 1 ) + 4;
      int        bigsize = FT_INT_MAX / sizeof ( char* );
      FT_Memory  memory  = list->memory;


      if ( oldsize == bigsize )
      {
        error = BDF_Err_Out_Of_Memory;
        goto Exit;
      }
      else if ( newsize < oldsize || newsize > bigsize )
        newsize = bigsize;

      if ( FT_RENEW_ARRAY( list->field, oldsize, newsize ) )
        goto Exit;

      list->size = newsize;

⌨️ 快捷键说明

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