160
|
1 /*
|
|
2 * fontconv - Convert bitmap fonts
|
|
3 * Programmed and designed by Matti 'ccr' Hamalainen
|
|
4 * (C) Copyright 2012 Tecnic Software productions (TNSP)
|
|
5 *
|
|
6 * Please read file 'COPYING' for information on license and distribution.
|
|
7 */
|
|
8 #include <stdio.h>
|
|
9 #include <errno.h>
|
|
10 #include "dmlib.h"
|
|
11 #include "dmargs.h"
|
|
12 #include "dmfile.h"
|
|
13 #include "dmimage.h"
|
|
14 #include "dmtext.h"
|
|
15
|
|
16 enum
|
|
17 {
|
|
18 OFMT_DMFONT,
|
|
19 };
|
|
20
|
|
21 enum
|
|
22 {
|
|
23 IFMT_IMAGE,
|
|
24 IFMT_FONT,
|
|
25 };
|
|
26
|
|
27 char *optInFilename = NULL, *optOutFilename = NULL;
|
|
28 int optOutFormat = OFMT_DMFONT,
|
|
29 optSplitWidth = 8,
|
|
30 optSplitHeight = 8;
|
|
31
|
|
32
|
|
33 DMOptArg optList[] =
|
|
34 {
|
|
35 { 0, '?', "help", "Show this help", OPT_NONE },
|
|
36 { 1, 'v', "verbose", "Be more verbose", OPT_NONE },
|
|
37 { 2, 'o', "output", "Output file (default stdout)", OPT_ARGREQ },
|
|
38 { 3, 's', "size", "Set glyph dimensions (-s WxH) for image->font conversion", OPT_ARGREQ },
|
|
39 };
|
|
40
|
|
41 const int optListN = sizeof(optList) / sizeof(optList[0]);
|
|
42
|
|
43
|
|
44 BOOL argHandleOpt(const int optN, char *optArg, char *currArg)
|
|
45 {
|
|
46 switch (optN)
|
|
47 {
|
|
48 case 0:
|
|
49 dmPrintBanner(stdout, dmProgName,
|
|
50 "[options] [sourcefile]");
|
|
51
|
|
52 dmArgsPrintHelp(stdout, optList, optListN);
|
|
53 exit(0);
|
|
54 break;
|
|
55
|
|
56 case 1:
|
|
57 dmVerbosity++;
|
|
58 break;
|
|
59
|
|
60 case 2:
|
|
61 optOutFilename = optArg;
|
|
62 break;
|
|
63
|
|
64 case 3:
|
|
65 {
|
|
66 int w, h;
|
|
67 if (sscanf(optArg, "%dx%d", &w, &h) != 2)
|
|
68 {
|
|
69 dmError("Invalid argument for -s option, '%s'.\n",
|
|
70 optArg);
|
|
71 return FALSE;
|
|
72 }
|
|
73 if (w < DMFONT_MIN_WIDTH || w > DMFONT_MAX_WIDTH ||
|
|
74 h < DMFONT_MIN_HEIGHT || h > DMFONT_MAX_HEIGHT)
|
|
75 {
|
|
76 dmError("Invalid dimensions, must be %d < W %d, %d < H < %d.\n",
|
|
77 DMFONT_MIN_WIDTH , DMFONT_MAX_WIDTH,
|
|
78 DMFONT_MIN_HEIGHT , DMFONT_MAX_HEIGHT);
|
|
79 return FALSE;
|
|
80 }
|
|
81 optSplitWidth = w;
|
|
82 optSplitHeight = h;
|
|
83 }
|
|
84 break;
|
|
85
|
|
86 default:
|
|
87 dmError("Unknown argument '%s'.\n", currArg);
|
|
88 return FALSE;
|
|
89 }
|
|
90
|
|
91 return TRUE;
|
|
92 }
|
|
93
|
|
94
|
|
95 BOOL argHandleFile(char *currArg)
|
|
96 {
|
|
97 if (!optInFilename)
|
|
98 optInFilename = currArg;
|
|
99 else
|
|
100 {
|
|
101 dmError("Too many filename arguments, '%s'\n", currArg);
|
|
102 return FALSE;
|
|
103 }
|
|
104
|
|
105 return TRUE;
|
|
106 }
|
|
107
|
|
108
|
|
109 int dmCreateBitmapFontFromImage(SDL_Surface *image, int width, int height, DMBitmapFont **pfont)
|
|
110 {
|
|
111 int nglyph, xc, yc, xglyphs, yglyphs;
|
|
112 DMBitmapFont *font;
|
|
113
|
|
114 if (image->w < width || width < 4 || image->h < height || height < 4)
|
|
115 return DMERR_INVALID_ARGS;
|
|
116
|
|
117 xglyphs = image->w / width;
|
|
118 yglyphs = image->h / height;
|
|
119
|
|
120 if ((font = dmNewBitmapFont(xglyphs * yglyphs, width, height)) == NULL)
|
|
121 return DMERR_MALLOC;
|
|
122
|
|
123 /*
|
|
124 fprintf(stderr, "%d x %d split as %d x %d blocks => %d x %d = %d glyphs\n",
|
|
125 image->w, image->h,
|
|
126 width, height,
|
|
127 xglyphs, yglyphs, xglyphs * yglyphs);
|
|
128 */
|
|
129
|
|
130 nglyph = 0;
|
|
131 for (yc = 0; yc < yglyphs; yc++)
|
|
132 for (xc = 0; xc < xglyphs; xc++)
|
|
133 {
|
|
134 SDL_Surface *glyph = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height,
|
|
135 image->format->BitsPerPixel,
|
|
136 image->format->Rmask,
|
|
137 image->format->Gmask,
|
|
138 image->format->Bmask,
|
|
139 image->format->Amask);
|
|
140
|
|
141 if (glyph == NULL)
|
|
142 {
|
|
143 dmFreeBitmapFont(font);
|
|
144 return DMERR_MALLOC;
|
|
145 }
|
|
146
|
|
147 SDL_Rect r;
|
|
148 r.x = xc * width;
|
|
149 r.y = yc * height;
|
|
150 r.w = width;
|
|
151 r.h = height;
|
|
152
|
|
153 SDL_BlitSurface(image, &r, glyph, NULL);
|
|
154
|
|
155 font->glyphs[nglyph++] = glyph;
|
|
156 }
|
|
157
|
|
158 *pfont = font;
|
|
159 return DMERR_OK;
|
|
160 }
|
|
161
|
|
162
|
|
163 int main(int argc, char *argv[])
|
|
164 {
|
|
165 DMResource *inFile = NULL;
|
|
166 DMBitmapFont *font = NULL;
|
|
167 int res;
|
|
168
|
|
169 dmInitProg("fontconv", "Bitmap font converter", "0.2", NULL, NULL);
|
|
170 dmVerbosity = 1;
|
|
171
|
|
172 // Parse arguments
|
|
173 if (!dmArgsProcess(argc, argv, optList, optListN,
|
|
174 argHandleOpt, argHandleFile, TRUE))
|
|
175 exit(1);
|
|
176
|
|
177 // Check arguments
|
|
178 if (!optInFilename)
|
|
179 {
|
|
180 dmError("Input or output file not specified!\n");
|
|
181 return 1;
|
|
182 }
|
|
183
|
|
184 // Open the source file
|
|
185 if ((inFile = dmf_create_stdio(optInFilename, "rb")) == NULL)
|
|
186 {
|
|
187 dmError("Error opening input file '%s', %d: %s\n",
|
|
188 optInFilename, errno, strerror(errno));
|
|
189 return 1;
|
|
190 }
|
|
191
|
|
192 if ((res = dmLoadBitmapFont(inFile, &font)) != DMERR_OK)
|
|
193 {
|
|
194 SDL_Surface *fontbmap;
|
|
195
|
|
196 dmfseek(inFile, 0L, SEEK_SET);
|
|
197
|
|
198 if ((fontbmap = dmLoadImage(inFile)) == NULL)
|
|
199 {
|
|
200 dmError("Could not load image file '%s'.\n", optInFilename);
|
|
201 goto error_exit;
|
|
202 }
|
|
203
|
|
204 if ((res = dmCreateBitmapFontFromImage(fontbmap, optSplitWidth, optSplitHeight, &font)) != DMERR_OK)
|
|
205 {
|
|
206 dmError("Could not create a font from image, %d: %s\n",
|
|
207 res, dmErrorStr(res));
|
|
208 goto error_exit;
|
|
209 }
|
|
210 SDL_FreeSurface(fontbmap);
|
|
211 }
|
|
212
|
|
213 if (font == NULL)
|
|
214 {
|
|
215 dmError("No font loaded.\n");
|
|
216 goto error_exit;
|
|
217 }
|
|
218
|
|
219 if (optOutFormat == OFMT_DMFONT)
|
|
220 {
|
|
221 DMResource *file;
|
|
222
|
|
223 if (optOutFilename == NULL)
|
|
224 file = dmf_create_stdio_stream(stdout);
|
|
225 else
|
|
226 file = dmf_create_stdio(optOutFilename, "wb");
|
|
227
|
|
228 if (file == NULL)
|
|
229 {
|
|
230 dmError("Error creating file '%s', %d: %s\n",
|
|
231 optInFilename, errno, strerror(errno));
|
|
232 goto error_exit;
|
|
233 }
|
|
234
|
|
235 res = dmSaveBitmapFont(file, font);
|
|
236 dmf_close(file);
|
|
237 }
|
|
238
|
|
239 if (res != DMERR_OK)
|
|
240 {
|
|
241 dmError("Error saving font, %d: %s\n",
|
|
242 res, dmErrorStr(res));
|
|
243 }
|
|
244
|
|
245 error_exit:
|
|
246
|
|
247 dmf_close(inFile);
|
|
248 dmFreeBitmapFont(font);
|
|
249
|
|
250 return 0;
|
|
251 }
|