Subversion Repositories Kolibri OS

Rev

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   <-m>\n\n"
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
}