123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752 |
- /****************************************************************************
- * tools/bdf-converter.c
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership. The
- * ASF licenses this file to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance with the
- * License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- *
- ****************************************************************************/
- /* Based one the "Glyph Bitmap Distribution Format (BDF) Specification",
- * Version 2.2, by Adobe Systems Incorporated.
- */
- /****************************************************************************
- * Included Files
- ****************************************************************************/
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
- #include <string.h>
- #include <ctype.h>
- /****************************************************************************
- * Pre-processor Definitions
- ****************************************************************************/
- #if 0
- # define VERBOSE
- # define DBG
- #endif
- /* 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
- /****************************************************************************
- * Private 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: my_strtok_r
- *
- * Description:
- * MinGW does not seem to provide strtok_r
- *
- ****************************************************************************/
- #ifndef HAVE_STRTOK_R
- static char *my_strtok_r(char *str, const char *delim, char **saveptr)
- {
- char *pbegin;
- char *pend = NULL;
- /* Decide if we are starting a new string or continuing from
- * the point we left off.
- */
- if (str)
- {
- pbegin = str;
- }
- else if (saveptr && *saveptr)
- {
- pbegin = *saveptr;
- }
- else
- {
- return NULL;
- }
- /* Find the beginning of the next token */
- for (;
- *pbegin && strchr(delim, *pbegin) != NULL;
- pbegin++);
- /* If we are at the end of the string with nothing
- * but delimiters found, then return NULL.
- */
- if (!*pbegin)
- {
- return NULL;
- }
- /* Find the end of the token */
- for (pend = pbegin + 1;
- *pend && strchr(delim, *pend) == NULL;
- pend++);
- /* pend either points to the end of the string or to
- * the first delimiter after the string.
- */
- if (*pend)
- {
- /* Turn the delimiter into a null terminator */
- *pend++ = '\0';
- }
- /* Save the pointer where we left off and return the
- * beginning of the token.
- */
- if (saveptr)
- {
- *saveptr = pend;
- }
- return pbegin;
- }
- #undef strtok_r
- #define strtok_r my_strtok_r
- #endif
- /****************************************************************************
- * 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;
- char *token;
- char *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;
- char *token;
- char *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)
- {
- int i;
- int j;
- /* 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);
- 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;
- char *token;
- char *saveptr1;
- char *input;
- char *output;
- /* FONTBOUNDINGBOX properties */
- int fbb_x = 0;
- int fbb_y = 0;
- int fbb_y_off = 0;
- /* int fbb_x_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;
- }
|