1 /* $Id$ */
2 /*
3  * makes X11 BDF font italic.
4  * by Daisuke NISHIKAWA
5  *
6  * perl code by SHINYAMA Yusuke <euske@cl.cs.titech.ac.jp>, public domain.
7  * awk code by Yasuyuki Furukawa <furukawa@vinelinux.org>, public domain.
8  */
9 #include <ctype.h>
10 #include "common.h"
11 #include "italic.h"
12 #include "utils.h"
13 
14 #define BUFLEN 256
15 
16 static void mkitalic(int correct, int dy, Property *prop, int verbose, char *filename);
17 static void get_option(int *correct, int *dy, Property *prop, int *verbose, char **filename, int argc, char *argv[]);
18 static void usage(FILE *fp, int status);
19 
20 
main(int argc,char * argv[])21 int main(int argc, char *argv[])
22 {
23   Property prop;
24   int correct = PIXEL_CORRECTION;
25   int dy = SLANT_DEEP;
26   int verbose = FALSE;
27   char *filename = NULL;
28 
29   prop.weight[0] = prop.weight[1] = NULL;
30   prop.slant[0] = "R";
31   prop.slant[1] = "I";
32   get_option(&correct, &dy, &prop, &verbose, &filename, argc, argv);
33   mkitalic(correct, dy, &prop, verbose, filename);
34   return EXIT_SUCCESS;
35 }
36 
mkitalic(int correct,int dy,Property * prop,int verbose,char * filename)37 static void mkitalic(int correct, int dy, Property *prop, int verbose, char *filename)
38 {
39   FILE *fp;
40   char buf[BUFLEN], outbuf[BUFLEN], keyword[BUFLEN];
41   Pattern *ptable;
42   Bitmap *bmap;
43   size_t count;
44   int width, height, dw, width_max, height_max;
45   int bitmap, rc;
46   ProgressMeter *meter;
47   int max_chars;
48 
49   width = height = dw = 0;
50   prop->width = &width;
51   prop->height = &height;
52   prop->dw = &dw;
53   prop->dy = dy;
54   prop->recast = recast_bbx;
55   fp = file_open(filename);
56   max_chars = replace_property(fp, BUFLEN, prop);
57   if (max_chars < 0) {
58     fclose(fp);
59     return;
60   }
61   meter = NULL;
62   if (verbose) {
63     meter = progress_meter_new(max_chars);
64   }
65   width_max = width+dw;
66   height_max = height;
67   ptable = pattern_new(correct);
68   bmap = bitmap_new(((width-1)/8+1)*8+dw, height_max);
69   count = 0;
70   bitmap = FALSE;
71   while (fgets(buf, BUFLEN, fp) != NULL) {
72     if (isalpha(buf[0])) {
73       sscanf(buf, "%s", keyword);
74       if (strcmp(keyword, "BBX") == 0) {
75         /* recast the metric information from the bounding box */
76         rc = recast_bbx(outbuf, &width, &height, &dw, dy, buf);
77         if (!rc || (width+dw > width_max) || (height > height_max)) {
78           fclose(fp);
79           fprintf(stderr, "Incorrect bounding box data: %s\n", buf);
80           exit(EXIT_FAILURE);
81         }
82         fputs(outbuf, stdout);
83         continue;
84       }
85       if (strcmp(keyword, "BITMAP") == 0) {
86         bitmap = TRUE;
87         count = 0;
88         fputs(buf, stdout);
89         continue;
90       }
91       if (strcmp(keyword, "ENDCHAR") == 0) {
92         bitmap = FALSE;
93         if (correct > 0) {
94           bitmap_correct_pixel(bmap, ptable, width, height, dy);
95         }
96         bitmap_make_slant(bmap, width, height, dy);
97         bitmap_output(stdout, bmap, width+dw, height);
98         fputs(buf, stdout);
99         if (verbose) {
100           progress_meter_print(meter);
101         }
102         continue;
103       }
104     }
105 
106     if (bitmap) {
107       bitmap_get_line(bmap, width, count, buf);
108       if (count < height) {
109         count++;
110       }
111       continue;
112     }
113     fputs(buf, stdout);
114   }
115   fclose(fp);
116   pattern_delete(ptable);
117   bitmap_delete(bmap);
118 
119   if (verbose) {
120     progress_meter_clear(meter);
121     progress_meter_delete(meter);
122   }
123 }
124 
get_option(int * correct,int * dy,Property * prop,int * verbose,char ** filename,int argc,char * argv[])125 static void get_option(int *correct, int *dy, Property *prop, int *verbose, char **filename, int argc, char *argv[])
126 {
127   int i;
128 
129   i = 1;
130   while (i < argc) {
131     if (*argv[i] == '-') {
132       switch (*(argv[i]+1)) {
133       case 'p':
134         print_ptable(stdout, *correct);
135         exit(EXIT_SUCCESS);
136         break;
137 #if defined DEBUG
138       case 'S':
139         if (++i < argc) {
140           prop->slant[0] = argv[i];
141         }
142         break;
143       case 's':
144         if (++i < argc) {
145           prop->slant[1] = argv[i];
146         }
147         break;
148       case 'c':
149         if (++i < argc) {
150           *correct = atoi(argv[i]);
151         }
152         break;
153       case 'd':
154         if (++i < argc) {
155           *dy = atoi(argv[i]);
156         }
157         break;
158 #endif /* DEBUG */
159       case 'V':
160         *verbose = TRUE;
161         break;
162       case 'h':
163         usage(stdout, EXIT_SUCCESS);
164         break;
165       }
166     } else {
167       *filename = argv[i];
168       break;
169     }
170     i++;
171   }
172 }
173 
usage(FILE * fp,int status)174 static void usage(FILE *fp, int status)
175 {
176   fprintf(fp,
177           "Usage: mkitalic [OPTION] [FILE]\n\n"
178           "Write processed X11 BDF file to standard output.\n"
179           "With no FILE, read standard input.\n"
180           "\nOptions:\n"
181           "  -p print a pattern table for pixel correction used by slanting\n"
182           "  -V verbose output\n"
183           "  -h display this help and exit\n"
184           );
185   exit(status);
186 }
187