Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4722 | ashmew2 | 1 | /* |
2 | convert.c: converts text bitmaps into binary bitmaps. |
||
3 | This has been written with an aim to detect any errors that |
||
4 | might have crept in while generating a text bitmap for a font. |
||
5 | |||
6 | Copyright 2011 dunkaist |
||
7 | Copyright 2014 ashmew2 |
||
8 | Distributed under the terms of the GNU General Public License v3. |
||
9 | See http://www.gnu.org/licenses/gpl.txt for the full license text. |
||
10 | */ |
||
11 | |||
12 | /* |
||
13 | For TRANSLATION, only the hard coded strings such as in usage[] need to |
||
14 | rewritten in the desired language. The translation selection should be |
||
15 | inside an #if LANG == RUS {} #else {} block. All messsages are printed |
||
16 | using msg_printx() and the translations need to be done for all such |
||
17 | calls. |
||
18 | */ |
||
19 | |||
20 | #include |
||
21 | #include |
||
22 | #include |
||
23 | #include |
||
24 | #include |
||
25 | #include |
||
26 | |||
27 | #define FONT_HEIGHT 9 /* The height of each symbol in input file */ |
||
28 | #define FONT_WIDTH_MONO 5 /* Fixed width for mono fonts */ |
||
29 | #define FONT_WIDTH_VAR 7 /* Max symbol width */ |
||
30 | #define LINE_BUFFER_SIZE 12 /* For FONT_WIDTH_VAR and delimiters */ |
||
31 | #define NUM_SYMBOLS 256 /* Number of symbols in input file */ |
||
32 | |||
33 | enum error_code { |
||
34 | ERROR_PARSING_ARGS = 1, |
||
35 | ERROR_OPENING_FILE, |
||
36 | ERROR_INVALID_INPUT_FILE |
||
37 | }; |
||
38 | |||
39 | void msg_printx(int errnum, char *message, ...) |
||
40 | { |
||
41 | va_list args; |
||
42 | |||
43 | va_start(args, message); |
||
44 | vfprintf(stderr, message, args); |
||
45 | va_end(args); |
||
46 | |||
47 | exit(errnum); |
||
48 | } |
||
49 | |||
50 | void usage_printx(char *prog_name) |
||
51 | { |
||
52 | char usage[] = "Usage: \n" |
||
53 | "\t%s |
||
54 | "Converts font bitmaps from text to binary format.\n\n" |
||
55 | "\tINPUTFILE\t The input file containing text bitmap.\n" |
||
56 | "\tOUTPUTFILE\t The output file for writing binary bitmap.\n" |
||
57 | "\t-m\t Mono flag. -0 for mono. -1 otherwise.\n\n" |
||
58 | "Examples: \n" |
||
59 | "\t%s char.txt CHAR.MT -0\n" |
||
60 | "\t%s char2.txt CHAR2.MT -1\n\n" |
||
61 | "Exit status: \n" |
||
62 | "\t 0: Successful conversion.\n" |
||
63 | "\t 1: Incorrect arguments supplied to the command.\n" |
||
64 | "\t 2: Files could not be opened for read/write.\n" |
||
65 | "\t 3: Error(s) reading data from file.\n\n" |
||
66 | "This is a part of the font_conv program in KolibriOS.\n"; |
||
67 | |||
68 | msg_printx(ERROR_PARSING_ARGS, usage, prog_name, prog_name, prog_name); |
||
69 | } |
||
70 | |||
71 | char* get_row(bool use_mono) |
||
72 | { |
||
73 | static int line_number = 1; /* Initialize to 1 for first line being read */ |
||
74 | static size_t len_line; |
||
75 | static char line[LINE_BUFFER_SIZE]; |
||
76 | |||
77 | size_t len; |
||
78 | char *current_line; |
||
79 | int i; |
||
80 | |||
81 | current_line = fgets(line, LINE_BUFFER_SIZE - 1, stdin); |
||
82 | |||
83 | if(!current_line) |
||
84 | msg_printx(ERROR_INVALID_INPUT_FILE, "Error: could not read line from input file.\n"); |
||
85 | |||
86 | len = strlen(current_line); |
||
87 | |||
88 | if(len > 2) |
||
89 | { |
||
90 | if(line[len - 1] == '\n' && line[len - 2] == '\r') |
||
91 | len -= 2; |
||
92 | else if(line[len - 1] == '\n') |
||
93 | --len; |
||
94 | else if(line_number != ((FONT_HEIGHT + 1) * NUM_SYMBOLS)) /* if last line of input */ |
||
95 | msg_printx(ERROR_INVALID_INPUT_FILE, "Error: line %d: no newline character found in first %d bytes.\n", 12 - 1, line_number); |
||
96 | |||
97 | line[--len] = '\0'; |
||
98 | } |
||
99 | else |
||
100 | msg_printx(ERROR_INVALID_INPUT_FILE, "Error: line %d: line too short.\n", line_number); |
||
101 | |||
102 | if(line_number == 1) /* Processing first line in input */ |
||
103 | { |
||
104 | if(len > FONT_WIDTH_VAR) |
||
105 | msg_printx(ERROR_INVALID_INPUT_FILE, "Error: line %d: length of line is larger than %d (maximum allowed width).\n", line_number, FONT_WIDTH_VAR); |
||
106 | |||
107 | if((use_mono) && (len != FONT_WIDTH_MONO)) |
||
108 | msg_printx(ERROR_INVALID_INPUT_FILE, "Error: line %d: length of line is not equal to %d (mono font width).\n", line_number, FONT_WIDTH_MONO); |
||
109 | |||
110 | len_line = len; |
||
111 | } |
||
112 | else |
||
113 | { |
||
114 | if(len != len_line) |
||
115 | msg_printx(ERROR_INVALID_INPUT_FILE, "Error: line %d: length of line does not match length of first line in file.\n", line_number); |
||
116 | |||
117 | /*validate Row*/ |
||
118 | for(i = 0; line[i]; i++) |
||
119 | if(!isprint(line[i])) |
||
120 | msg_printx(ERROR_INVALID_INPUT_FILE, "Error: line %d: non printable characters found on line.\n", line_number); |
||
121 | } |
||
122 | |||
123 | ++line_number; |
||
124 | |||
125 | return line; |
||
126 | } |
||
127 | |||
128 | int do_symbol(short int font_width) |
||
129 | { |
||
130 | short int row, col; |
||
131 | int data; |
||
132 | |||
133 | for(row = FONT_HEIGHT; row; row--) |
||
134 | { |
||
135 | char *line = get_row(font_width == FONT_WIDTH_MONO); |
||
136 | |||
137 | data = 0; /* Create empty byte for storing line */ |
||
138 | |||
139 | for(col = 0; col < font_width; col++) |
||
140 | { |
||
141 | if(line[col] != ' ') |
||
142 | data |= 1< |
||
143 | } |
||
144 | |||
145 | putchar(data); |
||
146 | } |
||
147 | return 0; |
||
148 | } |
||
149 | |||
150 | int main(int argc, char *argv[]) |
||
151 | { |
||
152 | char *input_file = NULL; |
||
153 | char *output_file = NULL; |
||
154 | short int char_num; |
||
155 | bool use_mono; |
||
156 | |||
157 | if(argc != 4) /* Required argc is 4, for three mandatory arguments. */ |
||
158 | usage_printx(argv[0]); |
||
159 | else |
||
160 | { |
||
161 | if(!strcmp(argv[3],"-0")) |
||
162 | use_mono = true; |
||
163 | else if(!strcmp(argv[3],"-1")) |
||
164 | use_mono = false; |
||
165 | else |
||
166 | usage_printx(argv[0]); |
||
167 | } |
||
168 | |||
169 | input_file = argv[1]; |
||
170 | output_file = argv[2]; |
||
171 | |||
172 | if(!freopen(input_file, "rt", stdin)) |
||
173 | msg_printx(ERROR_OPENING_FILE, "Error: unable to open %s for reading.\n", input_file); |
||
174 | |||
175 | if(!freopen(output_file, "wb", stdout)) |
||
176 | msg_printx(ERROR_OPENING_FILE, "Error: unable to open %s for writing.\n", output_file); |
||
177 | |||
178 | for(char_num = NUM_SYMBOLS; char_num; char_num--) |
||
179 | { |
||
180 | char *line = get_row(use_mono); |
||
181 | |||
182 | if(use_mono) |
||
183 | { |
||
184 | do_symbol(FONT_WIDTH_MONO); |
||
185 | } |
||
186 | else |
||
187 | { |
||
188 | size_t len = strlen(line); |
||
189 | |||
190 | int p = line[len - 1]; |
||
191 | |||
192 | putchar(p == ' '? 0x08 : p-47); /* Put a backspace character or a decimal digit */ |
||
193 | do_symbol(FONT_WIDTH_VAR); |
||
194 | } |
||
195 | } |
||
196 | |||
197 | return 0; |
||
198 | } |