graphlcd-base/tools/crtfont/crtfont.c
changeset 4 df6a40031aa5
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/graphlcd-base/tools/crtfont/crtfont.c	Wed Feb 06 17:32:55 2008 +0000
     1.3 @@ -0,0 +1,305 @@
     1.4 +/*
     1.5 + * GraphLCD tool crtfont
     1.6 + *
     1.7 + * crtfont.c  -  a tool to create *.fnt files for use with the GraphLCD
     1.8 + *               graphics library
     1.9 + *
    1.10 + * based on graphlcd plugin 0.1.1 for the Video Disc Recorder
    1.11 + *  (c) 2001-2004 Carsten Siebholz <c.siebholz AT t-online.de>
    1.12 + *
    1.13 + * This file is released under the GNU General Public License. Refer
    1.14 + * to the COPYING file distributed with this package.
    1.15 + *
    1.16 + * (c) 2004 Andreas Regel <andreas.regel AT powarman.de>
    1.17 + */
    1.18 +
    1.19 +#include <getopt.h>
    1.20 +#include <stdint.h>
    1.21 +#include <stdio.h>
    1.22 +#include <stdlib.h>
    1.23 +#include <string.h>
    1.24 +#include <glcdgraphics/bitmap.h>
    1.25 +#include <glcdgraphics/font.h>
    1.26 +
    1.27 +static const char *prgname = "crtfont";
    1.28 +static const char *version = "0.1.6";
    1.29 +
    1.30 +const int kMaxLineLength = 1024;
    1.31 +
    1.32 +enum ePicFormat
    1.33 +{
    1.34 +    undefined,
    1.35 +    PBM
    1.36 +};
    1.37 +
    1.38 +
    1.39 +void usage(void);
    1.40 +
    1.41 +char * trimleft(char * str)
    1.42 +{
    1.43 +    char * s = str;
    1.44 +    while (*s == ' ' || *s == '\t')
    1.45 +        s++;
    1.46 +    strcpy(str, s);
    1.47 +    return str;
    1.48 +}
    1.49 +
    1.50 +char * trimright(char * str)
    1.51 +{
    1.52 +    char * s = str + strlen(str) - 1;
    1.53 +    while (s >= str && (*s == ' ' || *s == '\t' || *s == '\n' || *s == '\r'))
    1.54 +        *s-- = 0;
    1.55 +    return str;
    1.56 +}
    1.57 +
    1.58 +char * trim(char * str)
    1.59 +{
    1.60 +    return trimleft(trimright(str));
    1.61 +}
    1.62 +
    1.63 +
    1.64 +int main(int argc, char *argv[])
    1.65 +{
    1.66 +    ePicFormat picFormat = undefined;
    1.67 +    GLCD::cFont font;
    1.68 +    char * picName = NULL;
    1.69 +    char * descName = NULL;
    1.70 +    char * fontName = NULL;
    1.71 +    FILE * descFile;
    1.72 +    bool error = false;
    1.73 +    GLCD::cBitmap * bitmap = NULL;
    1.74 +    GLCD::cBitmap * tmpBitmap = NULL;
    1.75 +    GLCD::cBitmap * charBitmap = NULL;
    1.76 +    char line[kMaxLineLength];
    1.77 +    int l = 0;
    1.78 +    char * token;
    1.79 +    int startOffset, endOffset;
    1.80 +    int spaceWidth;
    1.81 +    int version;
    1.82 +    char * ptr;
    1.83 +
    1.84 +    static struct option long_options[] =
    1.85 +    {
    1.86 +        { "format",   required_argument, NULL, 'f'},
    1.87 +        { "bmpfile",  required_argument, NULL, 'b'},
    1.88 +        { "descfile", required_argument, NULL, 'd'},
    1.89 +        { "outfile",  required_argument, NULL, 'o'},
    1.90 +        { NULL}
    1.91 +    };
    1.92 +
    1.93 +    int c, option_index = 0;
    1.94 +    while ((c = getopt_long(argc, argv, "f:b:d:o:", long_options, &option_index)) != -1)
    1.95 +    {
    1.96 +        switch (c)
    1.97 +        {
    1.98 +            case 'f':
    1.99 +                if (strcasecmp(optarg, "PBM") == 0)
   1.100 +                    picFormat = PBM;
   1.101 +                break;
   1.102 +
   1.103 +            case 'b':
   1.104 +                picName = strdup(optarg);
   1.105 +                break;
   1.106 +
   1.107 +            case 'd':
   1.108 +                descName = strdup(optarg);
   1.109 +                break;
   1.110 +
   1.111 +            case 'o':
   1.112 +                fontName = strdup(optarg);
   1.113 +                break;
   1.114 +
   1.115 +            default:
   1.116 +                return 1;
   1.117 +        }
   1.118 +    }
   1.119 +
   1.120 +    if (picFormat == undefined)
   1.121 +    {
   1.122 +        fprintf(stderr, "ERROR: You have to specify the format   (-f <format>)\n");
   1.123 +        error = true;
   1.124 +    }
   1.125 +    if (!picName)
   1.126 +    {
   1.127 +        fprintf(stderr, "ERROR: You have to specify the bmpfile  (-b bmpfile)\n");
   1.128 +        error = true;
   1.129 +    }
   1.130 +    if (!descName)
   1.131 +    {
   1.132 +        fprintf(stderr, "ERROR: You have to specify the descfile (-d descfile)\n");
   1.133 +        error = true;
   1.134 +    }
   1.135 +    if (!fontName)
   1.136 +    {
   1.137 +        fprintf(stderr, "ERROR: You have to specify the outfile  (-o outfile)\n");
   1.138 +        error = true;
   1.139 +    }
   1.140 +
   1.141 +    if (error)
   1.142 +    {
   1.143 +        usage();
   1.144 +        return 1;
   1.145 +    }
   1.146 +
   1.147 +    descFile = fopen(descName,"r");
   1.148 +    if (!descFile)
   1.149 +    {
   1.150 +        fprintf(stderr, "Cannot open file: %s\n",descName);
   1.151 +        return 2;
   1.152 +    }
   1.153 +
   1.154 +    // Load Picture
   1.155 +    switch (picFormat)
   1.156 +    {
   1.157 +        case PBM:
   1.158 +            bitmap = new GLCD::cBitmap(0, 0);
   1.159 +            bitmap->LoadPBM(picName);
   1.160 +            if (!bitmap)
   1.161 +            {
   1.162 +                fprintf(stderr, "Cannot open file: %s\n",picName);
   1.163 +                return 2;
   1.164 +            }
   1.165 +            break;
   1.166 +
   1.167 +        default:
   1.168 +            return 2;
   1.169 +    }
   1.170 +
   1.171 +    if (!bitmap)
   1.172 +        return 3;
   1.173 +
   1.174 +    spaceWidth = 0;
   1.175 +
   1.176 +    version = 0;
   1.177 +    fgets(line, sizeof(line), descFile);
   1.178 +    trim(line);
   1.179 +    if (strstr(line, "version") != NULL)
   1.180 +    {
   1.181 +        ptr = strstr(line, ":");
   1.182 +        version = atoi(ptr + 1);
   1.183 +    }
   1.184 +    if (version != 1)
   1.185 +    {
   1.186 +        fprintf(stderr, "Wrong description file format version (found %d, expected 1)!\n", version);
   1.187 +        return 2;
   1.188 +    }
   1.189 +    while (!feof(descFile))
   1.190 +    {
   1.191 +        fgets(line, sizeof(line), descFile);
   1.192 +        trim(line);
   1.193 +        if (strstr(line, "fontheight") != NULL)
   1.194 +        {
   1.195 +            ptr = strstr(line, ":");
   1.196 +            font.SetTotalHeight(atoi(ptr + 1));
   1.197 +        }
   1.198 +        else if (strstr(line, "fontascent") != NULL)
   1.199 +        {
   1.200 +            ptr = strstr(line, ":");
   1.201 +            font.SetTotalAscent(atoi(ptr + 1));
   1.202 +        }
   1.203 +        else if (strstr(line, "lineheight") != NULL)
   1.204 +        {
   1.205 +            ptr = strstr(line, ":");
   1.206 +            font.SetLineHeight(atoi(ptr + 1));
   1.207 +        }
   1.208 +        else if (strstr(line, "spacebetween") != NULL)
   1.209 +        {
   1.210 +            ptr = strstr(line, ":");
   1.211 +            font.SetSpaceBetween(atoi(ptr + 1));
   1.212 +        }
   1.213 +        else if (strstr(line, "spacewidth") != NULL)
   1.214 +        {
   1.215 +            ptr = strstr(line, ":");
   1.216 +            spaceWidth = atoi(ptr + 1);
   1.217 +        }
   1.218 +        else
   1.219 +        {
   1.220 +            token = strtok(line, " ");
   1.221 +            if (token)
   1.222 +            {
   1.223 +                startOffset = atoi(token);
   1.224 +
   1.225 +                // get character
   1.226 +                token = strtok(NULL, " ");
   1.227 +                while (token)
   1.228 +                {
   1.229 +                    uint16_t character;
   1.230 +                    if (strlen(token) == 1)
   1.231 +                        character = (uint8_t) token[0];
   1.232 +                    else
   1.233 +                        character = atoi(token);
   1.234 +
   1.235 +                    // get EndOffset
   1.236 +                    token = strtok(NULL, " ");
   1.237 +                    endOffset = atoi(token);
   1.238 +                    tmpBitmap = bitmap->SubBitmap(startOffset, l * font.TotalHeight(), endOffset - 1, (l + 1) * font.TotalHeight() - 1);
   1.239 +                    if (spaceWidth > 0)
   1.240 +                    {
   1.241 +                        // calculate width of this character
   1.242 +                        int x;
   1.243 +                        int y;
   1.244 +                        int left = 255;
   1.245 +                        int right = 0;
   1.246 +                        for (y = 0; y < tmpBitmap->Height(); y++)
   1.247 +                        {
   1.248 +                            for (x = 0; x < tmpBitmap->Width(); x++)
   1.249 +                            {
   1.250 +                                if (tmpBitmap->GetPixel(x, y))
   1.251 +                                    break;
   1.252 +                            }
   1.253 +                            if (x < tmpBitmap->Width() && x < left)
   1.254 +                                left = x;
   1.255 +                            for (x = tmpBitmap->Width() - 1; x >= 0; x--)
   1.256 +                            {
   1.257 +                                if (tmpBitmap->GetPixel(x, y))
   1.258 +                                    break;
   1.259 +                            }
   1.260 +                            if (x >= 0 && x > right)
   1.261 +                                right = x;
   1.262 +                        }
   1.263 +                        if (left > right)
   1.264 +                        {
   1.265 +                            left = 0;
   1.266 +                            right = spaceWidth - 1;
   1.267 +                        }
   1.268 +                        charBitmap = tmpBitmap->SubBitmap(left, 0, right, font.TotalHeight() - 1);
   1.269 +                        font.SetCharacter(character, charBitmap);
   1.270 +                        delete tmpBitmap;
   1.271 +                    }
   1.272 +                    else
   1.273 +                    {
   1.274 +                        font.SetCharacter(character, tmpBitmap);
   1.275 +                    }
   1.276 +                    startOffset = endOffset;
   1.277 +
   1.278 +                    // get next character
   1.279 +                    token = strtok(NULL, " ");
   1.280 +                }
   1.281 +            }
   1.282 +            l++;
   1.283 +        }
   1.284 +    }
   1.285 +    fclose(descFile);
   1.286 +    delete bitmap;
   1.287 +
   1.288 +    if (font.SaveFNT(fontName))
   1.289 +        fprintf(stdout,"Font '%s' created successfully\n", fontName);
   1.290 +
   1.291 +    return 0;
   1.292 +}
   1.293 +
   1.294 +void usage(void)
   1.295 +{
   1.296 +    fprintf(stdout, "\n");
   1.297 +    fprintf(stdout, "%s v%s\n", prgname, version);
   1.298 +    fprintf(stdout, "%s is a tool to create *.fnt files that are used by the\n", prgname);
   1.299 +    fprintf(stdout, "        graphlcd plugin for VDR.\n\n");
   1.300 +    fprintf(stdout, "  Usage: %s -f <format> -b bmpfile -d descfile -o outfile\n\n", prgname);
   1.301 +    fprintf(stdout, "  -f  --format      specifies the format of the bitmap. Possible values are:\n");
   1.302 +    fprintf(stdout, "                    PBM : file is an binary PBM file\n" );
   1.303 +    fprintf(stdout, "  -b  --bmpfile     specifies the name of the bitmap file (*.pbm)\n");
   1.304 +    fprintf(stdout, "  -d  --descfile    specifies the name of the description file (*.desc)\n");
   1.305 +    fprintf(stdout, "  -o  --outfile     specifies the name of the output file (*.fnt)\n");
   1.306 +    fprintf(stdout, "\n" );
   1.307 +    fprintf(stdout, "  example: %s -f PBM -b f12.pbm -d f12.desc -o f12.fnt\n", prgname);
   1.308 +}