diff options
author | px4dev <px4@purgatory.org> | 2012-08-04 15:12:36 -0700 |
---|---|---|
committer | px4dev <px4@purgatory.org> | 2012-08-04 15:12:36 -0700 |
commit | 8a365179eafdf3aea98e60ab9f5882b200d4c759 (patch) | |
tree | 4f38d6d4cd80bd0b6e22e2bb534c3f117ce44e56 /nuttx/tools/bdf-converter.c | |
download | px4-firmware-8a365179eafdf3aea98e60ab9f5882b200d4c759.tar.gz px4-firmware-8a365179eafdf3aea98e60ab9f5882b200d4c759.tar.bz2 px4-firmware-8a365179eafdf3aea98e60ab9f5882b200d4c759.zip |
Fresh import of the PX4 firmware sources.
Diffstat (limited to 'nuttx/tools/bdf-converter.c')
-rw-r--r-- | nuttx/tools/bdf-converter.c | 675 |
1 files changed, 675 insertions, 0 deletions
diff --git a/nuttx/tools/bdf-converter.c b/nuttx/tools/bdf-converter.c new file mode 100644 index 000000000..b32209fcf --- /dev/null +++ b/nuttx/tools/bdf-converter.c @@ -0,0 +1,675 @@ +/**************************************************************************** + * tools/bdf-converter.c + * + * Copyright (C) 2011 NX Engineering, S.A., All rights reserved. + * Author: Jose Pablo Carballo Gomez <jcarballo@nx-engineering.com> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/* + * Based one the "Glyph Bitmap Distribution Format (BDF) Specification", + * Version 2.2, by Adobe Systems Incorporated. + * + */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <stdbool.h> +#include <string.h> +#include <ctype.h> + +/**************************************************************************** + * Pre-Processor Definitions + ****************************************************************************/ + +/* +#define VERBOSE +#define DBG +*/ + +// BDF Specification Version 2.2: +// This version lifts the restriction on line length. In this version, the new +// maximum length of a value of the type string is 65535 characters, and hence +// lines may now be at least this long. + +#define BDF_MAX_LINE_LENGTH 65535 + +/* Ranges of 7-bit and 8-bit fonts */ + +#define NXFONT_MIN7BIT 33 +#define NXFONT_MAX7BIT 126 + +#define NXFONT_MIN8BIT 161 +#define NXFONT_MAX8BIT 255 + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +/* This structure holds information about a glyph */ + +typedef struct glyphinfo_s +{ + char *name; /* Name for they glyph */ + int encoding; /* The Adobe Standard Encoding value */ + int dw_x0; /* Width in x of the vector indicating + * the position of the next glyph's origin + * relative to the origin of this glyph */ + int dw_y0; /* Width in y of the vector indicating + * the position of the next glyph's origin + * relative to the origin of this glyph */ + int bb_w; /* The width of the black pixels in x */ + int bb_h; /* The height of the black pixels in y */ + int bb_x_off; /* X displacement of the lower left corner + * of the bitmap from origin 0 */ + int bb_y_off; /* Y displacement of the lower left corner + * of the bitmap from origin 0 */ + uint64_t *bitmap; /* Hexadecimal data for the character bitmap */ +} glyphinfo_t; + +/* This structures provides the metrics for one glyph */ + +typedef struct nx_fontmetric_s +{ + uint32_t stride : 3; /* Width of one font row in bytes */ + uint32_t width : 6; /* Width of the font in bits */ + uint32_t height : 6; /* Height of the font in rows */ + uint32_t xoffset : 6; /* Top, left-hand corner X-offset in pixels */ + uint32_t yoffset : 6; /* Top, left-hand corner y-offset in pixels */ + uint32_t unused : 5; +} nx_fontmetric_t; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: trimLine + * + * Description: + * Trims the line removing space characters at the front and at the end + * of the line. + * + * Input Parameters: + * line - The line to trim + * + ****************************************************************************/ +static void trimLine(char *line) +{ + char *str; + str = line; + char *strEnd; + for (strEnd = str + strlen(str) - 1; + strEnd >= str && isspace((int)(*strEnd)); + strEnd--); + *(strEnd + 1) = 0; +} + +/**************************************************************************** + * Name: bdf_parseIntLine + * + * Description: + * Parses a line containing a BDF property followed by integers. It will + * ignore the first token that corresponds to the property name. + * + * Input Parameters: + * line - A line with a BDF property followed by integers, i.e.: + * "FONTBOUNDINGBOX 8 13 0 -2" + * count - How many integers are specified by the BDF property. In the + * example above, count = 4. + * info - A pointer to memory provided by the caller in which to + * return the array of integers. For the example above: + * info[0] = 8 + * info[1] = 13 + * info[2] = 0 + * info[3] = -2 + * + ****************************************************************************/ +static void bdf_parseintline(char *line, unsigned int count, int *info) +{ + char *str, *token, *saveptr1; + str = line; + + /* Ignore the key */ + + token = (char *)strtok_r(str, " ", &saveptr1); + + while ((token = (char *)strtok_r(NULL, " ", &saveptr1)) && count--) + { + *(info++) = atoi(token); + } +} + +/**************************************************************************** + * Name: bdf_printglyphinfo + * + * Description: + * Prints the information available for a glyph. + * + * Input Parameters: + * ginfo - A glyphinfo_t struct with the glyph's information. + * + ****************************************************************************/ +#ifdef DBG +static void bdf_printglyphinfo(const glyphinfo_t *ginfo) +{ + printf("NAME = %s\n", ginfo->name); + printf("ENCODING = %d\n", ginfo->encoding); + printf("DW_X0 = %d\n", ginfo->dw_x0); + printf("DW_Y0 = %d\n", ginfo->dw_y0); + printf("BB_W = %d\n", ginfo->bb_w); + printf("BB_H = %d\n", ginfo->bb_h); + printf("BB_X_OFF = %d\n", ginfo->bb_x_off); + printf("BB_Y_OFF = %d\n", ginfo->bb_y_off); + int i; + for (i = 0; i < ginfo->bb_h; i++) + { + printf("BITMAP[%d] = %x\n", i, ginfo->bitmap[i]); + } +} +#endif /* DBG */ + +/**************************************************************************** + * Name: bdf_printnxmetricinfo + * + * Description: + * Prints the information available for a glyph's metric in the NX + * graphics system. + * + * Input Parameters: + * info - A nx_fontmetric_t struct with the glyph's information. + * + ****************************************************************************/ +#ifdef DBG +static void bdf_printnxmetricinfo(const nx_fontmetric_t *info) +{ + printf("STRIDE = %d\n", info->stride); + printf("WIDTH = %d\n", info->width); + printf("HEIGHT = %d\n", info->height); + printf("XOFFSET = %d\n", info->xoffset); + printf("YOFFSET = %d\n", info->yoffset); +} +#endif /* DBG */ + +/**************************************************************************** + * Name: bdf_getglyphinfo + * + * Description: + * Obtains the information for an individual glyph. The BDF properties + * taken into account are: + * - ENCODING + * - DWIDTH + * - BBX + * BDF properties ignored: + * - SWIDTH + * - SWIDTH1 + * - DWIDTH1 + * - VVECTOR + * + * Input Parameters: + * file - The input file stream pointing to the first line of the + * glyph's information (right after STARTCHAR). + * ginfo - A glyphinfo_t struct to fill with the glyph's information. + * + ****************************************************************************/ +static void bdf_getglyphinfo(FILE *file, glyphinfo_t *ginfo) +{ + char line[BDF_MAX_LINE_LENGTH]; + char lineCopy[BDF_MAX_LINE_LENGTH]; + char *str, *token, *saveptr1; + bool done; + + done = false; + + while(fgets(line, BDF_MAX_LINE_LENGTH, file) != NULL && !done) + { + trimLine(line); + strcpy(lineCopy, line); + str = line; + + while ((token = (char *)strtok_r(str, " ", &saveptr1))) + { + + /* ENCODING information */ + + if(strcmp(token, "ENCODING") == 0) + { + token = (char *)strtok_r(NULL, " ", &saveptr1); + ginfo->encoding = atoi(token); + } + + /* DWIDTH information */ + + if(strcmp(token, "DWIDTH") == 0) + { + token = (char *)strtok_r(NULL, " ", &saveptr1); + ginfo->dw_x0 = atoi(token); + token = (char *)strtok_r(NULL, " ", &saveptr1); + ginfo->dw_y0 = atoi(token); + } + + /* BBX information */ + + else if(strcmp(token, "BBX") == 0) + { + int bbxinfo[4]; + bdf_parseintline(lineCopy, 4, bbxinfo); + ginfo->bb_w = bbxinfo[0]; + ginfo->bb_h = bbxinfo[1]; + ginfo->bb_x_off = bbxinfo[2]; + ginfo->bb_y_off = bbxinfo[3]; + + /* This is the last BDF property of interest*/ + + done = true; + } + + str = NULL; + } + + } +} + +/**************************************************************************** + * Name: bdf_getglyphbitmap + * + * Description: + * Obtains the character bitmap information for an individual glyph. + * + * Input Parameters: + * file - The input file stream pointing to the first line of the + * glyph's bitmap (right after BITMAP). + * ginfo - A glyphinfo_t struct to fill with the glyph's bitmap. + * + ****************************************************************************/ +static void bdf_getglyphbitmap(FILE *file, glyphinfo_t *ginfo) +{ + char line[BDF_MAX_LINE_LENGTH]; + uint64_t *bitmap; + bool readingbitmap; + + bitmap = ginfo->bitmap; + readingbitmap = true; + + while (readingbitmap) + { + if (fgets(line, BDF_MAX_LINE_LENGTH, file) != NULL) + { + trimLine(line); + + if(strcmp(line, "ENDCHAR") == 0) + { + readingbitmap = false; + } + else + { + char *endptr; + *bitmap = strtoul(line, &endptr, 16); + bitmap++; + } + + } + else + { + /* error condition */ + + readingbitmap = false; + } + + } +} + +/**************************************************************************** + * Name: bdf_getstride + * + * Description: + * Obtains the stride for an individual glyph. The stride is the width + * of one glyph's bitmap row in bytes. + * + * Input Parameters: + * ginfo - A glyphinfo_t struct with the glyph's information. + * stride - A pointer to memory provided by the caller in which to + * return the stride. + * + ****************************************************************************/ +static void bdf_getstride(glyphinfo_t *ginfo, uint32_t *stride) +{ + *stride = (ginfo->bb_w % 8 == 0) ? ginfo->bb_w / 8 : ginfo->bb_w / 8 + 1; +} + +/**************************************************************************** + * Name: bdf_printoutput + * + * Description: + * Prints to the output stream the information of an individual glyph in + * the NuttX font format. + * + * Input Parameters: + * out - The output stream. + * ginfo - A glyphinfo_t struct with the glyph's information. + * nxmetric - A nx_fontmetric_t struct with the glyph's information. + * + ****************************************************************************/ +static void bdf_printoutput(FILE *out, + glyphinfo_t *ginfo, + nx_fontmetric_t *nxmetric) +{ + + /* Only interested in the 7 and 8 bit ranges */ + + if ((ginfo->encoding >= NXFONT_MIN7BIT && + ginfo->encoding <= NXFONT_MAX7BIT) || + (ginfo->encoding >= NXFONT_MIN8BIT && + ginfo->encoding <= NXFONT_MAX8BIT)) + { + + /* Glyph general info */ + + if (ginfo->bb_x_off < 0) + { + fprintf(out, + "/* %s (%d) -- NOTE: Xoffset should be %d, not 0. */\n", + ginfo->name, + ginfo->encoding, + ginfo->bb_x_off); + } + else + { + fprintf(out, "/* %s (%d) */\n", ginfo->name, ginfo->encoding); + } + + /* Glyph metrics */ + + fprintf(out, + "#define NXFONT_METRICS_%d {%d, %d, %d, %d, %d, 0}\n", + ginfo->encoding, + nxmetric->stride, + nxmetric->width, + nxmetric->height, + nxmetric->xoffset, + nxmetric->yoffset); + + /* Glyph bitmap */ + + fprintf(out, "#define NXFONT_BITMAP_%d {", ginfo->encoding); + int i, j; + for (i = 0; i < ginfo->bb_h - 1; i++) + { + for (j = 1; j <= nxmetric->stride; j++) + { + int nxbyteoffset; + uint8_t nxbyte = 0; + uint64_t tempbitmap = ginfo->bitmap[i]; + + /* Get the next byte */ + + nxbyteoffset = (nxmetric->stride - j) * 8; + nxbyte = (uint8_t)(tempbitmap >> nxbyteoffset); + fprintf(out, "0x%x, ", nxbyte); + } + } + + /* Different behavior for the last bitmap */ + + for (j = 1; j <= nxmetric->stride; j++) + { + int nxbyteoffset; + uint8_t nxbyte = 0; + uint64_t tempbitmap = ginfo->bitmap[i]; + + /* Get the next byte */ + + nxbyteoffset = (nxmetric->stride - j) * 8; + nxbyte = (uint8_t)(tempbitmap >> nxbyteoffset); + + if (j == nxmetric->stride) + { + fprintf(out, "0x%x}\n", nxbyte); + } + else + { + fprintf(out, "0x%x, ", nxbyte); + } + } + + fprintf(out, "\n"); + } + +} + +/**************************************************************************** + * Main + ****************************************************************************/ + +int main(int argc, char **argv) +{ + FILE *file, *out; + char line[BDF_MAX_LINE_LENGTH]; + char lineCopy[BDF_MAX_LINE_LENGTH]; + char *str, *token, *saveptr1; + char *input, *output; + + /* FONTBOUNDINGBOX properties*/ + + int fbb_x = 0; + int fbb_y = 0; + int fbb_x_off = 0; + int fbb_y_off = 0; + + /* Input BDF file */ + + input = argv[1]; + + if (input == NULL) + { + printf("%s: no input file\n", argv[0]); + exit(0); + } + + file = fopen(input, "r"); + + if (file == NULL) + { + printf("%s: error opening file %s\n", argv[0], input); + exit(0); + } + else + { +#ifdef VERBOSE + printf("Opening \"%s\"\n", input); +#endif /* VERBOSE */ + } + + /* Output file */ + if (argv[2]) + { + output = argv[2]; + } + else + { + output = "nxfonts_myfont.h"; + } + + out = fopen(output, "w"); + + if (out == NULL) + { + printf("%s: error opening file %s\n", argv[0], output); + fclose(file); + exit(0); + } + else + { + while (fgets(line, BDF_MAX_LINE_LENGTH, file) != NULL) + { + +#ifdef DBG + printf("--\n"); +#endif /* DBG */ + + // Save a copy of the line + + strcpy(lineCopy,line); + + // Clean it + + trimLine(line); + str = line; + + while ((token = (char *)strtok_r(str, " ", &saveptr1))) + { + + /* FONTBOUNDINGBOX - Global font information */ + + if (strcmp(token, "FONTBOUNDINGBOX") == 0) + { + int fbbinfo[4]; + bdf_parseintline(lineCopy, 4, fbbinfo); + fbb_x = fbbinfo[0]; + fbb_y = fbbinfo[1]; + fbb_x_off = fbbinfo[2]; + fbb_y_off = fbbinfo[3]; + + /* Print FONTBOUNDINGBOX information */ + + fprintf(out, "/* Maximum height and width of any"); + fprintf(out, " glyph in the set */\n\n"); + fprintf(out, "#define NXFONT_MAXHEIGHT %d\n", fbb_y); + fprintf(out, "#define NXFONT_MAXWIDTH %d\n\n", fbb_x); + } + + /* STARTCHAR - Individual glyph information */ + + if (strcmp(token, "STARTCHAR") == 0) + { + glyphinfo_t ginfo; + + /* Glyph name */ + + ginfo.name = (char *)strtok_r(NULL, " ", &saveptr1); + +#ifdef VERBOSE + printf("Processing glyph: %s\n", ginfo.name); +#endif /* VERBOSE */ + + /* Glyph information: + * ENCODING + * DWIDTH + * BBX + */ + ginfo.encoding = 0; + ginfo.dw_x0 = 0; + ginfo.dw_y0 = 0; + ginfo.bb_w = 0; + ginfo.bb_h = 0; + ginfo.bb_x_off = 0; + ginfo.bb_y_off = 0; + bdf_getglyphinfo(file, &ginfo); + + /* Glyph bitmap */ + + ginfo.bitmap = malloc(sizeof(uint64_t) * ginfo.bb_h); + bdf_getglyphbitmap(file, &ginfo); + +#ifdef DBG + bdf_printglyphinfo(&ginfo); +#endif /* DBG */ + + /* Convert to nxfonts */ + + nx_fontmetric_t nxmetric; + uint32_t stride; + bdf_getstride(&ginfo, &stride); + nxmetric.stride = stride; + nxmetric.width = ginfo.bb_w; + nxmetric.height = ginfo.bb_h; + + /* The NuttX font format does not support + * negative X offsets. */ + + if (ginfo.bb_x_off < 0) + { + nxmetric.xoffset = 0; + printf("%s: ignoring negative x offset for " + "glyph '%s' (%d)\n", + argv[0], + ginfo.name, + ginfo.encoding); + } + else + { + nxmetric.xoffset = ginfo.bb_x_off; + } + + nxmetric.yoffset = fbb_y + fbb_y_off - + ginfo.bb_y_off - ginfo.bb_h; + + +#ifdef DBG + bdf_printnxmetricinfo(&nxmetric); +#endif /* DBG */ + + /* The space (32) character is treated differently */ + + if (ginfo.encoding == 32) + { + fprintf(out, "/* The width of a space */\n\n"); + fprintf(out, "#define NXFONT_SPACEWIDTH %d\n\n", ginfo.dw_x0); + } + else + { + bdf_printoutput(out, &ginfo, &nxmetric); + } + + /* Free memory */ + + free(ginfo.bitmap); + + } + + str = NULL; + } + + } + fclose(file); + fclose(out); + + /* The End */ + + printf("Generated \"%s\"\n", output); + + } + + return EXIT_SUCCESS; +} |