📄 bdflib.c
字号:
/* * Copyright 2000 Computing Research Labs, New Mexico State University * Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007 * 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[(FT_Byte)(cc) >> 3] |= (FT_Byte)( 1 << ( (cc) & 7 ) ) )#define sbitset( m, cc ) \ ( m[(FT_Byte)(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; } Exit: return error; } static void _bdf_list_shift( _bdf_list_t* list,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -