summaryrefslogtreecommitdiff
path: root/toolbin/encs2c.ps
blob: f487970ab91e887930b25dc116430ce349f7dd40 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
%!
% Copyright (C) 2001-2023 Artifex Software, Inc.
% All Rights Reserved.
%
% This software is provided AS-IS with no warranty, either express or
% implied.
%
% This software is distributed under license and may not be copied,
% modified or distributed except as expressly authorized under the terms
% of the license contained in the file LICENSE in this distribution.
%
% Refer to licensing information at http://www.artifex.com or contact
% Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
% CA 94129, USA, for further information.
%

% Generate a C file containing the standard encodings and glyph sets.

% This program probably never needs to be run again: it is included mostly
% for reference.  It reads in the known Encodings and pseudo-Encodings
% (see the definition of /encfiles below) and generates C files that
% represent them in a compact format described in src/gscencs.c.
%
% If this file does need to be run again (and it has been in December 2020) you
% should generate all 4 files (gscedata.[c,h] and gdevpdtv.[c,h] by running this
% program 4 times, once for each output file.
%
% The generated files are named gscedata.[ch] and are included in the
% source distribution in the src directory.  The canonical invocation is
%   gs -dNOSAFER -Ilib -dNODISPLAY -q -SO=gscedata.h toolbin/encs2c.ps > src/gscedata.h
%   gs -dNOSAFER -Ilib -dNODISPLAY -q -SO=gscedata.c toolbin/encs2c.ps > src/gscedata.c
%
% NOTE: If the C representation of encodings changes, this file
% (toolbin/encs2c.ps), src/gscencs.h, and src/gscencs.c must be kept
% consistent with each other.
%
% This program also generates a table of glyphs available in
% WinAnsiEncoding, StandardEncoding, MacExpertEncoding, SymbolEncoding
% for pdfwrite device.
%
%   gs -dNOSAFER -Ilib -dNODISPLAY -q -SO=gdevpdtv.h toolbin/encs2c.ps > src/gdevpdtv.h
%   gs -dNOSAFER -Ilib -dNODISPLAY -q -SO=gdevpdtv.c toolbin/encs2c.ps > src/gdevpdtv.c
%
% For "-Ilib" you need to point that at a valid "lib" directory from
% the ghostpdl tree - since gs_css_e.ps now lives there.

% .namestring is longer available as an operator, define an
% equivalent here
/.namestring
{
  dup length string cvs
} bind def


% ================ Write header file ================ %

% Free variables: maxlen.
/writeheader {
  (#ifndef gscedata_INCLUDED) =
  (#  define gscedata_INCLUDED) =
  () =
  (#define NUM_LEN_BITS ) print lenbits =
  () =
  (#define N(len,offset) (((offset) << NUM_LEN_BITS) + (len))) =
  (#define N_LEN(e) ((e) & ((1 << NUM_LEN_BITS) - 1))) =
  (#define N_OFFSET(e) ((e) >> NUM_LEN_BITS)) =
  () =
  (extern const char gs_c_known_encoding_chars[];) =
  (extern const int gs_c_known_encoding_total_chars;) =
  (extern const int gs_c_known_encoding_max_length;) =
  (extern const ushort gs_c_known_encoding_offsets[];) =
  (extern const int gs_c_known_encoding_count;) =
  (extern const ushort *const gs_c_known_encodings[];) =
  (extern const ushort *const gs_c_known_encodings_reverse[];) =
  (extern const ushort gs_c_known_encoding_lengths[];) =
  (extern const ushort gs_c_known_encoding_reverse_lengths[];) =
  () =
  (#endif /* gscedata_INCLUDED */) =
} def

% ================ Write data file ================ %

% Free variables: encnames, encodings, estrs, maxlen.
/writedata {
  /reverse_lengths encnames length array def

  (#include "stdpre.h") =
  (#include "gstypes.h") =
  (#include "gscedata.h") =

        % Write the name strings, sorted by increasing length, and
        % alphabetically increasing within the same length.
  (
const char gs_c_known_encoding_chars[] = {) =
  1 1 maxlen {
    /len exch def
    /noff 0 def
        % Collect and sort names of this length.
    [ estrs {
      pop dup length len ne { pop } { .namestring } ifelse
    } forall ] /lt load .sort
        % Output the names.
    {
      dup {
        (') print (x) dup 0 4 -1 roll put print (',) print
      } forall
      (  /*N\() print len =only (,) print noff =only (\)*/) =
      estrs exch get noff ne {
        (Different offsets in 1st and 2nd pass) =
      } if
      /noff noff len add def
    } forall
  } for
  (0};) =
(
const int gs_c_known_encoding_total_chars = ) print
  offset =only (;) =

        % Write the starting offsets of the names of each length.
  /numchars 0 estrs { pop length add } forall def
  (
const int gs_c_known_encoding_max_length = ) print
  maxlen =only (;) =
  (
const ushort gs_c_known_encoding_offsets[] = {) =
  0 1 maxlen {
    lbase exch get =only (,) print
  } for
  numchars =only (};) =

        % Write the encodings themselves.
  (
const int gs_c_known_encoding_count = ) print
  encodings length =only (;) =
  /i 0 def
  encodings {
    () =
    (/* ) print encnames i get =only ( */) =
    (static const ushort gs_c_known_encoding_) print i =only ([] = {) =
    /e exch def
    e {
      (N\() print dup length =only (,) print
      estrs 1 index get =only (\),  /*) print .namestring print (*/) =
    } forall (0};) =

    (static const ushort gs_c_known_encoding_reverse_) print i =only ([] = {) =
    [
    /code 0 def
    e {
      dup /.notdef eq {
        pop
      } {
        [ exch estrs 1 index get lenbits bitshift 1 index length add code ] %[/name N code]
      } ifelse
      /code code 1 add def
    } forall
    ]
    reverse_lengths i 2 index length put
    {1 get exch 1 get exch lt} .sort {
      aload pop
      =only
      pop
      (,   /* N\() print dup length =only (,) print
      estrs 1 index get =only (\): ) print .namestring print (*/) =
    } forall (0};) =

  /i i 1 add def
  } forall

        % Write the table of pointers to the encodings.
  (
const ushort *const gs_c_known_encodings[] = {) =
  0 1 encodings length 1 sub {
    (    gs_c_known_encoding_) print dup =only (, /* ) print
    encnames exch get =only ( */) =
  } for (    0
  };) =

  (const ushort *const gs_c_known_encodings_reverse[] = {) =
  0 1 encodings length 1 sub {
    (    gs_c_known_encoding_reverse_) print dup =only (, /* ) print
    encnames exch get =only ( */) =
  } for (    0
  };) =

        % Write the table of encoding lengths.
  (
const ushort gs_c_known_encoding_lengths[] = {) =
  0 1 encodings length 1 sub {
    encodings exch get length =only (,) print
  } for (0};) =

  (const ushort gs_c_known_encoding_reverse_lengths[] = {) =
  reverse_lengths {
    =only (,) print
  } forall (0};) =

} def

% ========= Write PDF good glyph table ========= %

/calc_glyph_table {

  /N { lenbits bitshift add } bind def

  /enc_mame_to_index <<
    0 encnames {
      exch dup 1 add
    } forall pop
  >> readonly def

  /glyph_type 600 dict begin

  /SymbolEncoding enc_mame_to_index exch get encodings exch get {
    dup length
    exch estrs exch get
    N 1 def
  } forall

  { /StandardEncoding /WinAnsiEncoding /MacExpertEncoding } {
    enc_mame_to_index exch get encodings exch get {
      dup length exch estrs exch get N 3 def
    } forall
  } forall
  currentdict end def

  /max_glyph 0 def

  glyph_type {
    pop max_glyph .max /max_glyph exch def
  } forall

} bind def

/write_glyph_table {
  (#include "gdevpdtv.h") = () =
  calc_glyph_table
  (/*) =
  ( * Glyph attributes for every glyph <= GS_C_PDF_MAX_GOOD_GLYPH) =
  ( * packed 4 per byte least significant bits first.) =
  ( */)=

  (const unsigned char gs_c_pdf_glyph_type[] = {) =
  0 1 max_glyph 4 idiv {
    4 mul
    dup           glyph_type exch .knownget not { 0 } if
    1 index 1 add glyph_type exch .knownget not { 0 } if 2 bitshift or
    1 index 2 add glyph_type exch .knownget not { 0 } if 4 bitshift or
    1 index 3 add glyph_type exch .knownget not { 0 } if 6 bitshift or
    =only
    3 add max_glyph lt { (,) } { () = (};) } ifelse =
  } for

} bind def

/write_glyph_table_header {
  calc_glyph_table

  (#ifndef gdevpdtv_INCLUDED) =
  (#define gdevpdtv_INCLUDED) =
  () =
  (#define GS_C_PDF_MAX_GOOD_GLYPH ) print max_glyph =
  (#define GS_C_PDF_GOOD_GLYPH_MASK 1) =
  (#define GS_C_PDF_GOOD_NON_SYMBOL_MASK 2) =
  () =
  (extern const unsigned char gs_c_pdf_glyph_type[];) =
  () =
  (#endif /* gdevpdtv_INCLUDED */) =
} bind def

% ================ Main program ================ %

% Collect the registered encodings.

/encodings 20 array def
/encfiles [
  [(gs_std_e.ps) (gs_il1_e.ps) (gs_sym_e.ps) (gs_dbt_e.ps)]
  [(gs_wan_e.ps) (gs_mro_e.ps) (gs_mex_e.ps) (gs_mgl_e.ps)]
  [(gs_lgo_e.ps) (gs_lgx_e.ps) (gs_css_e.ps)]
] def
/encnames 11 array def
/encindex null def
/encname null def
4 dict begin
/.registerencoding {
  /encindex 2 index store
  //encodings 3 1 roll readonly put
} bind def
/.defineencoding {
  pop /encname exch store
} bind def
encfiles { { runlibfile encnames encindex encname put } forall } forall
end
/encodings [ encodings { dup null eq { pop } if } forall ] def

% Collect all names referenced from the encodings.
/estrs 1000 dict def
/maxlen 0 def
encodings {
  {
    estrs 1 index null put
    .namestring length maxlen .max /maxlen exch def
  } forall
} forall

% Calculate glyph offset dictionary
/lbase maxlen 1 add array def
lbase 0 0 put
/offset 0 def
1 1 maxlen {
  /len exch def
  lbase len offset put
  /noff 0 def
        % Collect and sort names of this length.
  [ estrs {
  pop dup length len ne { pop } { .namestring } ifelse
  } forall ] /lt load .sort
        % Output the names.
  {
    estrs exch noff put
    /noff noff len add def
  } forall
  /offset offset noff add def
} for
estrs readonly pop

% Compute the division of the glyph number into length and offset.
/lenbits 1 maxlen {
  dup 1 eq { exit } if exch 1 add exch -1 bitshift
} loop pop def



% Write the initial boilerplate.
(/* Copyright (C) 2001-2023 Artifex Software, Inc.) =
(   All Rights Reserved.) =
() =
(   This software is provided AS-IS with no warranty, either express or) =
(   implied.) =
() =
(   This software is distributed under license and may not be copied,) =
(   modified or distributed except as expressly authorized under the terms) =
(   of the license contained in the file LICENSE in this distribution.) =
() =
(   Refer to licensing information at http://www.artifex.com or contact) =
(   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,) =
(   CA 94129, USA, for further information.) =

(*/) =
(/*) =
( * This file contains substantial parts of toolbin/encs2c.ps,) =
( * which generated the remainder of the file mechanically from) =
encfiles {
  ( * ) print { (  ) print print } forall () =
} forall
( *) =
( * This source file is maintained manually under source code control,) =
( * however its content should be regenerated by using encs2c.ps) =
( * if changes are required.) =
( * You should not manually alter this file! If you regenerate it using) =
( * encs2c.ps you must regenerate all 4 files; base/gscedata.[c|h]) =
( * and devices/vector/gdevpdtv.[c|h]) =
( */) =
() =

<<
  /gscedata.h { writeheader }
  /gscedata.c { writedata }
  /gdevpdtv.h { write_glyph_table_header }
  /gdevpdtv.c { write_glyph_table }
>> O .knownget {
  exec
} {
  (%stderr) (w) file dup dup
  (Don't know how to create ) writestring
  O writestring
  (\n) writestring
} ifelse

quit