1 /* parse_ofm.h: Checking an existent OFM file
2
3 This file is part of Omega,
4 which is based on the web2c distribution of TeX,
5
6 Copyright (c) 1994--2001 John Plaice and Yannis Haralambous
7 Copyright (C) 2005, 2006 Roozbeh Pournader
8
9 Omega is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 Omega is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with Omega; if not, write to the Free Software Foundation, Inc.,
21 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22
23 */
24
25 #include "cpascal.h"
26 #include "list_routines.h"
27 #include "header_routines.h"
28 #include "manifests.h"
29 #include "char_routines.h"
30 #include "ligkern_routines.h"
31 #include "out_ofm.h"
32 #include "extra_routines.h"
33 #include "param_routines.h"
34 #include "dimen_routines.h"
35 #include "error_routines.h"
36 #include "print_routines.h"
37 #include "out_routines.h"
38 #include "font_routines.h"
39 #include "parse_ofm.h"
40 #include "omfonts.h"
41 #include "manifests.h"
42
43 unsigned top_char, top_width, top_height, top_depth, top_italic;
44 unsigned start_ptr, check_sum_pos, design_size_pos, scheme_pos;
45 unsigned seven_bit_flag_pos;
46 unsigned random_word_pos, header_length;
47
48 unsigned ivalues_start,fvalues_start,mvalues_start,
49 rules_start,glues_start,penalties_start;
50 unsigned ivalues_base,fvalues_base,mvalues_base,
51 rules_base,glues_base,penalties_base;
52 unsigned char_base,width_base,height_base,depth_base,italic_base;
53 unsigned lig_kern_base,kern_base,exten_base,param_base;
54 /* base addresses for the subfiles */
55 unsigned char_start;
56 unsigned bytes_per_entry;
57
58 unsigned lf;
59 boolean ofm_on;
60 unsigned start_pos;
61 unsigned family_pos;
62 unsigned ofm_ptr;
63 unsigned ncw;
64 unsigned ncl;
65 unsigned nce;
66 unsigned nco;
67 unsigned npc;
68
69 static void
eval_two_bytes(unsigned * pos)70 eval_two_bytes(unsigned *pos) {
71 if (ofm[ofm_ptr]>127)
72 fatal_error_0("One of the subfile sizes (2) is negative");
73 *pos = ofm[ofm_ptr]*0x100 + ofm[ofm_ptr+1];
74 ofm_ptr += 2;
75 }
76
77 static void
eval_four_bytes(unsigned * pos)78 eval_four_bytes(unsigned *pos) {
79 if (ofm[ofm_ptr]>127)
80 fatal_error_0("One of the subfile sizes (4) is negative");
81 *pos = ofm[ofm_ptr]*0x1000000 + ofm[ofm_ptr+1]*0x10000 +
82 ofm[ofm_ptr+2]*0x100 + ofm[ofm_ptr+3];
83 ofm_ptr += 4;
84 }
85
86 static void ofm_organize(void);
87 static void ofm_read_simple(void);
88 static void ofm_read_rest(void);
89
90 boolean changed = FALSE;
91
92 void
parse_ofm(boolean read_ovf)93 parse_ofm(boolean read_ovf)
94 {
95 ofm_organize();
96 if (read_ovf == TRUE) input_ovf_file();
97 ofm_read_simple();
98 if (read_ovf == TRUE) input_ovf_fonts();
99 ofm_read_rest();
100 if (read_ovf == TRUE) input_ovf_chars();
101 print_characters(read_ovf);
102 if (changed) {
103 left();
104 out("COMMENT THE OFM FILE WAS BAD, SO THE DATA HAS BEEN CHANGED!");
105 right();
106 }
107 }
108
109 /* parse_ofm ensures that all of the header entries are consistent.
110 The file is assumed to have been read in already, with the
111 contents in the ofm array (length_ofm bytes).
112 */
113
114 void
ofm_organize(void)115 ofm_organize(void)
116 {
117 unsigned copies,i;
118
119 ofm_on = false; ofm_level = OFM_NOLEVEL; lf = 0; lh = 0;
120 nco = 0; ncw = 0; npc = 0;
121 bc = 0; ec = 0; nw = 0; nh = 0; nd = 0; ni = 0;
122 nl = 0; nk = 0; ne = 0; np = 0;
123 nki = 0; nwi = 0; nkf = 0; nwf = 0;
124 nkm = 0; nwm = 0;
125 nkr = 0; nwr = 0; nkg = 0; nwg = 0;
126 nkp = 0; nwp = 0; font_dir = 0;
127
128 if (length_ofm < 8)
129 fatal_error_0("File too short");
130 lf = ofm[0]*256 + ofm[1];
131 if (lf==0) { /* This is not a TFM file, it is an OFM-file */
132 ofm_on = TRUE;
133
134 /* next line edited by Thomas Esser, based on a patch sent
135 * by Hossein Movahhedian. The old code had " + 1"
136 * instead of "+ OFM_LEVEL0" and caused lots of segfaults */
137 ofm_level = ofm[2]*0x100 + ofm[3] + OFM_LEVEL0;
138 if (ofm[4]>127)
139 fatal_error_0("File length is negative");
140 lf = ofm[4]*0x1000000 + ofm[5]*0x10000 + ofm[6]*0x100 + ofm[7];
141 } else {
142 ofm_on = FALSE;
143 ofm_level = OFM_TFM;
144 }
145 if ((lf*4)!=length_ofm)
146 fatal_error_2("Stated (%d) and actual (%d) file length do not match",
147 lf*4, length_ofm);
148
149 switch(ofm_level) {
150 case OFM_TFM: { start_pos = 2; check_sum_pos = 24; break; }
151 case OFM_LEVEL0: { start_pos = 8; check_sum_pos = 56; break; }
152 case OFM_LEVEL1: { start_pos = 8; check_sum_pos = 116; break; }
153 default: { fatal_error_1("OFMLEVEL %d not supported", ofm_level-OFM_LEVEL0);
154 break; }
155 }
156 design_size_pos = check_sum_pos+4;
157 scheme_pos = design_size_pos+4;
158 family_pos = scheme_pos+40;
159 random_word_pos = family_pos+20;
160
161 ofm_ptr = start_pos;
162
163 if (ofm_on==FALSE) {
164 eval_two_bytes(&lh);
165 eval_two_bytes(&bc);
166 eval_two_bytes(&ec);
167 eval_two_bytes(&nw);
168 eval_two_bytes(&nh);
169 eval_two_bytes(&nd);
170 eval_two_bytes(&ni);
171 eval_two_bytes(&nl);
172 eval_two_bytes(&nk);
173 eval_two_bytes(&ne);
174 eval_two_bytes(&np);
175 ncw = (ec-bc+1);
176 ncl = nl;
177 nce = ne;
178 header_length = 6;
179 top_char = 255;
180 top_width = 255;
181 top_height = 15;
182 top_depth = 15;
183 top_italic = 63;
184 } else {
185 eval_four_bytes(&lh);
186 eval_four_bytes(&bc);
187 eval_four_bytes(&ec);
188 eval_four_bytes(&nw);
189 eval_four_bytes(&nh);
190 eval_four_bytes(&nd);
191 eval_four_bytes(&ni);
192 eval_four_bytes(&nl);
193 eval_four_bytes(&nk);
194 eval_four_bytes(&ne);
195 eval_four_bytes(&np);
196 eval_four_bytes(&font_dir);
197 top_char = 0x10ffff;
198 top_width = 65535;
199 top_height = 255;
200 top_depth = 255;
201 top_italic = 255;
202 ncl = nl*2;
203 nce = ne*2;
204 if (ofm_level==OFM_LEVEL0) {
205 header_length = 14;
206 ncw = 2*(ec-bc+1);
207 } else {
208 header_length = 29;
209 eval_four_bytes(&nco);
210 eval_four_bytes(&ncw);
211 eval_four_bytes(&npc);
212 eval_four_bytes(&nki); /* Kinds of font ivalues */
213 eval_four_bytes(&nwi); /* Words of font ivalues */
214 eval_four_bytes(&nkf); /* Kinds of font fvalues */
215 eval_four_bytes(&nwf); /* Words of font fvalues */
216 eval_four_bytes(&nkm); /* Kinds of font mvalues */
217 eval_four_bytes(&nwm); /* Words of font mvalues */
218 eval_four_bytes(&nkr); /* Kinds of font rules */
219 eval_four_bytes(&nwr); /* Words of font rules */
220 eval_four_bytes(&nkg); /* Kinds of font glues */
221 eval_four_bytes(&nwg); /* Words of font glues */
222 eval_four_bytes(&nkp); /* Kinds of font penalties */
223 eval_four_bytes(&nwp); /* Words of font penalties */
224 }
225 }
226 if (lf != (header_length+lh+ncw+nw+nh+nd+ni+ncl+nk+nce+np+
227 nki+nwi+nkf+nwf+nkm+nwm+nkr+nwr+nkg+nwg+nkp+nwp))
228 fatal_error_0("Subfile sizes do not add up to the stated total");
229 if (lh < 2)
230 fatal_error_1("The header length is only %d", lh);
231 if ((bc > (ec+1)) || (ec > top_char))
232 fatal_error_2("The character code range %d .. %d is illegal", bc, ec);
233 if ((nw==0) || (nh==0) || (nd==0) || (ni==0))
234 fatal_error_0("Incomplete subfiles for character dimensions");
235 ivalues_start = header_length+lh;
236 fvalues_start = ivalues_start+nki;
237 mvalues_start = fvalues_start+nkf;
238 rules_start = mvalues_start+nkm;
239 glues_start = rules_start+nkr;
240 penalties_start = glues_start+nkg;
241 ivalues_base = penalties_start+nkp;
242 fvalues_base = ivalues_base+nwi;
243 mvalues_base = fvalues_base+nwf;
244 rules_base = mvalues_base+nwm;
245 glues_base = rules_base+nwr;
246 penalties_base = glues_base+nwg;
247 char_base = penalties_base+nwp;
248 bytes_per_entry = (12 + 2*npc) / 4 * 4;
249 init_planes();
250 no_labels = 0;
251 switch (ofm_level) {
252 case OFM_TFM: {
253 for(i=bc; i<=ec; i++) {
254 init_character(i,NULL);
255 char_start = 4*char_base+4*(i-bc);
256 current_character->index_indices[C_WD] =
257 ofm[char_start] & 0xff;
258 current_character->index_indices[C_HT] =
259 (ofm[char_start+1] & 0xf0) >> 4;
260 current_character->index_indices[C_DP] =
261 ofm[char_start+1] & 0xf;
262 current_character->index_indices[C_IC] =
263 (ofm[char_start+2] & 0xfc) >> 2;
264 current_character->tag =
265 ofm[char_start+2] & 0x3;
266 if (current_character->tag == TAG_LIG) no_labels++;
267 current_character->remainder =
268 ofm[char_start+3] & 0xff;
269 }
270 break;
271 }
272 case OFM_LEVEL0: {
273 for(i=bc; i<=ec; i++) {
274 init_character(i,NULL);
275 char_start = 4*char_base+8*(i-bc);
276 current_character->index_indices[C_WD] =
277 ((ofm[char_start] & 0xff) << 8) |
278 (ofm[char_start+1] & 0xff);
279 current_character->index_indices[C_HT] =
280 ofm[char_start+2] & 0xff;
281 current_character->index_indices[C_DP] =
282 ofm[char_start+3] & 0xff;
283 current_character->index_indices[C_IC] =
284 ofm[char_start+4] & 0xff;
285 current_character->tag =
286 ofm[char_start+5] & 0x3;
287 if (current_character->tag == TAG_LIG) no_labels++;
288 current_character->remainder =
289 ((ofm[char_start+6] & 0xff) << 8) |
290 (ofm[char_start+7] & 0xff);
291 }
292 break;
293 }
294 case OFM_LEVEL1: {
295 char_start = 4*char_base;
296 i = bc;
297 while (i<=ec) {
298 init_character(i,NULL);
299 current_character->index_indices[C_WD] =
300 ((ofm[char_start] & 0xff) << 8) |
301 (ofm[char_start+1] & 0xff);
302 current_character->index_indices[C_HT] =
303 ofm[char_start+2] & 0xff;
304 current_character->index_indices[C_DP] =
305 ofm[char_start+3] & 0xff;
306 current_character->index_indices[C_IC] =
307 ofm[char_start+4] & 0xff;
308 current_character->tag =
309 ofm[char_start+5] & 0x3;
310 if (current_character->tag == TAG_LIG) no_labels++;
311 current_character->remainder =
312 ((ofm[char_start+6] & 0xff) << 8) |
313 (ofm[char_start+7] & 0xff);
314 copies = 256*ofm[char_start+8]+ofm[char_start+9];
315 /* Handle character params */
316 copy_characters(i, copies);
317 i += copies + 1;
318 char_start += bytes_per_entry;
319 }
320 if (char_start != (4*(char_base+ncw)))
321 fatal_error_0("Length of char info table does not "
322 "correspond to specification");
323 break;
324 }
325 default: {
326 fatal_error_1("Inappropriate font level (%d)", ofm_level-OFM_LEVEL0);
327 }
328 }
329 width_base = char_base+ncw;
330 height_base = width_base+nw;
331 depth_base = height_base+nh;
332 italic_base = depth_base+nd;
333 lig_kern_base = italic_base+ni;
334 kern_base = lig_kern_base+ncl;
335 exten_base = kern_base+nk;
336 param_base = exten_base+nce-1;
337 }
338
339 void
ofm_read_simple(void)340 ofm_read_simple(void)
341 {
342
343 if (ofm_on==TRUE) {
344 print_ofm_level(ofm_level-OFM_LEVEL0);
345 print_font_dir(font_dir);
346 }
347 header = (char *) ofm+check_sum_pos;
348 retrieve_header();
349 print_family();
350 print_face();
351 print_coding_scheme();
352 print_design_size();
353 out("(COMMENT DESIGNSIZE IS IN POINTS)"); out_ln();
354 out("(COMMENT OTHER SIZES ARE MULTIPLES OF DESIGNSIZE)"); out_ln();
355 print_check_sum();
356 if ((seven_bit == TRUE) || (ofm_level != OFM_TFM))
357 print_seven_bit_safe_flag();
358 retrieve_parameters(ofm+(4*param_base));
359 print_parameters();
360 }
361
362 void
ofm_read_rest(void)363 ofm_read_rest(void)
364 {
365 retrieve_dimen_tables();
366 if (verbose_option==TRUE) print_dimen_tables();
367 retrieve_ligkern_table(ofm+(4*lig_kern_base), ofm+(4*kern_base));
368 adjust_labels(FALSE);
369 if (verbose_option==TRUE) print_labels();
370 print_ligkern_table();
371 retrieve_exten_table(ofm+(4*exten_base));
372 if (verbose_option==TRUE) print_extens();
373 }
374