📄 bdflib.c
字号:
/*
* 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 + -