📄 bdf.c
字号:
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 + -