comparison TOOLS/subfont-c/subfont.c @ 1471:00a1f4b77803

dirty fix to get it work with glibc 2.1.x, and changed blur algorithm
author arpi
date Thu, 09 Aug 2001 17:29:25 +0000
parents 2c7b0478db0c
children 3182755fdee8
comparison
equal deleted inserted replaced
1470:2c7b0478db0c 1471:00a1f4b77803
15 #include <stdlib.h> 15 #include <stdlib.h>
16 #include <iconv.h> 16 #include <iconv.h>
17 #include <math.h> 17 #include <math.h>
18 #include <string.h> 18 #include <string.h>
19 19
20 #if 1 /* freetype 2.0.1 */ 20 #if 0 /* freetype 2.0.1 */
21 #include <freetype/freetype.h> 21 #include <freetype/freetype.h>
22 #else /* freetype 2.0.3 */ 22 #else /* freetype 2.0.3 */
23 #include <ft2build.h> 23 #include <ft2build.h>
24 #include FT_FREETYPE_H 24 #include FT_FREETYPE_H
25 #endif 25 #endif
30 30
31 #define f266toInt(x) (((x)+32)>>6) /* round fractional fixed point number to integer */ 31 #define f266toInt(x) (((x)+32)>>6) /* round fractional fixed point number to integer */
32 /* coordinates are in 26.6 pixels (i.e. 1/64th of pixels) */ 32 /* coordinates are in 26.6 pixels (i.e. 1/64th of pixels) */
33 33
34 34
35 int const test = 0; 35 int const test = 1;
36 36
37 /* default values */ 37 /* default values */
38 char *encoding = "iso-8859-1"; /* target encoding */ 38 char *encoding = "iso-8859-1"; /* target encoding */
39 char *charmap = "ucs-4le"; /* font charmap encoding */ 39 /* gcc 2.1.3 doesn't support ucs-4le, but supports ucs-4 (==ucs-4be) */
40 char *charmap = "ucs-4"; /* ucs-4le font charmap encoding */
40 int ppem = 20; /* font size in pixels */ 41 int ppem = 20; /* font size in pixels */
41 42
42 int const colors = 256; 43 int const colors = 256;
43 int const maxcolor = 255; 44 int const maxcolor = 255;
44 int radius = 6; /* blur radius */ 45 int radius = 2; /* blur radius */
45 double minalpha = 1.0; /* good value for minalpha is 0.5 */ 46 double minalpha = 1.0; /* good value for minalpha is 0.5 */
46 double alpha_factor = 1.0; 47 double alpha_factor = 1.0;
47 48
48 int const first_char = 33; 49 int const first_char = 33;
49 int const charset_size = 256; 50 int const charset_size = 256;
54 55
55 56
56 unsigned char *buffer; 57 unsigned char *buffer;
57 unsigned char *abuffer; 58 unsigned char *abuffer;
58 int width, height; 59 int width, height;
59 FT_ULong ustring[256]; 60 static FT_ULong ustring[256];
60 61
61 #define eprintf(...) fprintf(stderr, __VA_ARGS__) 62 #define eprintf(...) fprintf(stderr, __VA_ARGS__)
62 #define ERROR(msg, ...) (eprintf("%s: error: " msg "\n", command, ##__VA_ARGS__), exit(1)) 63 #define ERROR(msg, ...) (eprintf("%s: error: " msg "\n", command, ##__VA_ARGS__), exit(1))
63 #define WARNING(msg, ...) eprintf("%s: warning: " msg "\n", command, ##__VA_ARGS__) 64 #define WARNING(msg, ...) eprintf("%s: warning: " msg "\n", command, ##__VA_ARGS__)
64 65
94 int const max_name = 128; 95 int const max_name = 128;
95 char name[max_name]; 96 char name[max_name];
96 97
97 snprintf(name, max_name, "%s-b.raw", encoding); 98 snprintf(name, max_name, "%s-b.raw", encoding);
98 f = fopen(name, "wb"); 99 f = fopen(name, "wb");
99 if (f==NULL) ERROR("fopen failed."); 100 if (f==NULL) ERROR("fopen failed.",NULL);
100 write_header(f); 101 write_header(f);
101 fwrite(buffer, 1, width*height, f); 102 fwrite(buffer, 1, width*height, f);
102 fclose(f); 103 fclose(f);
103 104
104 snprintf(name, max_name, "%s-a.raw", encoding); 105 snprintf(name, max_name, "%s-a.raw", encoding);
105 f = fopen(name, "wb"); 106 f = fopen(name, "wb");
106 if (f==NULL) ERROR("fopen failed."); 107 if (f==NULL) ERROR("fopen failed.",NULL);
107 write_header(f); 108 write_header(f);
108 fwrite(abuffer, 1, width*height, f); 109 fwrite(abuffer, 1, width*height, f);
109 fclose(f); 110 fclose(f);
110 } 111 }
111 112
123 int baseline, space_advance = 20; 124 int baseline, space_advance = 20;
124 125
125 126
126 /* initialize freetype */ 127 /* initialize freetype */
127 error = FT_Init_FreeType(&library); 128 error = FT_Init_FreeType(&library);
128 if (error) ERROR("Init_FreeType failed."); 129 if (error) ERROR("Init_FreeType failed.",NULL);
129 error = FT_New_Face(library, font_path, 0, &face); 130 error = FT_New_Face(library, font_path, 0, &face);
130 if (error) ERROR("New_Face failed."); 131 if (error) ERROR("New_Face failed.",NULL);
131 132
132 /* 133 /*
133 if (font_metrics) { 134 if (font_metrics) {
134 error = FT_Attach_File(face, font_metrics); 135 error = FT_Attach_File(face, font_metrics);
135 if (error) WARNING("Attach_File failed."); 136 if (error) WARNING("Attach_File failed.");
136 } 137 }
137 */ 138 */
138 139
139 140
140 if (face->charmap->encoding!=ft_encoding_unicode) 141 if (face->charmap->encoding!=ft_encoding_unicode)
141 WARNING("Selected font has no unicode charmap. Very bad!"); 142 WARNING("Selected font has no unicode charmap. Very bad!",NULL);
142 143
143 144
144 /* set size */ 145 /* set size */
145 if (FT_IS_SCALABLE(face)) { 146 if (FT_IS_SCALABLE(face)) {
146 error = FT_Set_Pixel_Sizes(face, ppem, ppem); 147 error = FT_Set_Pixel_Sizes(face, ppem, ppem);
155 } 156 }
156 } 157 }
157 WARNING("Selected font is not scalable. Using ppem=%i", face->available_sizes[j].height); 158 WARNING("Selected font is not scalable. Using ppem=%i", face->available_sizes[j].height);
158 error = FT_Set_Pixel_Sizes(face, face->available_sizes[j].width, face->available_sizes[j].height); 159 error = FT_Set_Pixel_Sizes(face, face->available_sizes[j].width, face->available_sizes[j].height);
159 } 160 }
160 if (error) WARNING("Set_Pixel_Sizes failed."); 161 if (error) WARNING("Set_Pixel_Sizes failed.",NULL);
161 162
162 163
163 if (FT_IS_FIXED_WIDTH(face)) 164 if (FT_IS_FIXED_WIDTH(face))
164 WARNING("Selected font is fixed-width."); 165 WARNING("Selected font is fixed-width.",NULL);
165 166
166 167
167 /* compute space advance */ 168 /* compute space advance */
168 error = FT_Load_Char(face, ' ', load_flags); 169 error = FT_Load_Char(face, ' ', load_flags);
169 if (error) WARNING("spacewidth set to default."); 170 if (error) WARNING("spacewidth set to default.",NULL);
170 else space_advance = f266toInt(face->glyph->advance.x); /* +32 is for rounding */ 171 else space_advance = f266toInt(face->glyph->advance.x); /* +32 is for rounding */
171 172
172 173
173 /* create font.desc */ 174 /* create font.desc */
174 f = fopen("font.desc", "w"); 175 f = fopen("font.desc", "w");
175 if (f==NULL) ERROR("fopen failed."); 176 if (f==NULL) ERROR("fopen failed.",NULL);
176 177
177 /* print font.desc header */ 178 /* print font.desc header */
178 fprintf(f, "[info]\n"); 179 fprintf(f, "[info]\n");
179 fprintf(f, "name 'File generated for %s encoding using `%s%s%s' face (%s), ppem=%i'\n", 180 fprintf(f, "name 'File generated for %s encoding using `%s%s%s' face (%s), ppem=%i'\n",
180 encoding, 181 encoding,
240 241
241 } 242 }
242 243
243 fclose(f); 244 fclose(f);
244 245
245 if (ymax<=ymin) ERROR("Something went wrong."); 246 if (ymax<=ymin) ERROR("Something went wrong.",NULL);
246 247
247 248
248 width = pen_x; 249 width = pen_x;
249 height = ymax - ymin + 2*radius; 250 height = ymax - ymin + 2*radius;
250 baseline = ymax + radius; 251 baseline = ymax + radius;
251 eprintf("bitmap size: %ix%i\n", width, height); 252 eprintf("bitmap size: %ix%i\n", width, height);
252 253
253 buffer = (unsigned char*)malloc(width*height); 254 buffer = (unsigned char*)malloc(width*height);
254 abuffer = (unsigned char*)malloc(width*height); 255 abuffer = (unsigned char*)malloc(width*height);
255 if (buffer==NULL || abuffer==NULL) ERROR("malloc failed."); 256 if (buffer==NULL || abuffer==NULL) ERROR("malloc failed.",NULL);
256 257
257 258
258 /* render glyphs */ 259 /* render glyphs */
259 pen_x = 0; 260 pen_x = 0;
260 pen_y = baseline; 261 pen_y = baseline;
284 pen_x = (pen_x+7)&~7; /* 8 byte align */ 285 pen_x = (pen_x+7)&~7; /* 8 byte align */
285 } 286 }
286 287
287 288
288 error = FT_Done_FreeType(library); 289 error = FT_Done_FreeType(library);
289 if (error) ERROR("Done_FreeType failed."); 290 if (error) ERROR("Done_FreeType failed.",NULL);
290 } 291 }
291 292
292 void prepare_charset() { 293 void prepare_charset() {
293 iconv_t cd; 294 iconv_t cd;
294 unsigned char text[charset_size]; 295 unsigned char text[charset_size];
305 cd = iconv_open(charmap, charmap); 306 cd = iconv_open(charmap, charmap);
306 if (cd==(iconv_t)-1) ERROR("iconv doesn't know %s encoding. Use the source!", charmap); 307 if (cd==(iconv_t)-1) ERROR("iconv doesn't know %s encoding. Use the source!", charmap);
307 iconv_close(cd); 308 iconv_close(cd);
308 309
309 cd = iconv_open(charmap, encoding); 310 cd = iconv_open(charmap, encoding);
310 if (cd==(iconv_t)-1) ERROR("Unsupported encoding, use iconv -l to list character sets known on your system."); 311 if (cd==(iconv_t)-1) ERROR("Unsupported encoding, use iconv -l to list character sets known on your system.",NULL);
311 while (1) { 312 while (1) {
312 count = iconv(cd, &inbuf, &inbuf_left, &outbuf, &outbuf_left); 313 count = iconv(cd, &inbuf, &inbuf_left, &outbuf, &outbuf_left);
313 if (inbuf_left==0) break; 314 if (inbuf_left==0) break;
314 /* skip undefined characters */ 315 /* skip undefined characters */
315 inbuf+= 1; 316 inbuf+= 1;
316 inbuf_left-= 1; 317 inbuf_left-= 1;
317 *(FT_ULong*)outbuf = 0; 318 *(FT_ULong*)outbuf = 0;
318 outbuf+= 4; 319 outbuf+=sizeof(FT_ULong);
319 } 320 }
320 iconv_close(cd); 321 iconv_close(cd);
322
323 /* converting unicodes BE -> LE */
324 for (i = 0; i<256; ++i){
325 FT_ULong x=ustring[i];
326 x= ((x>>24)&255)
327 | (((x>>16)&255)<<8)
328 | (((x>> 8)&255)<<16)
329 | ((x&255)<<24);
330 ustring[i]=x;
331 }
332
321 } 333 }
322 334
323 void blur() { 335 void blur() {
324 int const r = radius; 336 int const r = radius;
325 int const w = 2*r+1; /* matrix size */ 337 int const w = 2*r+1; /* matrix size */
326 double const A = log(minalpha/maxcolor)/((r+1)*(r+1)); 338 double const A = log(1.0/maxcolor)/((r+1)*(r+1));
327 double const B = alpha_factor * maxcolor; 339 double const B = maxcolor;
340 int sum=0;
328 341
329 int i, x, y, mx, my; 342 int i, x, y, mx, my;
330 unsigned char *m = (unsigned char*)malloc(w*w); 343 unsigned char *m = (unsigned char*)malloc(w*w);
331 344
332 if (m==NULL) ERROR("malloc failed"); 345 if (m==NULL) ERROR("malloc failed",NULL);
333 346
334 347
335 /* Gaussian matrix */ 348 /* Gaussian matrix */
336 for (my = 0; my<w; ++my) { 349 for (my = 0; my<w; ++my) {
337 for (mx = 0; mx<w; ++mx) { 350 for (mx = 0; mx<w; ++mx) {
338 m[mx+my*w] = (int)(exp(A * ((mx-r)*(mx-r)+(my-r)*(my-r))) * B + .5); 351 m[mx+my*w] = (int)(exp(A * ((mx-r)*(mx-r)+(my-r)*(my-r))) * B + .5);
352 sum+=m[mx+my*w];
339 if (test) eprintf("%3i ", m[mx+my*w]); 353 if (test) eprintf("%3i ", m[mx+my*w]);
340 } 354 }
341 if (test) eprintf("\n"); 355 if (test) eprintf("\n");
342 } 356 }
357 printf("gauss sum = %d\n",sum);
343 358
344 /* This is not a gaussian blur! */ 359 /* This is not a gaussian blur! */
345 /* And is very slow */ 360 /* And is very slow */
346 for (y = 0; y<height; ++y) 361 for (y = 0; y<height; ++y){
347 for (x = 0; x<width; ++x) { 362 for (x = 0; x<width; ++x) {
348 int max = -1; 363 float max = 0;
349 for (my = -r; my<=r; ++my) 364 for (my = -r; my<=r; ++my)
350 if (y+my>=0 && y+my<height) 365 if (y+my>0 && y+my<height-1)
351 for (mx = -r; mx<=r; ++mx) { 366 for (mx = -r; mx<=r; ++mx) {
352 if (x+mx>=0 && x+mx<width) { 367 if (x+mx>0 && x+mx<width-1) {
353 int p = buffer[x+mx+(y+my)*width] * m[mx+r+(my+r)*w]; 368 // int p = buffer[x+mx+(y+my)*width] * m[mx+r+(my+r)*w];
354 if (p>max) { 369 int p = 0;
355 max = p; 370
356 abuffer[x+y*width] = (p + maxcolor/2) / maxcolor; 371 p = ( (buffer[x+mx-1+(y+my-1)*width]) +
357 } 372 (buffer[x+mx-1+(y+my+1)*width]) +
373 (buffer[x+mx+1+(y+my-1)*width]) +
374 (buffer[x+mx+1+(y+my+1)*width]) )/2 +
375
376 ( (buffer[x+mx-1+(y+my)*width]) +
377 (buffer[x+mx+1+(y+my)*width]) +
378 (buffer[x+mx+(y+my-1)*width]) +
379 (buffer[x+mx+(y+my+1)*width]) +
380
381 (buffer[x+mx+(y+my)*width]) ) ;
382
383 if(p>255) p=255;
384
385 // p*=m[mx+r+(my+r)*w];
386 // if (p>max) {
387 // max = p;
388 // abuffer[x+y*width] = (p + maxcolor/2) / maxcolor;
389 // }
390 //max+=(p + maxcolor/2) / maxcolor;
391 max+=p*m[mx+r+(my+r)*w]/(float)sum;
358 } 392 }
359 393
360 } 394 }
361 } 395 max=max*alpha_factor;
396 // printf("%5.3f ",max);
397 if(max>255) max=255;
398 abuffer[x+y*width] = max;
399 }
400 // printf("\n");
401 }
362 free(m); 402 free(m);
363 } 403 }
364 404
365 void usage() { 405 void usage() {
366 printf("Usage: %s encoding ppem font [alphaFactor [minAlpha [radius]]]\n", command); 406 printf("Usage: %s encoding ppem font [alphaFactor [minAlpha [radius]]]\n", command);
398 font_path = argv[3]; 438 font_path = argv[3];
399 439
400 if (argc>4) { 440 if (argc>4) {
401 d = atof(argv[4]); 441 d = atof(argv[4]);
402 if (d>0.001 && d<1000.) alpha_factor = d; 442 if (d>0.001 && d<1000.) alpha_factor = d;
403 else WARNING("alphaFactor set to default."); 443 else WARNING("alphaFactor set to default.",NULL);
404 } 444 }
405 if (argc>5) { 445 if (argc>5) {
406 d = atof(argv[5]); 446 d = atof(argv[5]);
407 if (d>0.1 && d<=maxcolor) minalpha = d; 447 if (d>0.1 && d<=maxcolor) minalpha = d;
408 else WARNING("minAlpha set to default."); 448 else WARNING("minAlpha set to default.",NULL);
409 } 449 }
410 if (argc>6) { 450 if (argc>6) {
411 i = atoi(argv[6]); 451 i = atoi(argv[6]);
412 if (i>=0 && i<20) radius = i; 452 if (i>=0 && i<20) radius = i;
413 else WARNING("radius set to default."); 453 else WARNING("radius set to default.",NULL);
414 } 454 }
415 } 455 }
416 456
417 int main(int argc, char **argv) { 457 int main(int argc, char **argv) {
418 parse_args(argc, argv); 458 parse_args(argc, argv);