1 /* out_ofm.c: Outputting to an 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 
8 Omega is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12 
13 Omega is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with Omega; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21 
22 */
23 
24 #include "cpascal.h"
25 #include "list_routines.h"
26 #include "header_routines.h"
27 #include "manifests.h"
28 #include "omfonts.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 "parse_ofm.h"
37 
38 static void compute_ofm_subsizes(void);
39 static void output_ofm_subsizes(void);
40 
41 void
output_ofm_file(void)42 output_ofm_file(void)
43 {
44     check_and_correct();
45     compute_ofm_extra_stuff();
46     compute_ofm_character_info();
47     compute_ofm_subsizes();
48     output_ofm_subsizes();
49     output_ofm_header();
50     output_ofm_extra_stuff();
51     output_ofm_character_info();
52     output_ofm_dimension();
53     output_ofm_ligkern();
54     output_ofm_extensible();
55     output_ofm_parameter();
56 }
57 
58 static void
compute_ofm_subsizes(void)59 compute_ofm_subsizes(void)
60 {
61     switch(ofm_level) {
62         case OFM_TFM: {
63             lh = header_max + 1;
64             nw++; nh++; nd++; ni++;
65             compute_ligkern_offset();
66             lf = 6+lh+(ec-bc+1)+nw+nh+nd+ni+nl+lk_offset+nk+ne+np;
67             break;
68         }
69         case OFM_LEVEL0: {
70             lh = header_max + 1;
71             nw++; nh++; nd++; ni++;
72             compute_ligkern_offset();
73             lf = 14+lh+2*(ec-bc+1)+nw+nh+nd+ni+2*(nl+lk_offset)+nk+2*ne+np;
74             break;
75         }
76         case OFM_LEVEL1: {
77             lh = header_max + 1;
78             nw++; nh++; nd++; ni++;
79             compute_ligkern_offset();
80             words_per_entry = (12 + 2*npc) / 4;
81             ncw = num_char_info * words_per_entry;
82             lf = 29+lh+ncw+nw+nh+nd+ni+2*(nl+lk_offset)+nk+2*ne+np+
83                  nki+nwi+nkf+nwf+nkm+nwm+nkr+nwr+nkg+nwg+nkp+nwp;
84             nco = 29+lh+nki+nwi+nkf+nwf+nkm+nwm+nkr+nwr+nkg+nwg+nkp+nwp;
85             break;
86         }
87         default: { internal_error_0("output_ofm_subfiles"); }
88     }
89 }
90 
91 static void
output_ofm_subsizes(void)92 output_ofm_subsizes(void)
93 {
94     switch(ofm_level) {
95         case OFM_TFM: {
96             out_ofm_2(lf); out_ofm_2(lh); out_ofm_2(bc); out_ofm_2(ec);
97             out_ofm_2(nw); out_ofm_2(nh); out_ofm_2(nd); out_ofm_2(ni);
98             out_ofm_2(nl+lk_offset); out_ofm_2(nk);
99             out_ofm_2(ne); out_ofm_2(np);
100             break;
101         }
102         case OFM_LEVEL0: {
103             out_ofm_4(0);
104             out_ofm_4(lf); out_ofm_4(lh); out_ofm_4(bc); out_ofm_4(ec);
105             out_ofm_4(nw); out_ofm_4(nh); out_ofm_4(nd); out_ofm_4(ni);
106             out_ofm_4(nl+lk_offset); out_ofm_4(nk);
107             out_ofm_4(ne); out_ofm_4(np); out_ofm_4(font_dir);
108             break;
109         }
110         case OFM_LEVEL1: {
111             out_ofm_4(1);
112             out_ofm_4(lf); out_ofm_4(lh); out_ofm_4(bc); out_ofm_4(ec);
113             out_ofm_4(nw); out_ofm_4(nh); out_ofm_4(nd); out_ofm_4(ni);
114             out_ofm_4(nl+lk_offset); out_ofm_4(nk);
115             out_ofm_4(ne); out_ofm_4(np); out_ofm_4(font_dir);
116             out_ofm_4(nco); out_ofm_4(ncw); out_ofm_4(npc);
117             out_ofm_4(nki); out_ofm_4(nwi);
118             out_ofm_4(nkf); out_ofm_4(nwf);
119             out_ofm_4(nkm); out_ofm_4(nwm);
120             out_ofm_4(nkr); out_ofm_4(nwr);
121             out_ofm_4(nkg); out_ofm_4(nwg);
122             out_ofm_4(nkp); out_ofm_4(nwp);
123             break;
124         }
125         default: { internal_error_0("output_ofm_subfiles"); }
126     }
127 }
128 
129 unsigned file_ofm_count = 0;
130 
131 void
out_ofm(unsigned i)132 out_ofm(unsigned i)
133 {
134     fputc(i,file_ofm);
135     file_ofm_count++;
136 }
137 
138 void
out_ofm_2(unsigned i)139 out_ofm_2(unsigned i)
140 {
141 
142     fputc((i>>8)&0xff,  file_ofm);
143     fputc(i&0xff,       file_ofm);
144     file_ofm_count += 2;
145 }
146 
147 void
out_ofm_4(unsigned i)148 out_ofm_4(unsigned i)
149 {
150     fputc((i>>24)&0xff, file_ofm);
151     fputc((i>>16)&0xff, file_ofm);
152     fputc((i>>8)&0xff,  file_ofm);
153     fputc(i&0xff,       file_ofm);
154     file_ofm_count += 4;
155 }
156 
157 void
out_ofm_char(unsigned i)158 out_ofm_char(unsigned i)
159 {
160     if (ofm_level == OFM_NOLEVEL) {
161         internal_error_1("out_ofm_char.1 (ofm_level=%d)", ofm_level);
162     }
163     if (ofm_level == OFM_TFM) {
164         if (i>=0x100) internal_error_1("out_ofm_char.2 (i=%x)", i);
165         out_ofm(i);
166     } else {
167         if (i>=0x10000) internal_error_1("out_ofm_char.3 (i=%x)", i);
168         out_ofm_2(i);
169     }
170 }
171 
172 #define dabs(x) ((x)>=0?(x):-(x))
173 
174 void
out_ofm_scaled(fix fval)175 out_ofm_scaled(fix fval)
176 {
177     if (dabs((double)fval/(double)design_units) >= 16.0) {
178         warning_2("The relative dimension %d is too large.\n"
179                   "Must be less than 16*designsize = %d designunits",
180                   fval/0x100000, design_units/0x10000);
181         fval = 0;
182     }
183     if (design_units != UNITY) {
184         fval = zround(((double)fval/(double)design_units) * 1048576.0);
185     }
186     if (fval < 0) {
187         out_ofm(255); fval = fval + 0x1000000;
188         if (fval <= 0) fval = 1;
189     } else {
190         out_ofm(0);
191         if (fval >= 0x1000000) fval = 0xffffff;
192     }
193     out_ofm((fval >> 16) & 0xff);
194     out_ofm((fval >> 8) & 0xff);
195     out_ofm(fval & 0xff);
196 }
197