diff options
Diffstat (limited to 'console/bdf.c')
-rw-r--r-- | console/bdf.c | 986 |
1 files changed, 0 insertions, 986 deletions
diff --git a/console/bdf.c b/console/bdf.c deleted file mode 100644 index 2e9e02bd..00000000 --- a/console/bdf.c +++ /dev/null @@ -1,986 +0,0 @@ -/* Adobe Glyph Bitmap Distribution Format (BDF) parser. - Copyright (C) 2002 Free Software Foundation, Inc. - Written by Marcus Brinkmann <marcus@gnu.org>. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <malloc.h> -#include <ctype.h> -#include <stdarg.h> -#include <search.h> - -#include "bdf.h" - - -/* Return a statically allocated string describing the BDF error value - ERR. */ -const char * -bdf_strerror (bdf_error_t err) -{ - switch (err) - { - case BDF_NO_ERROR: - return "Success"; - case BDF_SYSTEM_ERROR: - return "System error"; - case BDF_SYNTAX_ERROR: - return "Syntax error"; - case BDF_INVALID_ARGUMENT: - return "Invalid Argument"; - case BDF_COUNT_MISMATCH: - return "Count mismatch"; - default: - return "Unknown error"; - } -} - - -/* Copy the string starting from ARG and return the pointer to it in - STRING. If QUOTED is true, outer double quotes are stripped, and - two consecutive double quotes within the string are replaced by one - douple quotes. */ -static bdf_error_t -parse_string (char *arg, char **string, int quoted) -{ - if (quoted) - { - char *value = ++arg; - do - { - value = strchr (value, '"'); - if (!value) - return BDF_INVALID_ARGUMENT; - else if (*(value + 1) == '"') - { - char *copyp = value++; - while (*(++copyp)) - *(copyp - 1) = *copyp; - *(copyp - 1) = 0; - } - } - while (*value != '"' || *(value + 1) == '"'); - *value = 0; - } - - *string = strdup (arg); - if (!*string) - { - errno = ENOMEM; - return BDF_SYSTEM_ERROR; - } - return 0; -} - - -/* Parse the string STR for format TEMPLATE, and require an exact - match. Set err if a parsing error occurs. TEMPLATE must be a - string constant. */ -#define parse_template(str, template, rest...) \ - do \ - { \ - int parse_template_count = -1; \ - sscanf (str, template " %n", rest, &parse_template_count); \ - if (parse_template_count == -1 || *(str + parse_template_count)) \ - err = BDF_SYNTAX_ERROR; \ - } \ - while (0) - -#define hex2nr(c) (((c) >= '0' && (c) <= '9') ? (c) - '0' \ - : (((c) >= 'a' && (c) <= 'f') ? (c) - 'a' \ - : (((c) >= 'A' && (c) <= 'F') ? (c) - 'A' : 0))) - -/* Convert a two-digit hex number starting from LINE to a char and - return the result in BYTE. */ -static bdf_error_t -parse_hexbyte (char *line, unsigned char *byte) -{ - if (!isxdigit (*line) || !isxdigit(*(line + 1))) - return BDF_SYNTAX_ERROR; - else - *byte = (hex2nr (*line) << 4) + hex2nr (*(line + 1)); - return 0; -} - - -/* Like getline(), but keeps track of line count in COUNT, skips - COMMENT lines, and removes whitespace at the beginning and end of a - line. */ -static int -next_line (char **line, int *size, FILE *file, int *count) -{ - int len; - - do - { - len = getline (line, size, file); - if (len >= 0) - { - char *cline = *line; - if (count) - (*count)++; - if (!strncmp (cline, "COMMENT", 7)) - len = 0; - else - while (len > 0 && (cline[len - 1] == '\n' || cline[len - 1] == '\r' - || cline[len - 1] == ' ' - || cline[len - 1] == '\t')) - cline[--len] = 0; - } - } - while (len <= 0 && !feof (file) && !ferror (file)); - return len; -} - - -/* Isolate the next white-space seperated argument from the current - line, and set ARGP to the beginning of the next argument. It is an - error if there is no further argument. */ -static bdf_error_t -find_arg (char **argp) -{ - char *arg = *argp; - - arg = strchr (arg, ' '); - if (arg) - { - *(arg++) = 0; - while (*arg == ' ' || *arg == '\t') - arg++; - } - if (!arg || !*arg) - return BDF_SYNTAX_ERROR; - *argp = arg; - return 0; -} - - -/* Read the font from stream FILE, and return it in FONT. If - LINECOUNT is not zero, it will contain the number of lines in the - file at success, and the line an error occured at failure. */ -bdf_error_t -bdf_read (FILE *filep, bdf_font_t *font, int *linecount) -{ - bdf_error_t err = 0; - char *line = 0; - int line_size = 0; - int len; - int done = 0; - bdf_font_t bdf; - struct - { - /* Current line. */ - enum { START, FONT, PROPERTIES, GLYPHS, GLYPH, BITMAP } location; - /* The number of properties parsed so far. */ - int properties; - /* The number of glyphs parsed so far. */ - int glyphs; - - /* True if we have seen a SIZE keyword so far. */ - int has_size : 1; - /* True if we have seen a FONTBOUNDINGBOX keyword so far. */ - int has_fbbx : 1; - /* True if we have seen a METRICSSET keyword so far. */ - int has_metricsset : 1; - - /* Current glyph. */ - struct bdf_glyph *glyph; - /* True if we have seen an ENCODING keyword for the glyph. */ - int glyph_has_encoding : 1; - /* True if we have seen an BBX keyword for the glyph. */ - int glyph_has_bbx : 1; - /* Width of the glyph in bytes. */ - int glyph_bwidth; - /* Height of the glyph in pixel. */ - int glyph_bheight; - /* How many bitmap lines have been parsed already. */ - int glyph_blines; - } parser = { location: START, properties: 0, glyphs: 0, - has_size: 0, has_fbbx: 0 }; - - bdf = calloc (1, sizeof *bdf); - if (!bdf) - { - errno = ENOMEM; - return BDF_SYSTEM_ERROR; - } - - if (linecount) - *linecount = 0; - - while (!err && (len = next_line (&line, &line_size, filep, linecount)) >= 0) - { - switch (parser.location) - { - case START: - { - /* This is the start of the file, only comments are allowed - until STARTFONT is encountered. */ - char *arg = line; - err = find_arg (&arg); - - if (err) - continue; - if (!strcmp (line, "STARTFONT")) - { - char *minor = strchr (arg, '.'); - if (minor) - *(minor++) = '\0'; - parser.location = FONT; - parse_template (arg, "%i", &bdf->version_maj); - if (minor) - parse_template (minor, "%i", &bdf->version_min); - else - bdf->version_min = 0; - } - else - err = BDF_SYNTAX_ERROR; - } - break; - - case FONT: - { - /* This is the global header before the CHARS. */ - char *arg = line; - err = find_arg (&arg); - - if (err) - continue; - else if (!bdf->has_content_version - && !strcmp (line, "CONTENTVERSION")) - { - bdf->has_content_version = 1; - parse_template (arg, "%i", &bdf->content_version); - } - else if (!bdf->name && !strcmp (line, "FONT")) - err = parse_string (arg, &bdf->name, 0); - else if (!parser.has_size - && !strcmp (line, "SIZE")) - { - parser.has_size = 1; - parse_template (arg, "%i%i%i", &bdf->point_size, - &bdf->res_x, &bdf->res_y); - } - else if (!parser.has_fbbx && !strcmp (line, "FONTBOUNDINGBOX")) - { - parser.has_fbbx = 1; - parse_template (arg, "%i%i%i%i", &bdf->bbox.width, - &bdf->bbox.height, &bdf->bbox.offx, - &bdf->bbox.offy); - } - else if (!parser.has_metricsset && !strcmp (line, "METRICSSET")) - { - parser.has_metricsset = 1; - parse_template (arg, "%i", &bdf->metricsset); - if (!err && (bdf->metricsset < 0 - || bdf->metricsset > 2)) - err = BDF_INVALID_ARGUMENT; - } - else if (!bdf->properties && !strcmp (line, "STARTPROPERTIES")) - { - parser.location = PROPERTIES; - parse_template (arg, "%i", &bdf->properties_count); - if (!err && (bdf->properties_count <= 0)) - err = BDF_INVALID_ARGUMENT; - if (err) - goto leave; - bdf->__properties_allocated = bdf->properties_count; - bdf->properties = calloc (bdf->properties_count, - sizeof (struct bdf_property)); - if (!bdf->properties) - { - errno = ENOMEM; - err = BDF_SYSTEM_ERROR; - } - } - else if (!strcmp (line, "CHARS")) - { - /* This marks the end of the first section, so check - for mandatory global options. */ - if (!bdf->name || !parser.has_size || !parser.has_fbbx) - err = BDF_SYNTAX_ERROR; - else - { - parser.location = GLYPHS; - parse_template (arg, "%i", &bdf->glyphs_count); - if (!err && (bdf->glyphs_count < 0)) - err = BDF_INVALID_ARGUMENT; - if (!err) - { - bdf->__glyphs_allocated = bdf->glyphs_count; - bdf->glyphs = calloc (bdf->glyphs_count, - sizeof (struct bdf_glyph)); - if (!bdf->glyphs) - { - errno = ENOMEM; - err = BDF_SYSTEM_ERROR; - } - } - } - } - else if (!bdf->has_swidth && !strcmp (line, "SWIDTH")) - { - bdf->has_swidth = 1; - parse_template (arg, "%i%i", &bdf->swidth.x, &bdf->swidth.y); - } - else if (!bdf->has_dwidth && !strcmp (line, "DWIDTH")) - { - bdf->has_dwidth = 1; - parse_template (arg, "%i%i", &bdf->dwidth.x, &bdf->dwidth.y); - } - else if (!bdf->has_swidth1 && !strcmp (line, "SWIDTH1")) - { - bdf->has_swidth1 = 1; - parse_template (arg, "%i%i", &bdf->swidth1.x, &bdf->swidth1.y); - } - else if (!bdf->has_dwidth1 && !strcmp (line, "DWIDTH1")) - { - bdf->has_dwidth1 = 1; - parse_template (arg, "%i%i", &bdf->dwidth1.x, &bdf->dwidth1.y); - } - else if (!bdf->has_vvector && !strcmp (line, "VVECTOR")) - { - bdf->has_vvector = 1; - parse_template (arg, "%i%i", &bdf->vvector.x, &bdf->vvector.y); - } - else - err = BDF_SYNTAX_ERROR; - } - break; - - case PROPERTIES: - /* This is the property list in the global header, between - STARTPROPERTIES and ENDPROPERTIES. */ - if (!strcmp (line, "ENDPROPERTIES")) - { - parser.location = FONT; - if (parser.properties != bdf->properties_count) - err = BDF_COUNT_MISMATCH; - } - else - { - if (parser.properties == bdf->properties_count) - err = BDF_COUNT_MISMATCH; - else - { - struct bdf_property *prop - = &bdf->properties[parser.properties++]; - char *arg = line; - - err = find_arg (&arg); - if (err) - continue; - - err = parse_string (line, &prop->name, 0); - if (!err) - { - if (*arg == '"') - { - prop->type = BDF_PROPERTY_STRING; - err = parse_string (arg, &prop->value.string, 1); - } - else - { - prop->type = BDF_PROPERTY_NUMBER; - parse_template (arg, "%i", &prop->value.number); - } - } - } - } - break; - - case GLYPHS: - /* This is the second section of the file, containing the - glyphs. */ - if (!strcmp (line, "ENDFONT")) - { - if (parser.glyphs != bdf->glyphs_count) - err = BDF_COUNT_MISMATCH; - done = 1; - } - else - { - char *arg = line; - - err = find_arg (&arg); - if (err) - continue; - else if (!strcmp (line, "STARTCHAR")) - { - if (parser.glyphs == bdf->glyphs_count) - err = BDF_COUNT_MISMATCH; - - parser.location = GLYPH; - parser.glyph = &bdf->glyphs[parser.glyphs++]; - parser.glyph_has_encoding = 0; - parser.glyph_has_bbx = 0; - parser.glyph_blines = 0; - err = parse_string (arg, &(parser.glyph->name), 0); - } - else - err = BDF_SYNTAX_ERROR; - } - break; - - case GLYPH: - /* This is a glyph, but not its bitmap yet. */ - if (!strcmp (line, "BITMAP")) - { - if (!parser.glyph_has_encoding - || !parser.glyph_has_bbx - - /* In writing mode 0, SWIDTH and DWIDTH are mandatory. */ - || (bdf->metricsset != 1 - && (!(parser.glyph->has_swidth || bdf->has_swidth) - || !(parser.glyph->has_dwidth || bdf->has_dwidth))) - - /* In writing mode 1, SWIDTH1, DWIDTH1 and VVECTOR - are mandatory. */ - || (bdf->metricsset != 0 - && (!(parser.glyph->has_swidth1 || bdf->has_swidth1) - || !(parser.glyph->has_dwidth1 || bdf->has_dwidth1) - || !(parser.glyph->has_vvector - || bdf->has_vvector)))) - err = BDF_SYNTAX_ERROR; - - parser.location = BITMAP; - parser.glyph->bitmap = malloc (parser.glyph_bwidth - * parser.glyph_bheight); - if (!parser.glyph->bitmap) - { - errno = ENOMEM; - err = BDF_SYSTEM_ERROR; - } - } - else - { - char *arg = line; - - err = find_arg (&arg); - if (err) - continue; - else if (!parser.glyph_has_encoding - && !strcmp (line, "ENCODING")) - { - parser.glyph_has_encoding = 1; - parse_template (arg, "%i", &parser.glyph->encoding); - if (err == BDF_SYNTAX_ERROR) - { - err = 0; - parse_template (arg, "%i%i", &parser.glyph->encoding, - &parser.glyph->internal_encoding); - if (!err && parser.glyph->encoding != -1) - err = BDF_SYNTAX_ERROR; - } - } - else if (!parser.glyph_has_bbx && !strcmp (line, "BBX")) - { - parser.glyph_has_bbx = 1; - parse_template (arg, "%i%i%i%i", &parser.glyph->bbox.width, - &parser.glyph->bbox.height, - &parser.glyph->bbox.offx, - &parser.glyph->bbox.offy); - if (!err) - { - parser.glyph_bwidth = (parser.glyph->bbox.width + 7) / 8; - parser.glyph_bheight = parser.glyph->bbox.height; - } - } - else if (!parser.glyph->has_swidth && !strcmp (line, "SWIDTH")) - { - parser.glyph->has_swidth = 1; - parse_template (arg, "%i%i", &parser.glyph->swidth.x, - &parser.glyph->swidth.y); - } - else if (!parser.glyph->has_dwidth && !strcmp (line, "DWIDTH")) - { - parser.glyph->has_dwidth = 1; - parse_template (arg, "%i%i", &parser.glyph->dwidth.x, - &parser.glyph->dwidth.y); - } - else if (!parser.glyph->has_swidth1 && !strcmp (line, "SWIDTH1")) - { - parser.glyph->has_swidth1 = 1; - parse_template (arg, "%i%i", &parser.glyph->swidth1.x, - &parser.glyph->swidth1.y); - } - else if (!parser.glyph->has_dwidth1 && !strcmp (line, "DWIDTH1")) - { - parser.glyph->has_dwidth1 = 1; - parse_template (arg, "%i%i", &parser.glyph->dwidth1.x, - &parser.glyph->dwidth1.y); - } - else if (!parser.glyph->has_vvector && !strcmp (line, "VVECTOR")) - { - parser.glyph->has_vvector = 1; - parse_template (arg, "%i%i", &parser.glyph->vvector.x, - &parser.glyph->vvector.y); - } - else - err = BDF_SYNTAX_ERROR; - } - break; - - case BITMAP: - /* This is the bitmap of a glyph. */ - if (!strcmp (line, "ENDCHAR")) - { - if (parser.glyph_blines != parser.glyph_bheight) - err = BDF_COUNT_MISMATCH; - parser.location = GLYPHS; - parser.glyph = 0; - } - else - { - if (strlen (line) != 2 * parser.glyph_bwidth) - err = BDF_SYNTAX_ERROR; - else if (parser.glyph_blines == parser.glyph_bheight) - err = BDF_COUNT_MISMATCH; - else - { - char *number = line; - unsigned char *bline = parser.glyph->bitmap - + parser.glyph_bwidth * parser.glyph_blines++; - - do - { - err = parse_hexbyte (number, bline); - number += 2; - bline++; - } - while (!err && *number); - } - } - break; - } - } - while (!err && !done && !feof (filep) && !ferror (filep)); - - leave: - if (ferror (filep)) - err = ferror (filep); - if (err) - free (bdf); - else - *font = bdf; - return err; -} - - -/* Destroy the BDF font object and release all associated - resources. */ -void -bdf_destroy (bdf_font_t font) -{ - int i; - for (i = 0; i < font->glyphs_count; i++) - free (font->glyphs[i].name); - free (font->glyphs); - for (i = 0; i < font->properties_count; i++) - { - free (font->properties[i].name); - if (font->properties[i].type == BDF_PROPERTY_STRING) - free (font->properties[i].value.string); - } - free (font->properties); - free (font->name); -} - - -bdf_error_t -bdf_new (bdf_font_t *font, int version_maj, int version_min, - const char *name, int point_size, int res_x, int res_y, - int bbox_width, int bbox_height, int bbox_offx, int bbox_offy, - int metricsset) -{ - bdf_font_t bdf; - - if (!font - || (version_maj != 2) - || (version_min != 1 && version_min != 2) - || !name) - return BDF_INVALID_ARGUMENT; - - bdf = calloc (1, sizeof *bdf); - if (!bdf) - { - errno = ENOMEM; - return BDF_SYSTEM_ERROR; - } - - bdf->version_maj = version_maj; - bdf->version_min = version_min; - bdf->name = strdup (name); - if (!name) - { - free (bdf); - errno = ENOMEM; - return BDF_SYSTEM_ERROR; - } - - bdf->point_size = point_size; - bdf->res_x = res_x; - bdf->res_y = res_y; - bdf->bbox.width = bbox_width; - bdf->bbox.height = bbox_height; - bdf->bbox.offx = bbox_offx; - bdf->bbox.offy = bbox_offy; - bdf->metricsset = metricsset; - *font = bdf; - return 0; -} - -#define bdf_set_something(what) \ -bdf_error_t \ -bdf_set_##what (bdf_font_t font, int glyph, int x, int y) \ -{ \ - if (x < 0 || y < 0 || glyph > font->glyphs_count - 1) \ - return BDF_INVALID_ARGUMENT; \ - if (glyph < 0) \ - { \ - font->has_##what = 1; \ - font->what.x = x; \ - font->what.y = y; \ - } \ - else \ - { \ - font->glyphs[glyph].has_##what = 1; \ - font->glyphs[glyph].what.x = x; \ - font->glyphs[glyph].what.y = y; \ - } \ - return 0; \ -} - -bdf_set_something (swidth) -bdf_set_something (dwidth) -bdf_set_something (swidth1) -bdf_set_something (dwidth1) -bdf_set_something (vvector) - - -static bdf_error_t -expand_properties (bdf_font_t font, int count) -{ - if (font->__properties_allocated == font->properties_count) - { - struct bdf_property *new; - new = realloc (font->properties, - (font->__properties_allocated + count) - * sizeof (struct bdf_property)); - if (!new) - { - errno = ENOMEM; - return BDF_SYSTEM_ERROR; - } - font->__properties_allocated += count; - font->properties = new; - } - return 0; -} - - -/* Add a new string property to the font FONT. */ -bdf_error_t -bdf_add_string_property (bdf_font_t font, const char *name, const char *value) -{ - bdf_error_t err; - struct bdf_property *prop; - - err = expand_properties (font, 16); - if (err) - { - err = expand_properties (font, 1); - if (err) - return err; - } - - prop = &font->properties[font->properties_count]; - prop->type = BDF_PROPERTY_STRING; - prop->name = strdup (name); - if (prop->name) - prop->value.string = strdup (value); - if (!prop->name || !prop->value.string) - { - errno = ENOMEM; - return BDF_SYSTEM_ERROR; - } - font->properties_count++; - return 0; -} - - -/* Add a new number property to the font FONT. */ -bdf_error_t -bdf_add_number_property (bdf_font_t font, const char *name, int value) -{ - bdf_error_t err; - struct bdf_property *prop; - - err = expand_properties (font, 16); - if (err) - { - err = expand_properties (font, 1); - if (err) - return err; - } - - prop = &font->properties[font->properties_count]; - prop->type = BDF_PROPERTY_NUMBER; - prop->name = strdup (name); - if (!prop->name) - { - errno = ENOMEM; - return BDF_SYSTEM_ERROR; - } - prop->value.number = value; - font->properties_count++; - return 0; -} - - -static bdf_error_t -expand_glyphs (bdf_font_t font, int count) -{ - if (font->__glyphs_allocated == font->glyphs_count) - { - struct bdf_glyph *new; - new = realloc (font->glyphs, - (font->__glyphs_allocated + count) - * sizeof (struct bdf_glyph)); - if (!new) - { - errno = ENOMEM; - return BDF_SYSTEM_ERROR; - } - font->__glyphs_allocated += count; - font->glyphs = new; - } - return 0; -} - - -/* Add a new glyph with the specified paramters to the font FONT. If - encoding is -1, internal_encoding specifies the internal - encoding. All other parameters are mandatory. */ -bdf_error_t -bdf_add_glyph (bdf_font_t font, const char *name, int encoding, - int internal_encoding, int bbox_width, int bbox_height, - int bbox_offx, int bbox_offy, const unsigned char *bitmap) -{ - bdf_error_t err; - struct bdf_glyph *glyph; - int bsize; - - err = expand_glyphs (font, 64); - if (err) - { - err = expand_glyphs (font, 1); - if (err) - return err; - } - - glyph = &font->glyphs[font->glyphs_count]; - memset (glyph, 0, sizeof (*glyph)); - - glyph->name = strdup (name); - if (!glyph->name) - { - errno = ENOMEM; - return BDF_SYSTEM_ERROR; - } - glyph->encoding = encoding; - if (encoding == -1) - glyph->internal_encoding = internal_encoding; - glyph->bbox.width = bbox_width; - glyph->bbox.height = bbox_height; - glyph->bbox.offx = bbox_offx; - glyph->bbox.offy = bbox_offy; - bsize = ((bbox_width + 7) / 8) * bbox_height; - glyph->bitmap = malloc (bsize); - if (!glyph->bitmap) - { - free (glyph->name); - errno = ENOMEM; - return BDF_SYSTEM_ERROR; - } - memcpy (glyph->bitmap, bitmap, bsize); - font->glyphs_count++; - return 0; -} - - -/* Write the font FONT in BDF format to stream FILEP. */ -bdf_error_t -bdf_write (FILE *filep, bdf_font_t font) -{ - int index; - - if (font->version_maj != 2 - || (font->version_min != 1 && font->version_min != 2)) - return BDF_INVALID_ARGUMENT; - fprintf (filep, "STARTFONT %i.%i\n", font->version_maj, font->version_min); - - if (!font->name) - return BDF_INVALID_ARGUMENT; - fprintf (filep, "FONT %s\n", font->name); - fprintf (filep, "SIZE %i %i %i\n", font->point_size, - font->res_x, font->res_y); - fprintf (filep, "FONTBOUNDINGBOX %i %i %i %i\n", - font->bbox.width, font->bbox.height, - font->bbox.offx, font->bbox.offy); - if (font->has_swidth) - fprintf (filep, "SWIDTH %i %i\n", font->swidth.x, font->swidth.y); - if (font->has_dwidth) - fprintf (filep, "DWIDTH %i %i\n", font->dwidth.x, font->dwidth.y); - if (font->has_swidth1) - fprintf (filep, "SWIDTH1 %i %i\n", font->swidth1.x, font->swidth1.y); - if (font->has_dwidth1) - fprintf (filep, "DWIDTH1 %i %i\n", font->dwidth1.x, font->dwidth1.y); - if (font->has_vvector) - fprintf (filep, "VVECTOR %i %i\n", font->vvector.x, font->vvector.y); - if (font->properties_count < 0) - return BDF_INVALID_ARGUMENT; - if (font->properties_count > 0) - { - fprintf (filep, "STARTPROPERTIES %i\n", font->properties_count); - for (index = 0; index < font->properties_count; index++) - { - struct bdf_property *prop = &font->properties[index]; - - if (prop->type == BDF_PROPERTY_NUMBER) - fprintf (filep, "%s %i\n", prop->name, prop->value.number); - else - { - char *val = prop->value.string; - - fprintf (filep, "%s \"", prop->name); - while (*val) - { - fputc (*val, filep); - if (*(val++) == '"') - fputc ('"', filep); - } - fprintf (filep, "\"\n"); - } - } - fprintf (filep, "ENDPROPERTIES\n"); - } - if (font->glyphs_count <= 0) - return BDF_INVALID_ARGUMENT; - fprintf (filep, "CHARS %i\n", font->glyphs_count); - - for (index = 0; index < font->glyphs_count; index++) - { - struct bdf_glyph *glyph = &font->glyphs[index]; - unsigned char *bitmap; - int row, col; - - fprintf (filep, "STARTCHAR %s\n", glyph->name); - if (glyph->encoding != -1) - fprintf (filep, "ENCODING %i\n", glyph->encoding); - else - fprintf (filep, "ENCODING %i %i\n", glyph->encoding, - glyph->internal_encoding); - if (glyph->has_swidth) - fprintf (filep, "SWIDTH %i %i\n", glyph->swidth.x, glyph->swidth.y); - if (glyph->has_dwidth) - fprintf (filep, "DWIDTH %i %i\n", glyph->dwidth.x, glyph->dwidth.y); - if (glyph->has_swidth1) - fprintf (filep, "SWIDTH1 %i %i\n", glyph->swidth1.x, glyph->swidth1.y); - if (glyph->has_dwidth1) - fprintf (filep, "DWIDTH1 %i %i\n", glyph->dwidth1.x, glyph->dwidth1.y); - if (glyph->has_vvector) - fprintf (filep, "VVECTOR %i %i\n", glyph->vvector.x, glyph->vvector.y); - fprintf (filep, "BBX %i %i %i %i\n", glyph->bbox.width, - glyph->bbox.height, glyph->bbox.offx, glyph->bbox.offy); - fprintf (filep, "BITMAP\n"); - bitmap = glyph->bitmap; - for (row = 0; row < glyph->bbox.height; row++) - { - for (col = 0; col < (glyph->bbox.width + 7) / 8; col++) - fprintf (filep, "%02X", *(bitmap++)); - fputc ('\n', filep); - } - fprintf (filep, "ENDCHAR\n"); - } - fprintf (filep, "ENDFONT\n"); - if (ferror (filep)) - { - errno = ferror (filep); - return BDF_SYSTEM_ERROR; - } - return 0; -} - - -/* The function returns -1 if the encoding of glyph A is lower than - the encoding of glyph B, 1 if it is the other way round, and 0 if - the encoding of both glyphs is the same. */ -int -bdf_compare_glyphs (const void *a, const void *b) -{ - struct bdf_glyph *first = (struct bdf_glyph *) a; - struct bdf_glyph *second = (struct bdf_glyph *) b; - - if (first->encoding < second->encoding) - return -1; - else if (first->encoding > second->encoding) - return 1; - else - { - if (first->encoding == -1) - { - if (first->internal_encoding < second->internal_encoding) - return -1; - else if (first->internal_encoding > second->internal_encoding) - return 1; - else - return 0; - } - else - return 0; - } -} - - -/* Sort the glyphs in the font FONT. This must be called before using - bdf_find_glyphs, after the font has been created or after new - glyphs have been added to the font. */ -void -bdf_sort_glyphs (bdf_font_t font) -{ - qsort (font->glyphs, font->glyphs_count, sizeof (struct bdf_glyph), - bdf_compare_glyphs); -} - - -/* Find the glyph with the encoding ENC (and INTERNAL_ENC, if ENC is - -1) in the font FONT. Requires that the glyphs in the font are - sorted. */ -struct bdf_glyph * -bdf_find_glyph (bdf_font_t font, int enc, int internal_enc) -{ - struct bdf_glyph key = { encoding: enc, internal_encoding: internal_enc }; - return bsearch (&key, font->glyphs, font->glyphs_count, - sizeof (struct bdf_glyph), bdf_compare_glyphs); -} |