2 |
- |
1 |
% Copyright (C) 1992, 1993, 1994, 1995, 1999 Aladdin Enterprises. All rights reserved.
|
|
|
2 |
%
|
|
|
3 |
% This software is provided AS-IS with no warranty, either express or
|
|
|
4 |
% implied.
|
|
|
5 |
%
|
|
|
6 |
% This software is distributed under license and may not be copied,
|
|
|
7 |
% modified or distributed except as expressly authorized under the terms
|
|
|
8 |
% of the license contained in the file LICENSE in this distribution.
|
|
|
9 |
%
|
|
|
10 |
% For more information about licensing, please refer to
|
|
|
11 |
% http://www.ghostscript.com/licensing/. For information on
|
|
|
12 |
% commercial licensing, go to http://www.artifex.com/licensing/ or
|
|
|
13 |
% contact Artifex Software, Inc., 101 Lucas Valley Road #110,
|
|
|
14 |
% San Rafael, CA 94903, U.S.A., +1(415)492-9861.
|
|
|
15 |
|
|
|
16 |
% $Id: font2c.ps,v 1.6 2003/07/10 02:56:51 ray Exp $
|
|
|
17 |
% font2c.ps
|
|
|
18 |
% Write out a PostScript Type 0 or Type 1 font as C code
|
|
|
19 |
% that can be linked with the interpreter.
|
|
|
20 |
% This even works on protected fonts, if you use the -dWRITESYSTEMDICT
|
|
|
21 |
% switch in the command line. The code is reentrant and location-
|
|
|
22 |
% independent and has no external references, so it can be put into
|
|
|
23 |
% a sharable library even on VMS.
|
|
|
24 |
|
|
|
25 |
/font2cdict 100 dict dup begin
|
|
|
26 |
|
|
|
27 |
% Define the maximum string length that all compilers will accept.
|
|
|
28 |
% This must be approximately
|
|
|
29 |
% min(max line length, max string literal length) / 4 - 5.
|
|
|
30 |
|
|
|
31 |
/max_wcs 50 def
|
|
|
32 |
|
|
|
33 |
% Define a temporary file for writing out procedures.
|
|
|
34 |
/wtempname (_.tmp) def
|
|
|
35 |
|
|
|
36 |
% ------ Protection utilities ------ %
|
|
|
37 |
|
|
|
38 |
% Protection values are represented by a mask:
|
|
|
39 |
/a_noaccess 0 def
|
|
|
40 |
/a_executeonly 1 def
|
|
|
41 |
/a_readonly 3 def
|
|
|
42 |
/a_all 7 def
|
|
|
43 |
/prot_names
|
|
|
44 |
[ (0) (a_execute) null (a_readonly) null null null (a_all)
|
|
|
45 |
] def
|
|
|
46 |
/prot_opers
|
|
|
47 |
[ {noaccess} {executeonly} {} {readonly} {} {} {} {}
|
|
|
48 |
] def
|
|
|
49 |
|
|
|
50 |
% Get the protection of an object.
|
|
|
51 |
/getpa
|
|
|
52 |
{ dup wcheck
|
|
|
53 |
{ pop a_all }
|
|
|
54 |
{ % Check for executeonly or noaccess objects in protected.
|
|
|
55 |
dup protected exch known
|
|
|
56 |
{ protected exch get }
|
|
|
57 |
{ pop a_readonly }
|
|
|
58 |
ifelse
|
|
|
59 |
}
|
|
|
60 |
ifelse
|
|
|
61 |
} bind def
|
|
|
62 |
|
|
|
63 |
% Get the protection appropriate for (all the) values in a dictionary.
|
|
|
64 |
/getva
|
|
|
65 |
{ a_noaccess exch
|
|
|
66 |
{ exch pop
|
|
|
67 |
dup type dup /stringtype eq 1 index /arraytype eq or
|
|
|
68 |
exch /packedarraytype eq or
|
|
|
69 |
{ getpa a_readonly and or }
|
|
|
70 |
{ pop pop a_all exit }
|
|
|
71 |
ifelse
|
|
|
72 |
}
|
|
|
73 |
forall
|
|
|
74 |
} bind def
|
|
|
75 |
|
|
|
76 |
% Keep track of executeonly and noaccess objects,
|
|
|
77 |
% but don't let the protection actually take effect.
|
|
|
78 |
.currentglobal
|
|
|
79 |
false .setglobal % so protected can reference local objs
|
|
|
80 |
/protected % do first so // will work
|
|
|
81 |
systemdict wcheck { 1500 dict } { 1 dict } ifelse
|
|
|
82 |
def
|
|
|
83 |
systemdict wcheck not
|
|
|
84 |
{ (Warning: you will not be able to convert protected fonts.\n) print
|
|
|
85 |
(If you need to convert a protected font, please\n) print
|
|
|
86 |
(restart the program and specify the -dWRITESYSTEMDICT switch.\n) print
|
|
|
87 |
flush
|
|
|
88 |
(%end) .skipeof
|
|
|
89 |
}
|
|
|
90 |
if
|
|
|
91 |
userdict begin
|
|
|
92 |
/executeonly
|
|
|
93 |
{ dup //protected exch //a_executeonly put readonly
|
|
|
94 |
} bind def
|
|
|
95 |
/noaccess
|
|
|
96 |
{ dup //protected exch //a_noaccess put readonly
|
|
|
97 |
} bind def
|
|
|
98 |
end
|
|
|
99 |
true .setglobal
|
|
|
100 |
systemdict begin
|
|
|
101 |
/executeonly
|
|
|
102 |
{ userdict /executeonly get exec
|
|
|
103 |
} bind odef
|
|
|
104 |
/noaccess
|
|
|
105 |
{ userdict /noaccess get exec
|
|
|
106 |
} bind odef
|
|
|
107 |
end
|
|
|
108 |
%end
|
|
|
109 |
.setglobal
|
|
|
110 |
|
|
|
111 |
% ------ Output utilities ------ %
|
|
|
112 |
|
|
|
113 |
% By convention, the output file is named cfile.
|
|
|
114 |
|
|
|
115 |
% Define some utilities for writing the output file.
|
|
|
116 |
/wtstring 100 string def
|
|
|
117 |
/wb {cfile exch write} bind def
|
|
|
118 |
/ws {cfile exch writestring} bind def
|
|
|
119 |
/wl {ws (\n) ws} bind def
|
|
|
120 |
/wt {wtstring cvs ws} bind def
|
|
|
121 |
|
|
|
122 |
% Write a C string. Some compilers have unreasonably small limits on
|
|
|
123 |
% the length of a string literal or the length of a line, so every place
|
|
|
124 |
% that uses wcs must either know that the string is short,
|
|
|
125 |
% or be prepared to use wcca instead.
|
|
|
126 |
/wbx
|
|
|
127 |
{ 8#1000 add 8 (0000) cvrs dup 0 (\\) 0 get put ws
|
|
|
128 |
} bind def
|
|
|
129 |
/wcst
|
|
|
130 |
[
|
|
|
131 |
32 { /wbx load } repeat
|
|
|
132 |
95 { /wb load } repeat
|
|
|
133 |
129 { /wbx load } repeat
|
|
|
134 |
] def
|
|
|
135 |
("\\) { wcst exch { (\\) ws wb } put } forall
|
|
|
136 |
/wcs
|
|
|
137 |
{ (") ws { dup wcst exch get exec } forall (") ws
|
|
|
138 |
} bind def
|
|
|
139 |
/can_wcs % Test if can use wcs
|
|
|
140 |
{ length max_wcs le
|
|
|
141 |
} bind def
|
|
|
142 |
/wncs % name -> C string
|
|
|
143 |
{ wtstring cvs wcs
|
|
|
144 |
} bind def
|
|
|
145 |
% Write a C string as an array of character values.
|
|
|
146 |
% We only need this because of line and literal length limitations.
|
|
|
147 |
/wca % <string> <prefix> <suffix> wca -
|
|
|
148 |
{ 0 4 -2 roll exch
|
|
|
149 |
{ % Stack: suffix n prefix char
|
|
|
150 |
exch ws
|
|
|
151 |
exch dup 19 ge { () wl pop 0 } if 1 add
|
|
|
152 |
exch dup 32 ge 1 index 126 le and
|
|
|
153 |
{ 39 wb dup 39 eq 1 index 92 eq or { 92 wb } if wb 39 wb }
|
|
|
154 |
{ wt }
|
|
|
155 |
ifelse (,)
|
|
|
156 |
} forall
|
|
|
157 |
pop pop ws
|
|
|
158 |
} bind def
|
|
|
159 |
/wcca % <string> wcca -
|
|
|
160 |
{ ({\n) (}) wca
|
|
|
161 |
} bind def
|
|
|
162 |
|
|
|
163 |
% Write object protection attributes. Note that dictionaries and arrays are
|
|
|
164 |
% the only objects that can be writable.
|
|
|
165 |
/wpa
|
|
|
166 |
{ dup xcheck { (a_executable|) ws } if
|
|
|
167 |
dup type dup /dicttype eq exch /arraytype eq or
|
|
|
168 |
{ getpa }
|
|
|
169 |
{ getpa a_readonly and }
|
|
|
170 |
ifelse prot_names exch get ws
|
|
|
171 |
} bind def
|
|
|
172 |
/wva
|
|
|
173 |
{ getva prot_names exch get ws
|
|
|
174 |
} bind def
|
|
|
175 |
|
|
|
176 |
% ------ Object writing ------ %
|
|
|
177 |
|
|
|
178 |
/wnstring 128 string def
|
|
|
179 |
|
|
|
180 |
% Convert an object to a string to be scanned at a later time.
|
|
|
181 |
/cvos % <obj> cvos <string>
|
|
|
182 |
{ % We'd like to use == and write directly to a string,
|
|
|
183 |
% but we can't do the former because of operators,
|
|
|
184 |
% and we can't do the latter because we can't predict
|
|
|
185 |
% how long the string would have to be....
|
|
|
186 |
wtempname (w) file dup 3 -1 roll wproc closefile
|
|
|
187 |
wtempname status pop pop pop exch pop string
|
|
|
188 |
wtempname (r) file dup 3 -1 roll readstring pop exch closefile
|
|
|
189 |
} bind def
|
|
|
190 |
|
|
|
191 |
% Write a string/name or null as an element of a string/name/null array.
|
|
|
192 |
% Convert any other kind of value to a token to be read back in.
|
|
|
193 |
/wsn
|
|
|
194 |
{ dup null eq
|
|
|
195 |
{ pop (\t255,255,) wl
|
|
|
196 |
}
|
|
|
197 |
{ dup type /nametype eq { wnstring cvs } if
|
|
|
198 |
dup type /stringtype ne { cvos (255,) ws } if
|
|
|
199 |
dup length 256 idiv wt (,) ws
|
|
|
200 |
dup length 256 mod wt
|
|
|
201 |
(,) (,\n) wca
|
|
|
202 |
}
|
|
|
203 |
ifelse
|
|
|
204 |
} bind def
|
|
|
205 |
% Write a packed string/name/null array.
|
|
|
206 |
/wsna % <name> <(string|name|null)*> wsna -
|
|
|
207 |
{ (\tstatic const unsigned char ) ws exch wt ([] = {) wl
|
|
|
208 |
{ wsn } forall
|
|
|
209 |
(\t0\n};) wl
|
|
|
210 |
} bind def
|
|
|
211 |
|
|
|
212 |
% Write a number or an array of numbers, as refs.
|
|
|
213 |
/isnumber
|
|
|
214 |
{ type dup /integertype eq exch /realtype eq or
|
|
|
215 |
} bind def
|
|
|
216 |
/wnums
|
|
|
217 |
{ dup isnumber
|
|
|
218 |
{ (real_v\() ws wt (\),) ws }
|
|
|
219 |
{ { wnums } forall }
|
|
|
220 |
ifelse
|
|
|
221 |
} bind def
|
|
|
222 |
|
|
|
223 |
% Test whether a procedure or unusual array can be written (printed).
|
|
|
224 |
/iswx 4 dict dup begin
|
|
|
225 |
/arraytype { { iswproc } isall } def
|
|
|
226 |
/nametype { pop true } def
|
|
|
227 |
/operatortype { pop true } def % assume it has been bound in
|
|
|
228 |
/packedarraytype /arraytype load def
|
|
|
229 |
end def
|
|
|
230 |
/iswnx 6 dict dup begin
|
|
|
231 |
/arraytype { { iswproc } isall } def
|
|
|
232 |
/integertype { pop true } def
|
|
|
233 |
/nametype { pop true } def
|
|
|
234 |
/realtype { pop true } def
|
|
|
235 |
/stringtype { pop true } def
|
|
|
236 |
/packedarraytype /arraytype load def
|
|
|
237 |
end def
|
|
|
238 |
/iswproc % <obj> iswproc <bool>
|
|
|
239 |
{ dup xcheck { iswx } { iswnx } ifelse
|
|
|
240 |
1 index type .knownget { exec } { pop false } ifelse
|
|
|
241 |
} bind def
|
|
|
242 |
|
|
|
243 |
% Write a printable procedure (one for which iswproc returns true).
|
|
|
244 |
/wproca 3 dict dup begin
|
|
|
245 |
/arraytype
|
|
|
246 |
{ 1 index ({) writestring
|
|
|
247 |
{ 1 index ( ) writestring 1 index exch wproc } forall
|
|
|
248 |
(}) writestring
|
|
|
249 |
} bind def
|
|
|
250 |
/packedarraytype /arraytype load def
|
|
|
251 |
/operatortype { .writecvs } bind def % assume binding would work
|
|
|
252 |
end def
|
|
|
253 |
/wproc % <file> <proc> wproc -
|
|
|
254 |
{ dup type wproca exch .knownget { exec } { write==only } ifelse
|
|
|
255 |
} bind def
|
|
|
256 |
|
|
|
257 |
% Write a named object. Return true if this was possible.
|
|
|
258 |
% Legal types are: boolean, integer, name, real, string,
|
|
|
259 |
% array of (integer, integer+real, name, null+string),
|
|
|
260 |
% and certain procedures and other arrays (see iswproc above).
|
|
|
261 |
% All other objects are either handled specially or ignored.
|
|
|
262 |
/isall % <array> <proc> isall <bool>
|
|
|
263 |
{ true 3 -1 roll
|
|
|
264 |
{ 2 index exec not { pop false exit } if }
|
|
|
265 |
forall exch pop
|
|
|
266 |
} bind def
|
|
|
267 |
/wott 8 dict dup begin
|
|
|
268 |
/arraytype
|
|
|
269 |
{ woatt
|
|
|
270 |
{ aload pop 2 index 2 index exec
|
|
|
271 |
{ exch pop exec exit }
|
|
|
272 |
{ pop pop }
|
|
|
273 |
ifelse
|
|
|
274 |
}
|
|
|
275 |
forall
|
|
|
276 |
} bind def
|
|
|
277 |
/booleantype
|
|
|
278 |
{ { (\tmake_true\(&) } { (\tmake_false\(&) } ifelse ws
|
|
|
279 |
wt (\);) wl true
|
|
|
280 |
} bind def
|
|
|
281 |
/integertype
|
|
|
282 |
{ (\tmake_int\(&) ws exch wt (, ) ws
|
|
|
283 |
wt (\);) wl true
|
|
|
284 |
} bind def
|
|
|
285 |
/nametype
|
|
|
286 |
{ (\tcode = (*pprocs->name_create)\(i_ctx_p, &) ws exch wt
|
|
|
287 |
(, ) ws wnstring cvs wcs % OK, names are short
|
|
|
288 |
(\);) wl
|
|
|
289 |
(\tif ( code < 0 ) return code;) wl
|
|
|
290 |
true
|
|
|
291 |
} bind def
|
|
|
292 |
/packedarraytype
|
|
|
293 |
/arraytype load def
|
|
|
294 |
/realtype
|
|
|
295 |
{ (\tmake_real\(&) ws exch wt (, (float)) ws
|
|
|
296 |
wt (\);) wl true
|
|
|
297 |
} bind def
|
|
|
298 |
/stringtype
|
|
|
299 |
{ ({\tstatic const unsigned char s_[] = ) ws
|
|
|
300 |
dup dup can_wcs { wcs } { wcca } ifelse
|
|
|
301 |
(;) wl
|
|
|
302 |
(\tmake_const_string\(&) ws exch wt
|
|
|
303 |
(, a_readonly, ) ws length wt (, (const byte *)s_\);) wl
|
|
|
304 |
(}) wl true
|
|
|
305 |
} bind def
|
|
|
306 |
end def
|
|
|
307 |
% Write some other kind of object, if known.
|
|
|
308 |
/wother
|
|
|
309 |
{ dup otherobjs exch known
|
|
|
310 |
{ otherobjs exch get (\t) ws exch wt ( = ) ws wt (;) wl true }
|
|
|
311 |
{ pop pop false }
|
|
|
312 |
ifelse
|
|
|
313 |
} bind def
|
|
|
314 |
% Top-level procedure.
|
|
|
315 |
/wo % name obj -> OK
|
|
|
316 |
{ dup type wott exch .knownget { exec } { wother } ifelse
|
|
|
317 |
} bind def
|
|
|
318 |
|
|
|
319 |
% Write an array (called by wo).
|
|
|
320 |
/wap % <name> <array> wap -
|
|
|
321 |
{ dup xcheck not 1 index wcheck not and 1 index rcheck and
|
|
|
322 |
{ pop pop }
|
|
|
323 |
{ (\tr_set_attrs\(&) ws exch wt (, ) ws wpa (\);) wl }
|
|
|
324 |
ifelse
|
|
|
325 |
} bind def
|
|
|
326 |
/wnuma { % <name> <array> <element_C_type> <<type>_v> wnuma -
|
|
|
327 |
({\tstatic const ref_\() ws exch ws (\) a_[] = {) wl exch
|
|
|
328 |
% Stack: name type_v array
|
|
|
329 |
dup length 0 eq {
|
|
|
330 |
(\t) ws 1 index ws (\(0\)) wl
|
|
|
331 |
} {
|
|
|
332 |
dup {
|
|
|
333 |
(\t) ws 2 index ws (\() ws wt (\),) wl
|
|
|
334 |
} forall
|
|
|
335 |
} ifelse exch pop
|
|
|
336 |
% Stack: name array
|
|
|
337 |
(\t};) wl
|
|
|
338 |
dup wcheck {
|
|
|
339 |
(\tcode = (*pprocs->scalar_array_create)\(i_ctx_p, &) ws exch wt
|
|
|
340 |
(, (const ref *)a_, ) ws dup length wt
|
|
|
341 |
(, ) ws wpa (\);) wl
|
|
|
342 |
(\tif ( code < 0 ) return code;) wl
|
|
|
343 |
} {
|
|
|
344 |
(\tmake_const_array\(&) ws exch wt
|
|
|
345 |
(, avm_foreign|) ws dup wpa (, ) ws length wt
|
|
|
346 |
(, (const ref *)a_\);) wl
|
|
|
347 |
} ifelse
|
|
|
348 |
(}) wl
|
|
|
349 |
} bind def
|
|
|
350 |
/woatt [
|
|
|
351 |
% Integers
|
|
|
352 |
{ { { type /integertype eq } isall }
|
|
|
353 |
{ (long) (integer_v) wnuma true }
|
|
|
354 |
}
|
|
|
355 |
% Integers + reals
|
|
|
356 |
{ { { type dup /integertype eq exch /realtype eq or } isall }
|
|
|
357 |
{ (float) (real_v) wnuma true }
|
|
|
358 |
}
|
|
|
359 |
% Strings + nulls
|
|
|
360 |
{ { { type dup /nulltype eq exch /stringtype eq or } isall }
|
|
|
361 |
{ ({) ws dup (sa_) exch wsna
|
|
|
362 |
(\tcode = (*pprocs->string_array_create)\(i_ctx_p, &) ws exch wt
|
|
|
363 |
(, \(const char *\)sa_, ) ws dup length wt (, ) ws wpa (\);) wl
|
|
|
364 |
(\tif ( code < 0 ) return code;) wl
|
|
|
365 |
(}) wl true
|
|
|
366 |
}
|
|
|
367 |
}
|
|
|
368 |
% Names
|
|
|
369 |
{ { { type /nametype eq } isall }
|
|
|
370 |
{ ({) ws dup (na_) exch wsna
|
|
|
371 |
(\tcode = (*pprocs->name_array_create)\(i_ctx_p, &) ws 1 index wt
|
|
|
372 |
(, \(const char *\)na_, ) ws dup length wt (\);) wl
|
|
|
373 |
(\tif ( code < 0 ) return code;) wl
|
|
|
374 |
wap (}) wl true
|
|
|
375 |
}
|
|
|
376 |
}
|
|
|
377 |
% Procedure
|
|
|
378 |
{ { iswproc }
|
|
|
379 |
{ dup cvos
|
|
|
380 |
% Stack: name proc string
|
|
|
381 |
({\tstatic const unsigned char s_[] = ) ws
|
|
|
382 |
dup dup can_wcs { wcs } { wcca } ifelse
|
|
|
383 |
(;) wl
|
|
|
384 |
(\tcode = (*pprocs->ref_from_string)\(i_ctx_p, &) ws 2 index wt
|
|
|
385 |
(, \(const char *\)s_, ) ws length wt (\);) wl
|
|
|
386 |
(\tif ( code < 0 ) return code;) wl
|
|
|
387 |
wap (}) wl true
|
|
|
388 |
wtempname deletefile
|
|
|
389 |
}
|
|
|
390 |
}
|
|
|
391 |
% Default
|
|
|
392 |
{ { pop true }
|
|
|
393 |
{ wother }
|
|
|
394 |
}
|
|
|
395 |
] def
|
|
|
396 |
|
|
|
397 |
% Write a named dictionary. We assume the ref is already declared.
|
|
|
398 |
/wd % <name> <dict> <extra> wd -
|
|
|
399 |
{ 3 1 roll
|
|
|
400 |
({) ws
|
|
|
401 |
(\tref v_[) ws dup length wt (];) wl
|
|
|
402 |
dup [ exch
|
|
|
403 |
{ counttomark 2 sub wtstring cvs
|
|
|
404 |
(v_[) exch concatstrings (]) concatstrings exch wo not
|
|
|
405 |
{ (Skipping ) print ==only (....\n) print }
|
|
|
406 |
if
|
|
|
407 |
} forall
|
|
|
408 |
]
|
|
|
409 |
% Stack: array of keys (names)
|
|
|
410 |
({) ws dup (str_keys_) exch wsna
|
|
|
411 |
(\tstatic const cfont_dict_keys keys_ =) wl
|
|
|
412 |
(\t { 0, 0, ) ws length wt (, ) ws 3 -1 roll wt (, ) ws
|
|
|
413 |
dup wpa (, ) ws dup wva ( };) wl pop
|
|
|
414 |
(\tcode = \(*pprocs->ref_dict_create\)\(i_ctx_p, &) ws wt
|
|
|
415 |
(, &keys_, \(const char *\)str_keys_, v_\);) wl
|
|
|
416 |
(\tif ( code < 0 ) return code;) wl
|
|
|
417 |
(}) wl
|
|
|
418 |
(}) wl
|
|
|
419 |
} bind def
|
|
|
420 |
|
|
|
421 |
% Write character dictionary keys.
|
|
|
422 |
% We save a lot of space by abbreviating keys which appear in
|
|
|
423 |
% StandardEncoding or ISOLatin1Encoding.
|
|
|
424 |
% Writes code to declare and initialize enc_keys_, str_keys, and keys_.
|
|
|
425 |
/wcdkeys % <dict> wcdkeys -
|
|
|
426 |
{ % Write keys present in StandardEncoding or ISOLatin1Encoding,
|
|
|
427 |
% pushing other keys on the o-stack.
|
|
|
428 |
(static const charindex enc_keys_[] = {) wl
|
|
|
429 |
dup [ exch 0 exch
|
|
|
430 |
{ pop decoding 1 index known
|
|
|
431 |
{ decoding exch get ({) ws dup -8 bitshift wt
|
|
|
432 |
(,) ws 255 and wt (}, ) ws
|
|
|
433 |
1 add dup 5 mod 0 eq { (\n) ws } if
|
|
|
434 |
}
|
|
|
435 |
{ exch }
|
|
|
436 |
ifelse
|
|
|
437 |
}
|
|
|
438 |
forall pop
|
|
|
439 |
]
|
|
|
440 |
({0,0}\n};) wl
|
|
|
441 |
% Write other keys.
|
|
|
442 |
(str_keys_) exch wsna
|
|
|
443 |
% Write the declaration for keys_.
|
|
|
444 |
(static const cfont_dict_keys keys_ = {) wl
|
|
|
445 |
(\tenc_keys_, countof\(enc_keys_\) - 1,) wl
|
|
|
446 |
(\t) ws dup length wt ( - \(countof\(enc_keys_\) - 1\), 0, ) ws
|
|
|
447 |
dup wpa (, ) ws wva () wl
|
|
|
448 |
(};) wl
|
|
|
449 |
} bind def
|
|
|
450 |
|
|
|
451 |
% Enumerate character dictionary values in the same order that
|
|
|
452 |
% the keys appear in enc_keys_ and str_keys_.
|
|
|
453 |
% <proc> is called with each value in turn.
|
|
|
454 |
/cdforall % <dict> <proc> cdforall -
|
|
|
455 |
{ 2 copy
|
|
|
456 |
{ decoding 3 index known
|
|
|
457 |
{ 3 -1 roll pop exec }
|
|
|
458 |
{ pop pop pop }
|
|
|
459 |
ifelse
|
|
|
460 |
}
|
|
|
461 |
/exec cvx 3 packedarray cvx
|
|
|
462 |
/forall cvx
|
|
|
463 |
5 -2 roll
|
|
|
464 |
{ decoding 3 index known
|
|
|
465 |
{ pop pop pop }
|
|
|
466 |
{ 3 -1 roll pop exec }
|
|
|
467 |
ifelse
|
|
|
468 |
}
|
|
|
469 |
/exec cvx 3 packedarray cvx
|
|
|
470 |
/forall cvx
|
|
|
471 |
6 packedarray cvx exec
|
|
|
472 |
} bind def
|
|
|
473 |
|
|
|
474 |
% ------ Writers for special objects ------ %
|
|
|
475 |
|
|
|
476 |
/writespecial 10 dict dup begin
|
|
|
477 |
|
|
|
478 |
/FontInfo { 0 wd } def
|
|
|
479 |
|
|
|
480 |
/Private { 0 wd } def
|
|
|
481 |
|
|
|
482 |
/CharStrings
|
|
|
483 |
{ ({) wl
|
|
|
484 |
dup wcdkeys
|
|
|
485 |
(static const unsigned char values_[] = {) wl
|
|
|
486 |
{ wsn } cdforall
|
|
|
487 |
(\t0\n};) wl
|
|
|
488 |
(\tcode = \(*pprocs->string_dict_create\)\(i_ctx_p, &) ws wt
|
|
|
489 |
(, &keys_, (const char *)str_keys_, \(const char *\)values_\);) wl
|
|
|
490 |
(\tif ( code < 0 ) return code;) wl
|
|
|
491 |
(}) wl
|
|
|
492 |
} bind def
|
|
|
493 |
|
|
|
494 |
/Metrics
|
|
|
495 |
{ ({) wl
|
|
|
496 |
dup wcdkeys
|
|
|
497 |
(static const ref_(float) values_[] = {) wl
|
|
|
498 |
dup { (\t) ws wnums () wl } cdforall
|
|
|
499 |
(\t0\n};) wl
|
|
|
500 |
(static const unsigned char lengths_[] = {) wl
|
|
|
501 |
{ (\t) ws dup isnumber
|
|
|
502 |
{ pop 0 }
|
|
|
503 |
{ length 1 add }
|
|
|
504 |
ifelse wt (,) wl
|
|
|
505 |
} cdforall
|
|
|
506 |
(\t0\n};) wl
|
|
|
507 |
(\tcode = \(*pprocs->num_dict_create\)\(i_ctx_p, &) ws wt
|
|
|
508 |
(, &keys_, str_keys_, (const ref *)values_, lengths_\);) wl
|
|
|
509 |
(\tif ( code < 0 ) return code;) wl
|
|
|
510 |
(}) wl
|
|
|
511 |
} bind def
|
|
|
512 |
|
|
|
513 |
/Metrics2 /Metrics load def
|
|
|
514 |
|
|
|
515 |
/FDepVector pop % (converted to a list of font names)
|
|
|
516 |
|
|
|
517 |
end def
|
|
|
518 |
|
|
|
519 |
% ------ The main program ------ %
|
|
|
520 |
|
|
|
521 |
% Construct an inverse dictionary of encodings.
|
|
|
522 |
[ /StandardEncoding /ISOLatin1Encoding
|
|
|
523 |
/SymbolEncoding /DingbatsEncoding
|
|
|
524 |
/KanjiSubEncoding
|
|
|
525 |
]
|
|
|
526 |
dup length dict begin
|
|
|
527 |
{ mark exch dup { .findencoding exch def } stopped cleartomark
|
|
|
528 |
} forall
|
|
|
529 |
currentdict end /encodingnames exch def
|
|
|
530 |
|
|
|
531 |
% Invert the StandardEncoding and ISOLatin1Encoding vectors.
|
|
|
532 |
512 dict begin
|
|
|
533 |
|
|
|
534 |
|
|
|
535 |
currentdict end /decoding exch def
|
|
|
536 |
|
|
|
537 |
/writefont % cfilename procname -> [writes the current font]
|
|
|
538 |
{ (gsf_) exch concatstrings
|
|
|
539 |
/fontprocname exch def
|
|
|
540 |
/cfname exch def
|
|
|
541 |
/cfile cfname (w) file def
|
|
|
542 |
|
|
|
543 |
% Remove unwanted keys from the font.
|
|
|
544 |
currentfont dup length dict begin { def } forall
|
|
|
545 |
{ /FID /MIDVector /CurMID } { currentdict exch undef } forall
|
|
|
546 |
/Font currentdict end def
|
|
|
547 |
|
|
|
548 |
% Replace the FDepVector with a list of font names.
|
|
|
549 |
Font /FDepVector .knownget
|
|
|
550 |
{ [ exch { /FontName get } forall ]
|
|
|
551 |
Font /FDepVector 3 -1 roll put
|
|
|
552 |
}
|
|
|
553 |
if
|
|
|
554 |
|
|
|
555 |
% Find all the special objects we know about.
|
|
|
556 |
% wo uses this to write out references to otherwise intractable objects.
|
|
|
557 |
/otherobjs writespecial length dict dup begin
|
|
|
558 |
writespecial
|
|
|
559 |
{ pop Font 1 index .knownget { exch def } { pop } ifelse
|
|
|
560 |
}
|
|
|
561 |
forall
|
|
|
562 |
end def
|
|
|
563 |
|
|
|
564 |
% Define a dummy FontInfo, in case the font doesn't have one.
|
|
|
565 |
/FontInfo 0 dict def
|
|
|
566 |
|
|
|
567 |
% Write out the boilerplate.
|
|
|
568 |
Font begin
|
|
|
569 |
(/****************************************************************) wl
|
|
|
570 |
( Portions of this file are subject to the following notice(s):) wl
|
|
|
571 |
systemdict /copyright get wl
|
|
|
572 |
FontInfo /Notice .knownget
|
|
|
573 |
{ (----------------------------------------------------------------) wl wl
|
|
|
574 |
} if
|
|
|
575 |
(****************************************************************/) wl
|
|
|
576 |
() wl
|
|
|
577 |
(/* ) ws cfname ws ( */) wl
|
|
|
578 |
(/* This file was created by the ) ws product ws ( font2c utility. */) wl
|
|
|
579 |
() wl
|
|
|
580 |
(#undef DEBUG) wl
|
|
|
581 |
(#include "ccfont.h") wl
|
|
|
582 |
() wl
|
|
|
583 |
|
|
|
584 |
% Write the procedure prologue.
|
|
|
585 |
(#ifdef __PROTOTYPES__) wl
|
|
|
586 |
(ccfont_proc\() ws fontprocname ws (\);) wl
|
|
|
587 |
(int) wl
|
|
|
588 |
fontprocname ws ((i_ctx_t *i_ctx_p, const cfont_procs *pprocs, ref *pfont)) wl
|
|
|
589 |
(#else) wl
|
|
|
590 |
(int) wl
|
|
|
591 |
fontprocname ws ((i_ctx_p, pprocs, pfont) i_ctx_t *i_ctx_p; const cfont_procs *pprocs; ref *pfont;) wl
|
|
|
592 |
(#endif) wl
|
|
|
593 |
({\tint code;) wl
|
|
|
594 |
(\tref Font;) wl
|
|
|
595 |
otherobjs
|
|
|
596 |
{ exch pop (\tref ) ws wt (;) wl }
|
|
|
597 |
forall
|
|
|
598 |
|
|
|
599 |
% Write out the special objects.
|
|
|
600 |
otherobjs
|
|
|
601 |
{ exch writespecial 2 index get exec
|
|
|
602 |
}
|
|
|
603 |
forall
|
|
|
604 |
|
|
|
605 |
% Write out the main font dictionary.
|
|
|
606 |
% If possible, substitute the encoding name for the encoding;
|
|
|
607 |
% PostScript code will fix this up.
|
|
|
608 |
{ /Encoding /PrefEnc }
|
|
|
609 |
{ Font 1 index .knownget
|
|
|
610 |
{ encodingnames exch .knownget { def } { pop } ifelse }
|
|
|
611 |
{ pop }
|
|
|
612 |
ifelse
|
|
|
613 |
}
|
|
|
614 |
forall
|
|
|
615 |
(Font) Font FontType 0 eq { 5 } { 1 } ifelse wd
|
|
|
616 |
|
|
|
617 |
% Finish the procedural initialization code.
|
|
|
618 |
(\t*pfont = Font;) wl
|
|
|
619 |
(\treturn 0;) wl
|
|
|
620 |
(}) wl
|
|
|
621 |
end % Font
|
|
|
622 |
|
|
|
623 |
cfile closefile
|
|
|
624 |
|
|
|
625 |
} bind def
|
|
|
626 |
|
|
|
627 |
end def % font2cdict
|
|
|
628 |
|
|
|
629 |
% Compute the procedure name from the font name.
|
|
|
630 |
% Replace all non-alphanumeric characters with '_'.
|
|
|
631 |
/makefontprocnamemap 256 string
|
|
|
632 |
|
|
|
633 |
(0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)
|
|
|
634 |
{ 2 copy dup put pop } forall
|
|
|
635 |
readonly def
|
|
|
636 |
/makefontprocname % <fontname> makefontprocname <procnamestring>
|
|
|
637 |
{ dup length string cvs
|
|
|
638 |
dup length 1 sub -1 0
|
|
|
639 |
{ % Stack: string index
|
|
|
640 |
2 copy 2 copy get //makefontprocnamemap exch get put pop
|
|
|
641 |
}
|
|
|
642 |
for
|
|
|
643 |
} def
|
|
|
644 |
|
|
|
645 |
/writefont { font2cdict begin writefont end } def
|
|
|
646 |
|
|
|
647 |
% If the program was invoked from the command line, run it now.
|
|
|
648 |
[ shellarguments
|
|
|
649 |
{ counttomark dup 2 eq exch 3 eq or
|
|
|
650 |
{ counttomark -1 roll cvn
|
|
|
651 |
(Converting ) print dup =only ( font.\n) print flush
|
|
|
652 |
% Ensure that we get a clean copy of the font from the
|
|
|
653 |
% file system.
|
|
|
654 |
2 { % do both local and global
|
|
|
655 |
currentglobal not setglobal
|
|
|
656 |
dup undefinefont
|
|
|
657 |
} repeat
|
|
|
658 |
findfont setfont
|
|
|
659 |
(FontName is ) print currentfont /FontName get ==only (.\n) print flush
|
|
|
660 |
counttomark 1 eq
|
|
|
661 |
{ % Construct the procedure name from the file name.
|
|
|
662 |
currentfont /FontName get makefontprocname
|
|
|
663 |
}
|
|
|
664 |
if
|
|
|
665 |
writefont
|
|
|
666 |
(Done.\n) print flush
|
|
|
667 |
}
|
|
|
668 |
{ cleartomark
|
|
|
669 |
(Usage: font2c fontname cfilename.c [shortname]\n) print
|
|
|
670 |
( e.g.: font2c Courier cour.c\n) print flush
|
|
|
671 |
mark
|
|
|
672 |
}
|
|
|
673 |
ifelse
|
|
|
674 |
}
|
|
|
675 |
if pop
|