From 30ca2bdcde0675a2d52a9decf9dce73e57fdcee1 Mon Sep 17 00:00:00 2001 From: Ben Harris Date: Sat, 6 Jan 2007 17:32:34 +0000 Subject: Overhaul of glyph-name handling in the paper backends. Before, we had a separate dense array of glyph names for each font, and referenced glyphs by indicies into that array, which meant that the array had to be set up before we could generate any indices. Now we have an overall array of glyph names, and use the same glyph indicies for all fonts. Some arrays have had to turn into tree234s as a result. [originally from svn r7061] --- psdata.c | 4390 +++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 2349 insertions(+), 2041 deletions(-) (limited to 'psdata.c') diff --git a/psdata.c b/psdata.c index e9cad9c..66354d3 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,12 @@ 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(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(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 */ + glyph g = glyph_intern(glyphname); + + if (g == NOGLYPH) return 0xFFFF; + return ps_codes_alphabetic[g]; } /* ---------------------------------------------------------------------- @@ -1803,23 +1822,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(ps_std_glyphs[j]); 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; } -- cgit v1.1