📄 bdflib.c
字号:
/* 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[256]; _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 ); /* Limit ourselves to 256 characters in the font name. */ if ( len >= 256 ) { error = BDF_Err_Invalid_Argument; goto Exit; } 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; 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 && value[0] != 0 ) { if ( FT_STRDUP( fp->value.atom, value ) ) goto Exit; } break; case BDF_INTEGER: fp->value.int32 = _bdf_atol( value, 0, 10 ); break; case BDF_CARDINAL: fp->value.card32 = _bdf_atoul( value, 0, 10 ); break; default: ; } goto Exit; } /* See whether this property type exists yet or not. */ /* If not, create it. */ hn = hash_lookup( name, &(font->proptbl) ); if ( hn == 0 ) { error = bdf_create_property( name, BDF_ATOM, font ); if ( error ) goto Exit; hn = hash_lookup( name, &(font->proptbl) ); } /* Allocate another property if this is overflow. */ if ( font->props_used == font->props_size ) { if ( font->props_size == 0 ) { if ( FT_NEW_ARRAY( font->props, 1 ) ) goto Exit; } else { if ( FT_RENEW_ARRAY( font->props, font->props_size, font->props_size + 1 ) ) goto Exit; } fp = font->props + font->props_size; FT_MEM_ZERO( fp, sizeof ( bdf_property_t ) ); font->props_size++; } propid = (unsigned long)hn->data; if ( propid >= _num_bdf_properties ) prop = font->user_props + ( propid - _num_bdf_properties ); else prop = (bdf_property_t*)_bdf_properties + propid; fp = font->props + font->props_used; fp->name = prop->name; fp->format = prop->format; fp->builtin = prop->builtin; switch ( prop->format ) { case BDF_ATOM: fp->value.atom = 0; if ( value != 0 && value[0] ) { if ( FT_STRDUP( fp->value.atom, value ) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -