%! % 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