X-Git-Url: https://git.distorted.org.uk/~mdw/sgt/halibut/blobdiff_plain/6005b6f8b888d708c285845a97b41252ccef4a66..36e8f0f56f85d20f939091301d65c7f4f6889998:/psdata.c diff --git a/psdata.c b/psdata.c index e9cad9c..af46099 100644 --- a/psdata.c +++ b/psdata.c @@ -7,23 +7,18 @@ #include "halibut.h" #include "paper.h" -/* ---------------------------------------------------------------------- - * Mapping between PS character names (/aacute, /zcaron etc) and - * Unicode code points. - * - * Generated from the Adobe Glyph List at - * - * http://partners.adobe.com/public/developer/en/opentype/glyphlist.txt - * - * by a succession of Perl/sh fragments, quoted alongside each - * array. - */ - /* + * Within the paper backends, PostScript glyph names are represented + * by small integers. For standard glyphs, these are indicies into + * a table generated from the Adobe Glyph List from + * . + * Since all the scripts that generate fragments of code for this file + * need that list, it's worth generating a file containing just the names. -grep '^[^#;][^;]*;[^ ][^ ][^ ][^ ]$' glyphlist.txt | sort -t\; +0 -1 | \ - cut -f1 -d\; | perl -ne 'chomp; print "\"$_\", "' | \ - fold -s -w68 | sed 's/^/ /'; echo +grep '^[^#;][^;]*;[^ ][^ ][^ ][^ ]$' glyphlist.txt | sort -t\; -k1,2 | \ + cut -f1 -d\; > glyphnames.txt + +< glyphnames.txt xargs printf '"%s", ' | fold -s -w68 | sed 's/^/ /'; echo */ static const char *const ps_glyphs_alphabetic[] = { @@ -1120,7 +1115,44 @@ static const char *const ps_glyphs_alphabetic[] = { "zretroflexhook", "zstroke", "zuhiragana", "zukatakana", }; -/* +glyph glyph_intern(char const *glyphname) +{ + int i, j, k, c; + + i = -1; + j = lenof(ps_glyphs_alphabetic); + while (j-i > 1) { + k = (i + j) / 2; + c = strcmp(glyphname, ps_glyphs_alphabetic[k]); + + if (c == 0) + return k; + else if (c < 0) + j = k; + else + i = k; + } + + return NOGLYPH; /* illegal value means not found */ +} + +char const *glyph_extern(glyph glyph) +{ + + if (glyph == NOGLYPH) return ".notdef"; + assert(glyph < lenof(ps_glyphs_alphabetic)); + return ps_glyphs_alphabetic[glyph]; +} + +/* ---------------------------------------------------------------------- + * Mapping between PS character names (/aacute, /zcaron etc) and + * Unicode code points. + * + * Generated from the Adobe Glyph List at + * + * http://partners.adobe.com/public/developer/en/opentype/glyphlist.txt + * + * by another Perl/sh fragment. grep '^[^#;][^;]*;[^ ][^ ][^ ][^ ]$' glyphlist.txt | sort -t\; +0 -1 | \ cut -f2 -d\; | perl -ne 'chomp; print "0x$_, "' | \ @@ -1655,25 +1687,10 @@ static const unsigned short ps_codes_alphabetic[] = { 0xFF5A, 0x305E, 0x30BE, 0x24B5, 0x0290, 0x01B6, 0x305A, 0x30BA, }; -wchar_t ps_glyph_to_unicode(char const *glyph) +wchar_t ps_glyph_to_unicode(glyph g) { - int i, j, k, c; - - i = -1; - j = lenof(ps_glyphs_alphabetic); - while (j-i > 1) { - k = (i + j) / 2; - c = strcmp(glyph, ps_glyphs_alphabetic[k]); - - if (c == 0) - return ps_codes_alphabetic[k]; - else if (c < 0) - j = k; - else - i = k; - } - - return 0xFFFF; /* illegal value means not found */ + if (g == NOGLYPH) return 0xFFFF; + return ps_codes_alphabetic[g]; } /* ---------------------------------------------------------------------- @@ -1803,23 +1820,27 @@ fonts="Times-Roman Times-Italic Times-Bold Times-BoldItalic \ for i in $fonts; do printf 'static const kern_pair %s_kerns[] = {\n' $(echo $i | tr 'A-Z\-' a-z_) perl -e ' -open G, "stdchars.txt" or die; -chomp(@g = ); %g = map(($_, $i++), @g); +open S, "stdchars.txt" or die; +chomp(@s = ); +open G, "glyphnames.txt" or die; +chomp(@g = ); %g = map(($_, $i++), @g); %g = map(($_, $g{$_}), @s); open M, "$ARGV[0].afm" or die; while () { /KPX (\S+) (\S+) (\S+)/ and exists $g{$1} and exists $g{$2} and print "{$g{$1},$g{$2},$3}, "; } print "\n"' $i |\ fold -sw 68 | sed 's/^/ /' - printf ' {0xFFFF,0xFFFF,0}\n};\n' + printf ' {NOGLYPH,NOGLYPH,0}\n};\n' printf 'static const ligature %s_ligs[] = {\n' $(echo $i | tr 'A-Z\-' a-z_) perl -e ' -open G, "stdchars.txt" or die; -chomp(@g = ); %g = map(($_, $i++), @g); +open S, "stdchars.txt" or die; +chomp(@s = ); +open G, "glyphnames.txt" or die; +chomp(@g = ); %g = map(($_, $i++), @g); %g = map(($_, $g{$_}), @s); open M, "$ARGV[0].afm" or die; while () { / N (\S+) / and $l = $1; while (/ L (\S+) (\S+) /g) { exists $g{$l} and exists $g{$1} and exists $g{$2} and print "{$g{$l},$g{$1},$g{$2}}, "; } } print "\n"' $i |\ fold -sw 68 | sed 's/^/ /' - printf ' {0xFFFF,0xFFFF,0xFFFF}\n};\n' + printf ' {NOGLYPH,NOGLYPH,NOGLYPH}\n};\n' done cat <fp = NULL; fi->name = ps_std_fonts[i].name; - fi->nglyphs = lenof(ps_std_glyphs) - 1; - fi->glyphs = ps_std_glyphs; - fi->widths = ps_std_fonts[i].widths; - fi->kerns = newtree234(kern_cmp); - for (kern = ps_std_fonts[i].kerns; kern->left != 0xFFFF; kern++) - add234(fi->kerns, (void *)kern); - fi->ligs = newtree234(lig_cmp); - for (lig = ps_std_fonts[i].ligs; lig->left != 0xFFFF; lig++) - add234(fi->ligs, (void *)lig); + fi->widths = newtree234(width_cmp); for (j = 0; j < (int)lenof(fi->bmp); j++) - fi->bmp[j] = 0xFFFF; - for (j = 0; j < fi->nglyphs; j++) { + fi->bmp[j] = NOGLYPH; + for (j = 0; j < (int)lenof(ps_std_glyphs) - 1; j++) { + glyph_width *w = snew(glyph_width); wchar_t ucs; - ucs = ps_glyph_to_unicode(fi->glyphs[j]); + w->glyph = glyph_intern(ps_std_glyphs[j]); + w->width = ps_std_fonts[i].widths[j]; + add234(fi->widths, w); + ucs = ps_glyph_to_unicode(w->glyph); assert(ucs != 0xFFFF); - fi->bmp[ucs] = j; + fi->bmp[ucs] = w->glyph; } + fi->kerns = newtree234(kern_cmp); + for (kern = ps_std_fonts[i].kerns; kern->left != NOGLYPH; kern++) + add234(fi->kerns, (void *)kern); + fi->ligs = newtree234(lig_cmp); + for (lig = ps_std_fonts[i].ligs; lig->left != NOGLYPH; lig++) + add234(fi->ligs, (void *)lig); fi->next = all_fonts; all_fonts = fi; }