summaryrefslogtreecommitdiff
path: root/Build/source/texk/ttf2pt1/other
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
committerKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
commit487ca4806cc046076293cf6cc5fbba0db282bac7 (patch)
tree847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/ttf2pt1/other
parenta3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff)
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/ttf2pt1/other')
-rw-r--r--Build/source/texk/ttf2pt1/other/Makefile20
-rw-r--r--Build/source/texk/ttf2pt1/other/README.html176
-rw-r--r--Build/source/texk/ttf2pt1/other/bmpfont.h338
-rw-r--r--Build/source/texk/ttf2pt1/other/bz.c78
-rw-r--r--Build/source/texk/ttf2pt1/other/bzscreen.c220
-rw-r--r--Build/source/texk/ttf2pt1/other/bzscreen.h40
-rw-r--r--Build/source/texk/ttf2pt1/other/cmpf.c67
-rw-r--r--Build/source/texk/ttf2pt1/other/cntstems.pl50
-rw-r--r--Build/source/texk/ttf2pt1/other/dmpf.c53
-rw-r--r--Build/source/texk/ttf2pt1/other/lst.pl65
-rw-r--r--Build/source/texk/ttf2pt1/other/showdf58
-rw-r--r--Build/source/texk/ttf2pt1/other/showg633
12 files changed, 1798 insertions, 0 deletions
diff --git a/Build/source/texk/ttf2pt1/other/Makefile b/Build/source/texk/ttf2pt1/other/Makefile
new file mode 100644
index 00000000000..87d17a908b1
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/Makefile
@@ -0,0 +1,20 @@
+
+PROGS= bz cmpf dmpf
+
+BZOBJS= bz.o bzscreen.o
+
+CFLAGS= -g
+
+all: $(PROGS)
+
+clean:
+ rm -f $(PROGS) *.o *.core core.* core
+
+bz: $(BZOBJS)
+ $(CC) $(CFLAGS) -o bz $(BZOBJS)
+
+cmpf: cmpf.c bmpfont.h
+ $(CC) $(CFLAGS) -o cmpf -I/usr/local/include -L/usr/local/lib cmpf.c -lt1 -lm
+
+dmpf: dmpf.c bmpfont.h
+ $(CC) $(CFLAGS) -o dmpf -I/usr/local/include -L/usr/local/lib dmpf.c -lt1 -lm
diff --git a/Build/source/texk/ttf2pt1/other/README.html b/Build/source/texk/ttf2pt1/other/README.html
new file mode 100644
index 00000000000..794a947d9c6
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/README.html
@@ -0,0 +1,176 @@
+<HTML>
+<HEAD>
+<TITLE>
+Supplements for True Type to PostScript Type 1 Converter
+</TITLE>
+</HEAD>
+<BODY>
+<H2>
+Supplements for True Type to PostScript Type 1 Converter
+</H2>
+
+<!
+(Do not edit this file, it is generated from README.html!!!)
+>
+
+<h4><tt>bz</tt></h4>
+<!
+--
+>
+
+A small program to draw the Bezier curves on an alphanumeric display.
+The recommended way of uing it is to run it from xterm with "Tiny"
+(if you want higher magnification) or "Unreadable" (if you want
+higher resolution) font and as big window size as possible. The size
+of the window can be obtained by running "<tt>stty -a</tt>". For everything else
+just "Use the source, Luke!"
+<p>
+
+<h4><tt>cmpf</tt></h4>
+<!
+----
+>
+
+A small program to compare the rendering of two supposedly
+nearly-identical fonts at low resolutions. It requires the
+T1LIB library. This program may be used to compare the
+effect of various options of the converter on the resulting
+fonts. Create two <tt>.pfa</tt> files, one with one set of options,
+another with another set of options, then use this program
+to compare them.
+<p>
+
+<h4><tt>dmpf</tt></h4>
+<!
+----
+>
+
+A small program to dump the bitmaps of all glyphs of the font
+at low pixel sizes, up to 20 pixels. It requires the
+T1LIB library. This program may be used to compare the
+effect of changes in the T1LIB rasterizer and just for visual
+search for rendering anomalies.
+<p>
+
+<h4><tt>lst.pl</tt></h4>
+<!
+------
+>
+
+A simple PERL script that generates an HTML file
+with the full list of all characters in all
+possible styles of the Variable-width and Fixed-width
+fonts. This file is quite convenient to look
+at the converted fonts in Netscape (or other
+graphical browser).
+
+<h4><tt>cntstems.pl</tt></h4>
+<!
+------
+>
+
+A simple PERL script that counts the required hint stack in the
+interpreter to rasterize the glyphs of the font. May be quite
+useful in search for missing glyphs which may be aborted due to
+insufficient stack depth.
+
+<h4><tt>showg</tt></h4>
+<!
+-----
+>
+
+A PERL script that draws the glyphs and their interesting
+metrics (such as coordinates of the dots, hints and blue zones)
+in PostScript. It works only with un-encoded font files generated
+by <tt>ttf2pt1</tt>. The intended use is like:
+<p>
+
+&nbsp;&nbsp;<tt>showg [-c <i>&lt;fontfile.t1a&gt;</i>]... <i>&lt;fontfile.t1a&gt; &lt;glyph-to-draw&gt;</i>... &gt;file.ps</tt><br>
+&nbsp;&nbsp;<tt>gv file.ps # start the Ghostscript viewer</tt>
+<p>
+
+As you can see, multiple glyphs may be specified. The glyphs may be
+specified in one of three ways:
+<br>
+&nbsp;&nbsp;- as a decimal code (for example, <tt>43</tt> )
+<br>
+&nbsp;&nbsp;- as a glyph name preceded by a slash (for example, <tt>/plus</tt> )
+<br>
+&nbsp;&nbsp;- as a literal character preceded by a dot (for example, <tt>.+</tt> )
+<p>
+
+So for example the following command would draw the same glyph "left
+parenthesis" three times:
+<p>
+
+&nbsp;&nbsp;<tt>showg file.t1a 40 /parenleft .\( >/file.ps</tt>
+<p>
+
+Don't forget that some characters have to be protected from the shell
+by backslash as shown above, or else the shell would try to interpret
+them before passing to the program.
+<p>
+
+One file (given as the first argument) is considered the main file
+but multiple files can be specified with option <b>-c</b> for visual comparison
+of the outlines. The glyphs from the main file are drawn in black
+and supplemented with coordinate grid and sidebars for hints. The
+glyphs from the comparison files are drawn in slightly lighter colors
+(red, cyan, brown) and no supplemental information is provided for them.
+Each use of option <b>-c</b> adds one comparison file, this option may be used
+multiple times. If there are more than 3 comparison files the colors
+repeat cyclically.
+<p>
+
+So for example the following command would draw the same glyph "left
+parenthesis" from three files on the same page:
+<p>
+
+&nbsp;&nbsp;<tt>showg -c fileA.t1a -c fileB.t1a file.t1a .\( >/file.ps</tt>
+<p>
+
+This program is quite valuable it you want to take a close-up view at
+the font.
+<p>
+
+The outlines are drawn in black, the ends of the curves and
+lines are marked as dots, the first dots of the outlines
+are fatter. The Blue Zones are drawn in light blue. The
+substituted hints are marked in red, the global hints are
+marked in blue. The coordinate grid is drawn in green.
+The stems and the values of coordinates are for convenience
+marked twice, on each size of the picture.
+<p>
+
+<h4><tt>showdf</tt></h4>
+<!
+------
+>
+
+A Perl script to find a list of differing glyphs in two versions of a font
+file (for example, converted with different versions of <tt>ttf2pt1</tt> or
+with different options given to ttf2pt1) and feed this list into the <tt>showg</tt>
+program for display. The intended use is like:
+<p>
+
+&nbsp;&nbsp;<tt>showdf <i>&lt;showg-location&gt;</i> <i>&lt;fontfile1.t1a&gt;</i> <i>&lt;fontfile2.t1a&gt;</i> &gt;file.ps</tt><br>
+&nbsp;&nbsp;<tt>gv file.ps # start the Ghostscript viewer</tt>
+<p>
+
+If both <tt>showdf</tt> and <tt>showg</tt> scripts are located in the
+same directory, the command would look like:
+<p>
+
+&nbsp;&nbsp;<tt>./showdf ./showg font1.t1a font2.t1a &gt;file.ps</tt><br>
+<p>
+
+For decent results both font files should be converted from the same original
+font and contain the same glyphs with the same names in the same order.
+Otherwise most probably all the glyphs will be included, or a failure may
+happen if some glyph is not found in one of the files. It is also a good
+idea to convert the fonts for comparison with hinting disabled, otherwise
+the differences in hinting may trigger the otherwise equal glyphs to be shown.
+<p>
+
+</BODY>
+</HTML>
diff --git a/Build/source/texk/ttf2pt1/other/bmpfont.h b/Build/source/texk/ttf2pt1/other/bmpfont.h
new file mode 100644
index 00000000000..59c27372a4d
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/bmpfont.h
@@ -0,0 +1,338 @@
+/*
+ * see COPYRIGHT
+ */
+
+
+fchkneg(file, line, rc, cmd)
+ char *file;
+ int line;
+ int rc;
+ char *cmd;
+{
+ if(rc<0) {
+ fprintf(stderr,"%s: fatal error on line %d of %s: %d\n",
+ PROGNAME, line, file, rc);
+ fprintf(stderr,"%s\n", cmd);
+ exit(1);
+ }
+}
+
+fchknull(file, line, rc, cmd)
+ char *file;
+ int line;
+ void *rc;
+ char *cmd;
+{
+ if(rc==NULL) {
+ fprintf(stderr,"%s: fatal error on line %d of %s: NULL\n",
+ PROGNAME, line, file);
+ fprintf(stderr,"%s\n", cmd);
+ exit(1);
+ }
+}
+
+#define chkneg(f) fchkneg(__FILE__,__LINE__,(f),#f)
+#define chknull(f) fchknull(__FILE__,__LINE__,(f),#f)
+
+#define MYPAD 8
+
+#define CHRNONE ' '
+#define CHRBOTH '.'
+#define CHRONE '1'
+#define CHRTWO '2'
+
+#define MINSIZE 8
+#define MAXSIZE 20
+
+#define LINEWIDTH 80 /* screen line width in chars */
+#define MAXLINES (MAXSIZE*(MAXSIZE-MINSIZE+1))
+
+static char map[MAXLINES][LINEWIDTH+1];
+static char mbase, mx, mend;
+
+/* returns 0 if the same, -1 if different */
+
+int
+cmpglyphs(g1, g2)
+ GLYPH *g1, *g2;
+{
+ int wd1, wd2;
+ int ht1, ht2;
+ int i, j;
+ char *p1, *p2;
+
+ wd1=g1->metrics.rightSideBearing - g1->metrics.leftSideBearing;
+ ht1=g1->metrics.ascent - g1->metrics.descent;
+ wd2=g2->metrics.rightSideBearing - g2->metrics.leftSideBearing;
+ ht2=g2->metrics.ascent - g2->metrics.descent;
+
+ if(g1->bits==NULL && g2->bits!=NULL
+ || g1->bits!=NULL && g2->bits==NULL)
+ return -1;
+
+ if(g1->metrics.ascent != g2->metrics.ascent)
+ return -1;
+
+ if(g1->metrics.descent != g2->metrics.descent)
+ return -1;
+
+ if( wd1 != wd2 )
+ return -1;
+
+ if( (p1=g1->bits) !=NULL && (p2=g2->bits) !=NULL )
+ for(i=0; i<ht1; i++) {
+ for(j=0; j<wd1; j+=8) {
+ if( *p1++ != *p2++)
+ return -1;
+ }
+ }
+ return 0;
+}
+
+void
+resetmap()
+{
+ int i, j;
+
+ for(i=0; i<MAXLINES; i++)
+ for(j=0; j<LINEWIDTH; j++)
+ map[i][j]=' ';
+ mbase=mx=mend=0;
+}
+
+void
+drawdot(row, col, val)
+ unsigned row, col, val;
+{
+ if(row < MAXLINES && col < LINEWIDTH-1) {
+ map[row][col]=val;
+ if(row > mend)
+ mend=row;
+ }
+}
+
+void
+drawdotg1(row, col, val)
+ unsigned row, col, val;
+{
+ if(row < MAXLINES && col < LINEWIDTH-1) {
+ if(val)
+ map[row][col]=CHRONE;
+ else
+ map[row][col]=CHRNONE;
+ if(row > mend)
+ mend=row;
+ }
+}
+
+void
+drawdotg2(row, col, val)
+ unsigned row, col, val;
+{
+ if(row < MAXLINES && col < LINEWIDTH-1) {
+ if(val)
+ if(map[row][col]==CHRONE)
+ map[row][col]=CHRBOTH;
+ else
+ map[row][col]=CHRTWO;
+ else if(map[row][col]!=CHRONE)
+ map[row][col]=CHRNONE;
+ if(row > mend)
+ mend=row;
+ }
+}
+
+void
+drawglyf(size, g1)
+ int size;
+ GLYPH *g1;
+{
+ int wd1, wd2, wdm;
+ int ht1, ht2, ascm, desm;
+ int i, j, k, val;
+ char *p;
+ int off1, off2;
+
+ wd1=g1->metrics.rightSideBearing - g1->metrics.leftSideBearing;
+ ht1=g1->metrics.ascent - g1->metrics.descent;
+
+ wdm=wd1;
+
+ ascm=g1->metrics.ascent;
+ desm= -g1->metrics.descent;
+
+ if(mbase==0)
+ mbase=ascm+1;
+ else if(LINEWIDTH-mx <= wdm+1) {
+ mx=0; mbase=mend+ascm+2;
+ }
+
+ drawdot(mbase-ascm-1, mx, (size/10)%10+'0');
+ drawdot(mbase-ascm-1, mx+1, size%10+'0');
+
+ if( (p=g1->bits) !=NULL)
+ for(i=0; i<ht1; i++) {
+ for(j=0; j<wd1; j+=8) {
+ val = *p++;
+ for(k=0; k<8 && j+k<wd1; k++, val>>=1)
+ drawdot(i+mbase-g1->metrics.ascent, mx+j+k, (val&1)?CHRBOTH:CHRNONE);
+ }
+ }
+
+ wdm++;
+ if(wdm<3)
+ wdm=3;
+ mx+=wdm;
+ drawdot(mbase, mx-1, '-');
+}
+
+void
+drawdiff(size, g1, g2)
+ int size;
+ GLYPH *g1, *g2;
+{
+ int wd1, wd2, wdm;
+ int ht1, ht2, ascm, desm;
+ int i, j, k, val;
+ char *p;
+ int off1, off2;
+
+ wd1=g1->metrics.rightSideBearing - g1->metrics.leftSideBearing;
+ ht1=g1->metrics.ascent - g1->metrics.descent;
+ wd2=g2->metrics.rightSideBearing - g2->metrics.leftSideBearing;
+ ht2=g2->metrics.ascent - g2->metrics.descent;
+
+ if(wd1>wd2) {
+ wdm=wd1;
+ off1=0; off2=wd1-wd2;
+ } else {
+ wdm=wd2;
+ off2=0; off1=wd2-wd1;
+ }
+
+ if(g1->metrics.ascent > g2->metrics.ascent)
+ ascm=g1->metrics.ascent;
+ else
+ ascm=g2->metrics.ascent;
+
+ if(g1->metrics.descent < g2->metrics.descent)
+ desm= -g1->metrics.descent;
+ else
+ desm= -g2->metrics.descent;
+
+ if(mbase==0)
+ mbase=ascm+1;
+ else if(LINEWIDTH-mx <= wdm+1) {
+ mx=0; mbase=mend+ascm+2;
+ }
+
+ drawdot(mbase-ascm-1, mx, (size/10)%10+'0');
+ drawdot(mbase-ascm-1, mx+1, size%10+'0');
+
+ /* check which alignment is better */
+ if(off1!=0 || off2!=0) {
+ int cntl,cntr;
+ int a1, a2, d1, d2;
+ int val1, val2;
+ int rstep1, rstep2;
+
+ cntl=cntr=0;
+ rstep1=(wd1+7)/8;
+ rstep2=(wd2+7)/8;
+ a1=g1->metrics.ascent;
+ d1=g1->metrics.descent;
+ a2=g2->metrics.ascent;
+ d2=g2->metrics.descent;
+
+#ifdef dbgoff
+ printf("size: %d\n", size);
+#endif
+ for(i=ascm; i>= -desm; i--) {
+ for(j=0; j<wdm; j++) {
+ /* first the left alignment */
+ if(i>a1 || i<d1 || j>=wd1)
+ val1=0;
+ else
+ val1=( g1->bits[ (a1-i)*rstep1+j/8 ] >> (j%8) ) & 1;
+ if(i>a2 || i<d2 || j>=wd2)
+ val2=0;
+ else
+ val2=( g2->bits[ (a2-i)*rstep2+j/8 ] >> (j%8) ) & 1;
+
+ cntl += (val1 ^ val2);
+
+#ifdef dbgoff
+ putchar(val1?'1':' ');
+ putchar(val2?'2':' ');
+ putchar('.');
+#endif
+
+ /* now the right alignment */
+ if(i>a1 || i<d1 || j-off1>=wd1 || j<off1)
+ val1=0;
+ else
+ val1=( g1->bits[ (a1-i)*rstep1+(j-off1)/8 ] >> ((j-off1)%8) ) & 1;
+ if(i>a2 || i<d2 || j-off2>=wd2)
+ val2=0;
+ else
+ val2=( g2->bits[ (a2-i)*rstep2+(j-off2)/8 ] >> ((j-off2)%8) ) & 1;
+
+ cntr += (val1 ^ val2);
+
+#ifdef dbgoff
+ putchar(val1?'1':' ');
+ putchar(val2?'2':' ');
+ putchar('|');
+#endif
+ }
+#ifdef dbgoff
+ putchar('\n');
+#endif
+ }
+
+#ifdef dbgoff
+ printf("size %d: left %d right %d\n",size, cntl, cntr);
+#endif
+ if(cntl <= cntr) /* left is better or the same */
+ off1=off2=0;
+ }
+
+ if( (p=g1->bits) !=NULL)
+ for(i=0; i<ht1; i++) {
+ for(j=0; j<wd1; j+=8) {
+ val = *p++;
+ for(k=0; k<8 && j+k<wd1; k++, val>>=1)
+ drawdotg1(i+mbase-g1->metrics.ascent, mx+j+k+off1, val&1);
+ }
+ }
+ if( (p=g2->bits) !=NULL)
+ for(i=0; i<ht2; i++) {
+ for(j=0; j<wd2; j+=8) {
+ val = *p++;
+ for(k=0; k<8 && j+k<wd2; k++, val>>=1)
+ drawdotg2(i+mbase-g2->metrics.ascent, mx+j+k+off2, val&1);
+ }
+ }
+
+ wdm++;
+ if(wdm<3)
+ wdm=3;
+ mx+=wdm;
+ drawdot(mbase, mx-1, '-');
+}
+
+void
+printmap(f)
+ FILE *f;
+{
+ int i, j;
+
+ for(i=0; i<=mend; i++) {
+ for(j=LINEWIDTH-1; j>=0 && map[i][j]==' '; j--)
+ {}
+ map[i][j+1]='\n';
+ map[i][j+2]=0;
+ fputs(map[i], f);
+ }
+}
+
diff --git a/Build/source/texk/ttf2pt1/other/bz.c b/Build/source/texk/ttf2pt1/other/bz.c
new file mode 100644
index 00000000000..475d13fa47c
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/bz.c
@@ -0,0 +1,78 @@
+/*
+ * see COPYRIGHT
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "bzscreen.h"
+
+/* size of the screen in "physical pixels" */
+#define PHYSX 980
+#define PHYSY 310
+
+/* the bounding box of the drawing in "logical pixels" */
+/* the base point - set to 0, 0 for absolute coordinates */
+#define BASEX 19
+#define BASEY 122
+/* the maximal point */
+#define MAXX 450
+#define MAXY 481
+
+main(argc,argv)
+ int argc;
+ char **argv;
+{
+ initscreen(PHYSX, PHYSY, PHYSX, PHYSY, 0, 0, BASEX, BASEY, MAXX, MAXY);
+
+ /*
+ drawcurve('#', 0,0, 51,0, 1,49, 45,98);
+ drawcurve('1', 5,28, 8,37, 16,65, 45,98);
+
+ drawcurve('3', 0,0, 0,24, 30,68, 80,72);
+
+ drawcurve('1', 0,0, 0,5, 1,10, 2,15);
+ drawcurve('2', 2,15, 8,42, 30,68, 80,72);
+
+ drawcurve('4', 0,0, 0,37, 22,67, 80,72);
+ */
+
+ /* final */
+ /*
+ drawcurve('#', 324, 481, 390, 481, 448, 475, 448, 404 );
+ drawcurve('#', 448, 404, 448, 404, 448, 324, 448, 324 );
+ drawcurve('#', 448, 324, 402, 245, 19, 338, 19, 122 );
+ */
+
+ /* 3 */
+ /*
+ */
+ drawcurve('*', 450, 404, 450, 397, 450, 390, 448, 384 );
+
+ drawcurve('*', 448, 384, 446, 378, 444, 370, 443, 360 );
+ drawcurve('.', 443, 360, 309, 356, 206, 341, 132, 304 );
+ drawcurve('.', 132, 304, 57, 266, 19, 208, 19, 122 );
+
+ /* 4 */
+ drawcurve('#', 324, 481, 390, 481, 450, 475, 450, 404 );
+ drawcurve('#', 450, 404, 450, 397, 450, 390, 448, 384 );
+
+ drawcurve('#', 448, 384, 402, 245, 19, 338, 19, 122 );
+
+ /*
+ drawcurve('.', 324, 481, 361, 481, 391, 478, 414, 466 );
+ drawcurve('.', 414, 466, 436, 454, 450, 436, 450, 404 );
+
+ drawcurve('.', 450, 404, 450, 390, 447, 378, 443, 360 );
+ drawcurve('.', 443, 360, 309, 356, 206, 341, 132, 304 );
+
+ drawcurve('.', 132, 304, 57, 266, 19, 208, 19, 122 );
+ */
+
+ printscreen(stdout);
+}
+
+sumcurves(dx11, dy11, dx12, dy12, dx13, dy13,
+ dx21, dy21, dx22, dy22, dx23, dy23)
+{
+}
+
diff --git a/Build/source/texk/ttf2pt1/other/bzscreen.c b/Build/source/texk/ttf2pt1/other/bzscreen.c
new file mode 100644
index 00000000000..0bb5ab6a335
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/bzscreen.c
@@ -0,0 +1,220 @@
+/*
+ * see COPYRIGHT
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "bzscreen.h"
+
+/*
+ * functions to draw the bezier curves in text mode
+ */
+
+double
+fmin(a,b)
+ double a, b;
+{
+ if(a<b)
+ return a;
+ else
+ return b;
+}
+
+int
+abs(x)
+ int x;
+{
+ if(x<0)
+ return -x;
+ else
+ return x;
+}
+
+void
+initscreen(physx, physy, cols, rows, xoff, yoff, minx, miny, maxx, maxy)
+ unsigned physx, physy, cols, rows, xoff, yoff, minx, miny, maxx, maxy;
+{
+ int i,j;
+ double yxscale;
+
+ if(screen.dots != NULL)
+ free(screen.dots);
+
+ if(physx==0 || physy==0 || rows==0 || cols==0) {
+ fprintf(stderr, "*** negative or zero screen size\n");
+ exit(1);
+ }
+
+ if(physx+xoff > cols || physy+yoff > rows) {
+ fprintf(stderr, "*** drawable area out of screen\n");
+ exit(1);
+ }
+
+ if(minx>maxx || miny>maxy) {
+ fprintf(stderr, "*** empty drawable area\n");
+ exit(1);
+ }
+
+ screen.physx = physx;
+ screen.physy = physy;
+ screen.rows = rows;
+ screen.cols = cols+2; /* for '\n\0' */
+ screen.xoff = xoff;
+ screen.yoff = yoff;
+ screen.minx = minx;
+ screen.miny = miny;
+
+ if(( screen.dots=malloc(screen.rows*screen.cols) )==NULL) {
+ perror("*** no memory for screen: ");
+ exit(1);
+ }
+
+ j=screen.rows*screen.cols;
+ for(i=0; i<j; i++)
+ screen.dots[i]=' ';
+
+ /* scale of Y to X on the screen, i.e. x=YXSCALE*y */
+ /* 3/4 is the approx. ratio of Y/X sizes of the physical screen */
+ yxscale = ((double)physx/(double)physy*3.0/4.0);
+
+ /* scale of "logical" to "physical", i.e. physical=PHYSSCALE*logical */
+ screen.yscale = fmin( ((double)physy-0.51)/(maxy+1-miny),
+ ((double)physx-0.51)/yxscale/(maxx+1-minx) );
+ screen.xscale = yxscale * screen.yscale;
+}
+
+void
+drawcurve(mark, ax,ay, bx,by, cx,cy, dx,dy)
+ int mark, ax,ay, bx,by, cx,cy, dx,dy;
+{
+ int i,j,n,c;
+ int maxn=(screen.physx + screen.physy)*2;
+
+ ax-=screen.minx; bx-=screen.minx; cx-=screen.minx; dx-=screen.minx;
+ ay-=screen.miny; by-=screen.miny; cy-=screen.miny; dy-=screen.miny;
+
+ for(i=0; i<=maxn; i++) {
+ double t, t2, t3, nt, nt2, nt3;
+
+ t=(double)i/(double)maxn; t2=t*t; t3=t2*t;
+ nt=1-t; nt2=nt*nt; nt3=nt2*nt;
+
+ setfdot(
+ mark,
+ ( ax*t3 + bx*3*t2*nt + cx*3*t*nt2 + dx*nt3 ),
+ ( ay*t3 + by*3*t2*nt + cy*3*t*nt2 + dy*nt3 )
+ );
+ }
+}
+
+/* draw curve and mark direction at the ends */
+
+void
+drawcurvedir(mark, ax,ay, bx,by, cx,cy, dx,dy)
+ int mark, ax,ay, bx,by, cx,cy, dx,dy;
+{
+ int i,j,n,c;
+ int maxn=(screen.physx + screen.physy)*2;
+ double t, t2, t3, nt, nt2, nt3;
+ int markb, marke;
+
+ ax-=screen.minx; bx-=screen.minx; cx-=screen.minx; dx-=screen.minx;
+ ay-=screen.miny; by-=screen.miny; cy-=screen.miny; dy-=screen.miny;
+
+ if(bx==ax && by==ay) {
+ markb=mark;
+ } else if( abs(by-ay) > abs(bx-ax) ) {
+ if(by>ay)
+ markb='^';
+ else
+ markb='v';
+ } else {
+ if(bx>ax)
+ markb='>';
+ else
+ markb='<';
+ }
+
+ if(dx==cx && dy==cy) {
+ marke=mark;
+ } else if( abs(dy-cy) > abs(dx-cx) ) {
+ if(dy>cy)
+ marke='^';
+ else
+ marke='v';
+ } else {
+ if(dx>cx)
+ marke='>';
+ else
+ marke='<';
+ }
+
+ for(i=1; i<maxn; i++) {
+ t=(double)i/(double)maxn; t2=t*t; t3=t2*t;
+ nt=1-t; nt2=nt*nt; nt3=nt2*nt;
+
+ setfdot(
+ mark,
+ ( ax*t3 + bx*3*t2*nt + cx*3*t*nt2 + dx*nt3 ),
+ ( ay*t3 + by*3*t2*nt + cy*3*t*nt2 + dy*nt3 )
+ );
+ }
+ /* mark the ends */
+ setfdot( markb, (double)ax, (double)ay );
+ setfdot( marke, (double)dx, (double)dy );
+}
+
+void
+drawdot(mark, x, y)
+ int mark;
+ int x, y;
+{
+ x=(int)((x-screen.minx)*screen.xscale+0.5);
+ y=(int)((y-screen.miny)*screen.yscale+0.5);
+
+ if(y<0 || y>=screen.physy || x<0 || x>=screen.physx)
+ return;
+ screendot(x,y)=mark;
+}
+
+void
+setabsdot(mark, x, y)
+ int x, y, mark;
+{
+ if(y<0 || y>=screen.rows || x<0 || x>=screen.cols-2)
+ return;
+ screenabsdot(x,y)=mark;
+}
+
+void
+setfdot(mark, fx, fy)
+ int mark;
+ double fx, fy;
+{
+ int x, y;
+
+ x=(int)(fx*screen.xscale+0.5);
+ y=(int)(fy*screen.yscale+0.5);
+
+ if(y<0 || y>=screen.physy || x<0 || x>=screen.physx)
+ return;
+ screendot(x,y)=mark;
+}
+
+/* destructive */
+void
+printscreen(f)
+ FILE *f;
+{
+ int r;
+ char *pi, *pc;
+
+ for(r=screen.rows-1; r>=0; r--) {
+ pc=&screenabsdot(0,r);
+ for(pi=&screenabsdot(-2,r+1); pi>=pc && *pi == ' '; pi--)
+ {}
+ pi[1]='\n';
+ pi[2]=0;
+ fputs(pc, f);
+ }
+}
diff --git a/Build/source/texk/ttf2pt1/other/bzscreen.h b/Build/source/texk/ttf2pt1/other/bzscreen.h
new file mode 100644
index 00000000000..290d5195aac
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/bzscreen.h
@@ -0,0 +1,40 @@
+/*
+ * see COPYRIGHT
+ */
+
+
+/*
+ * Screen for drawing the Bezier curves in text mode
+ */
+
+struct screen {
+ unsigned physx;
+ unsigned physy;
+ unsigned cols;
+ unsigned rows;
+ unsigned xoff;
+ unsigned yoff;
+ unsigned minx;
+ unsigned miny;
+ char *dots;
+ double xscale;
+ double yscale;
+} screen;
+
+#define screenabsdot(x,y) (screen.dots[(y)*screen.cols+(x)])
+#define screendot(x,y) screenabsdot((x)+screen.xoff, (y)+screen.yoff)
+
+/* prototypes */
+double fmin(double a, double b);
+int abs(int x);
+void initscreen(unsigned physx, unsigned physy,
+ unsigned cols, unsigned rows, unsigned xoff, unsigned yoff,
+ unsigned minx, unsigned miny, unsigned maxx, unsigned maxy);
+void drawcurve(int mark, int ax,int ay,
+ int bx,int by, int cx,int cy, int dx,int dy);
+void drawcurvedir(int mark, int ax,int ay,
+ int bx,int by, int cx,int cy, int dx,int dy);
+void drawdot(int mark, int x, int y);
+void setabsdot(int mark, int x, int y);
+void setfdot(int mark, double x, double y);
+void printscreen(FILE *f);
diff --git a/Build/source/texk/ttf2pt1/other/cmpf.c b/Build/source/texk/ttf2pt1/other/cmpf.c
new file mode 100644
index 00000000000..37e6e98f0c0
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/cmpf.c
@@ -0,0 +1,67 @@
+/*
+ * see COPYRIGHT
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "t1lib.h"
+
+/*
+ * compare two [ almost the same ] fonts
+ */
+
+#define PROGNAME "cmpf"
+
+#include "bmpfont.h"
+
+
+main(ac, av)
+ int ac;
+ char **av;
+{
+ int fontid1, fontid2;
+ GLYPH *g1, *g2;
+ int chr, size, diff, offset;
+
+ if(ac!=3) {
+ fprintf(stderr,"Use: %s font1 font2\n", PROGNAME);
+ exit(1);
+ }
+
+ chkneg(T1_SetBitmapPad(MYPAD));
+ chkneg(T1_InitLib(NO_LOGFILE|IGNORE_CONFIGFILE|IGNORE_FONTDATABASE));
+ chkneg(fontid1=T1_AddFont(av[1]));
+ chkneg(fontid2=T1_AddFont(av[2]));
+
+
+ resetmap();
+ for(chr=0; chr<256; chr++) {
+ diff=0;
+ for(size=MAXSIZE; size>=MINSIZE; size--) {
+ chknull( g1=T1_CopyGlyph(T1_SetChar( fontid1, chr, (float)size, NULL)) );
+ chknull( g2=T1_CopyGlyph(T1_SetChar( fontid2, chr, (float)size, NULL)) );
+
+ if( cmpglyphs(g1, g2) ) {
+ /* printf("%d %d - diff\n", chr, size); */
+ diff=1;
+ drawdiff(size, g1, g2);
+ }
+ /*
+ else
+ fprintf(stderr, "%d %d - same\n", chr, size);
+ */
+
+ chkneg(T1_FreeGlyph(g1));
+ chkneg(T1_FreeGlyph(g2));
+ }
+ if(diff) {
+ printf("*** Difference for %d==0x%x %c\n", chr, chr,
+ isprint(chr) ? chr : ' ');
+ printmap(stdout);
+ diff=0;
+ resetmap();
+ }
+ }
+
+ printf("All done!\n");
+}
diff --git a/Build/source/texk/ttf2pt1/other/cntstems.pl b/Build/source/texk/ttf2pt1/other/cntstems.pl
new file mode 100644
index 00000000000..185c06c4fde
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/cntstems.pl
@@ -0,0 +1,50 @@
+#!/usr/bin/perl
+#
+# Copyright (c) 2000 by Sergey Babkin
+# (see COPYRIGHT for full copyright notice)
+#
+# script to calculate the total number of stems used by the
+# glyphs in case if stems are always pushed to the stack and
+# never popped (as X11 does)
+
+$insubrs = 0;
+$inchars = 0;
+
+while(<>)
+{
+ if(/\/Subrs/) {
+ $insubrs = 1;
+ } elsif(/\/CharStrings/) {
+ $insubrs = 0;
+ $inchars = 1;
+ }
+ if($insubrs && /^dup (\d+)/) {
+ $cursubr = $1;
+ $substems[$cursubr] = 0;
+ } elsif (/^dup (\d+) \/(\S+) put/) {
+ $codeof{$2} = $1;
+ }
+ if($inchars) {
+ if(/^\/(\S+)\s+\{/) {
+ $curchar = $1;
+ $charstems = 0;
+ } elsif( /endchar/ ) {
+ printf("%d:%s\t%d\n", $codeof{$curchar}, $curchar, $charstems);
+ } elsif( /(\d+)\s+4\s+callsubr/) {
+ $charstems += $substems[$1+0];
+ }
+ }
+ if(/[hv]stem3/) {
+ if($insubrs) {
+ $substems[$cursubr] += 3;
+ } elsif($inchars) {
+ $charstems += 3;
+ }
+ } elsif( /[hv]stem/ ) {
+ if($insubrs) {
+ $substems[$cursubr]++;
+ } elsif($inchars) {
+ $charstems++;
+ }
+ }
+}
diff --git a/Build/source/texk/ttf2pt1/other/dmpf.c b/Build/source/texk/ttf2pt1/other/dmpf.c
new file mode 100644
index 00000000000..1052a448721
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/dmpf.c
@@ -0,0 +1,53 @@
+/*
+ * see COPYRIGHT
+ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include "t1lib.h"
+
+/*
+ * Dump a rasterizarion of the font at small size
+ */
+
+#define PROGNAME "dmpf"
+
+#include "bmpfont.h"
+
+
+main(ac, av)
+ int ac;
+ char **av;
+{
+ int fontid1, fontid2;
+ GLYPH *g1, *g2;
+ int chr, size, diff, offset;
+
+ if(ac!=2) {
+ fprintf(stderr,"Use: %s font\n", PROGNAME);
+ exit(1);
+ }
+
+ chkneg(T1_SetBitmapPad(MYPAD));
+ chkneg(T1_InitLib(NO_LOGFILE|IGNORE_CONFIGFILE|IGNORE_FONTDATABASE));
+ chkneg(fontid1=T1_AddFont(av[1]));
+
+
+ resetmap();
+ for(chr=0; chr<256; chr++) {
+ for(size=MAXSIZE; size>=MINSIZE; size--) {
+ chknull( g1=T1_CopyGlyph(T1_SetChar( fontid1, chr, (float)size, NULL)) );
+
+ drawglyf(size, g1);
+
+ chkneg(T1_FreeGlyph(g1));
+ }
+
+ printf("*** Glyph %d==0x%x %c\n", chr, chr,
+ isprint(chr) ? chr : ' ');
+ printmap(stdout);
+ resetmap();
+ }
+
+ printf("All done!\n");
+}
diff --git a/Build/source/texk/ttf2pt1/other/lst.pl b/Build/source/texk/ttf2pt1/other/lst.pl
new file mode 100644
index 00000000000..b5840b275b0
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/lst.pl
@@ -0,0 +1,65 @@
+#!/usr/bin/perl
+#
+# script to create HTML file with character table
+# in plain, italic, bold, bold-italic
+#
+# see COPYRIGHT
+#
+
+# width of tables
+$step=16;
+
+# commands to enable and disable the font modes
+# (the fastest changing is first)
+@matrix = (
+ [ "Roman", "Italic", "</i>", "<i>" ],
+ [ "Medium", "Bold", "</b>", "<b>" ],
+ [ "Variable", "Fixed", "</tt>", "<tt>" ],
+);
+
+sub printall
+{
+ local $i, $j;
+
+ printf("<table border=\"0\" >\n");
+ for($j=32; $j<256; $j+=$step) {
+ printf("<tr>\n");
+ for $i ($j..$j+$step-1) {
+ $c=chr($i);
+ if($c eq "<") {
+ $c="&lt;";
+ } elsif($c eq ">") {
+ $c="&gt;";
+ }
+ printf("<td><font color=\"gray\">%03d</font></td><td>\n", $i);
+ printf("<font color=\"white\">%s%s%s</font>\n", $enmode, $c, $dismode);
+ printf("</td>\n");
+ }
+ printf("</tr>\n");
+ }
+ printf("</table><p>\n");
+}
+
+printf("<HTML><HEAD></HEAD><BODY bgcolor=\"black\">\n<font color=\"white\"><p>\n");
+
+for $mask (0.. (1<<@matrix)-1) {
+ #printf("<table><tr>");
+ $mode = $enmode = $dismode = "";
+ for $bit (0.. $#matrix) {
+ $val = ($mask >> $bit) & 1;
+ $mode = $matrix[$bit]->[$val] . "<br>" . $mode;
+ if( $val ) {
+ $enmode = $matrix[$bit]->[3] . $enmode;
+ $dismode = $dismode . $matrix[$bit]->[2];
+ }
+ #printf("=== %d %s %s %s\n", $val, $mode, $enmode, $dismode);
+ }
+ #printf("%x %s %s %s\n", $mask, $mode, $enmode, $dismode);
+ printf("<table border=\"0\"><tr><td>\n");
+ &printall();
+ printf("</td><td valign=top><font size=\"+1\" color=\"yellow\"><b>\n");
+ printf("%s\n", $mode);
+ printf("</b></font></td></tr></table>\n");
+}
+
+printf("</font></BODY></HTML>\n");
diff --git a/Build/source/texk/ttf2pt1/other/showdf b/Build/source/texk/ttf2pt1/other/showdf
new file mode 100644
index 00000000000..1706a81454d
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/showdf
@@ -0,0 +1,58 @@
+#!/usr/bin/perl
+
+if (@ARGV != 3) {
+ print STDERR "Use:\n";
+ print STDERR " showdf <showg-script> <old-file> <new-file>\n";
+ print STDERR "to create a showg diagram of glyphs differing in two files\n";
+ exit 1;
+}
+
+$cmd = shift @ARGV;
+$oldf = shift @ARGV;
+$newf = shift @ARGV;
+
+open(O, "<$oldf") or die "Unable to open '$oldf'\n";
+open(N, "<$newf") or die "Unable to open '$newf'\n";
+
+while(<O>) {
+ last if(/CharStrings/);
+}
+while(<N>) {
+ last if(/CharStrings/);
+}
+
+undef @symlist;
+$sym = '';
+$inlist = 0;
+$nstop = 0;
+
+while($so = <O>) {
+ if($so =~ m|^(/\S+)\s+\{|) {
+ $sym = $1;
+ $inlist = 0;
+ #printf STDERR "found sym $sym\n";
+ if (!$nstop || $sn !~ m|^$sym\s+\{|) {
+ while($sn = <N>) {
+ #print STDERR "+$sn";
+ last if($sn =~ m|^${sym}\s+\{|);
+ }
+ }
+ $nstop = 0;
+ } elsif(!$nstop) {
+ $sn = <N>;
+ #print STDERR "<$so>$sn\n";
+ if($so ne $sn) {
+ if(!$inlist) {
+ $inlist = 1;
+ push(@symlist, $sym);
+ }
+ if($sn =~ m|^(/\S+)\s+\{|) {
+ $nstop = 1;
+ #printf STDERR "stop at $1\n";
+ }
+ }
+ }
+}
+unshift(@symlist, $cmd, '-c', $oldf, $newf);
+#printf("%s\n", join(' ', @symlist));
+exec @symlist;
diff --git a/Build/source/texk/ttf2pt1/other/showg b/Build/source/texk/ttf2pt1/other/showg
new file mode 100644
index 00000000000..437860d4c2c
--- /dev/null
+++ b/Build/source/texk/ttf2pt1/other/showg
@@ -0,0 +1,633 @@
+#!/usr/bin/perl
+
+my @cmpfiles;
+
+while($ARGV[0] eq "-c") {
+ shift(@ARGV);
+ push(@cmpfiles, shift(@ARGV));
+}
+
+if( $#ARGV < 1) {
+ die("Usage: $0 [-c file]... file glyph-code...\n");
+}
+
+$fname=shift @ARGV;
+
+# storage for files
+my %fontname;
+my %fbbox;
+my %fblues;
+my %fenc;
+my %frevenc;
+my %fsubrs;
+my %fchars;
+my @cmnbbox; # common bounding box covering all files
+
+@cmnbbox = (100, 100, 100, 100);
+
+# read all files into memory
+for $f (@cmpfiles, $fname) {
+ open(FILE, "<$f") or die("no such file $f");
+ while(<FILE>) {
+ if(/FontBBox\s+\{\s*(.*)\s*}/) {
+ @bbox=split(/\s+/, $1);
+ push(@{$fbbox{$f}}, @bbox);
+ if($bbox[0] < $cmnbbox[0]) {
+ $cmnbbox[0] = $bbox[0];
+ }
+ if($bbox[1] < $cmnbbox[1]) {
+ $cmnbbox[1] = $bbox[1];
+ }
+ if($bbox[2] > $cmnbbox[2]) {
+ $cmnbbox[2] = $bbox[2];
+ }
+ if($bbox[3] > $cmnbbox[3]) {
+ $cmnbbox[3] = $bbox[3];
+ }
+ } elsif( /BlueValues\s+\[\s*(.*)\s*\]/ || /OtherBlues\s+\[\s*(.*)\s*\]/ ) {
+ @blues=split(/\s+/, $1);
+ push(@{$fblues{$f}}, @blues);
+ } elsif( /^dup\s+(\d+)\s+\/(\S+)\s+put/ ) {
+ $fenc{$f}{$1} = $2;
+ if( ! defined $frevenc{$f}{$2} ) {
+ $frevenc{$f}{$2} = $1;
+ }
+ } elsif( /^dup\s+(\d+)\s+\{\s*$/ ) {
+ $key = $1;
+ $bf = $_;
+ while(<FILE>) {
+ $bf .= $_;
+ if( /\}\s+NP/ ) {
+ last;
+ }
+ }
+ $fsubrs{$f}{$key} = $bf;
+ } elsif( /^\/(\S+)\s+\{\s*$/ ) {
+ $key = $1;
+ $bf = $_;
+ while(<FILE>) {
+ $bf .= $_;
+ if( /endchar/ ) {
+ last;
+ }
+ }
+ $fchars{$f}{$key} = $bf;
+ } elsif( /^\/FontName\s+(\S+)/ ) {
+ $fontname{$f} = $1;
+ }
+ }
+ close(FILE);
+}
+
+######################## Prolog ###################################
+
+print("%%!PS-Adobe-1.0
+%%DocumentNeededResources: font Courier
+%%Pages: (atend)
+%%EndComments
+%%BeginProlog
+/cmpfcolorarray [
+ [ 1 0.2 0.2 ] % slightly lighter red
+ [ 0 0.7 0.7 ] % cyan
+ [ 0.7 0.7 0 ] % brown-yellow
+] def
+/cmpfcolor { % number -> .
+ cmpfcolorarray length mod % get the subarray number
+ cmpfcolorarray exch get aload pop setrgbcolor
+} bind def
+/contourcolor { 0 0 0 setrgbcolor } bind def % black
+/bluezonecolor { 0.95 0.95 1 setrgbcolor } bind def % very light blue
+/coordcolor { 0 1 0 setrgbcolor } bind def % green
+/textcolor { 0 0 0 setrgbcolor } bind def % black
+/stemcolor { 1 0 0 setrgbcolor } bind def % red
+/mainstemcolor { 0 0 1 setrgbcolor } bind def % blue
+
+% /fnt2pt { 72 5 mul 1000 div } bind def
+
+/linehor { % . font_y -> .
+ gsave
+ 0 72 translate
+ 72 fnt2pt scale
+ newpath
+ 0 exch moveto
+ 7 0 rlineto
+ stroke
+ grestore
+} bind def
+
+/linevert { % . font_x -> .
+ gsave
+ 72 0 translate
+ fnt2pt 72 scale
+ newpath
+ 0 moveto
+ 0 7 rlineto
+ stroke
+ grestore
+} bind def
+
+/bluezone { % . font_y_1 font_y_2 -> .
+ gsave
+ bluezonecolor
+ 0 72 translate
+ 72 fnt2pt scale
+ newpath
+ 0 exch moveto
+ 7 0 rlineto
+ 7 exch lineto
+ -7 0 rlineto
+ closepath
+ fill
+ grestore
+} bind def
+
+/drawstem { % . xwidth ywidth x0 y0 -> .
+ gsave
+ 72 72 translate fnt2pt fnt2pt scale xorg yorg translate
+ newpath
+ moveto
+ dup 0 exch rlineto
+ exch 0 rlineto
+ neg 0 exch rlineto
+ closepath fill
+ grestore
+} bind def
+
+/getlen {
+ dup stringwidth pop
+} bind def
+
+/compressfont 0.8 def
+
+/label { % . string stringwd y -> .
+ dup lasty lt {
+ dup lasty fontsz sub le
+ } {
+ dup lasty fontsz add ge
+ } ifelse {
+ /curx 0 store
+ } if
+ dup /lasty exch store
+ 0 exch moveto
+ compressfont mul dup curx add maxx gt {
+ /curx 0 store
+ } if
+ curx 0 rmoveto
+ dup 0 rlineto
+ stroke
+ gsave
+ curx lasty moveto
+ curx add /curx exch store
+ compressfont 1 scale
+ show
+ grestore
+} bind def
+");
+
+@bbox=@cmnbbox;
+
+$nx=$bbox[2]-$bbox[0];
+$ny=$bbox[3]-$bbox[1];
+$maxsz= ($nx>$ny) ? $nx : $ny;
+$fnt2pt= 72*5/$maxsz;
+printf("/fnt2pt 72 5 mul %d div def\n", $maxsz);
+$xorg= -($bbox[0]-($maxsz-$nx)/2);
+$yorg= -($bbox[1]-($maxsz-$ny)/2);
+printf("/xorg %d def /yorg %d def\n", $xorg, $yorg);
+
+print("
+%%EndProlog
+");
+
+######################## Subroutines ##############################
+
+sub bluezone # from to
+{
+ my ($a, $b)=@_;
+ printf("%d %d bluezone\n",$a+$yorg, $b+$yorg);
+ $ycoord{$a+0}=1;
+ $ycoord{$b+0}=1;
+}
+
+sub linehor # x
+{
+ my $a=$_[0];
+ printf("%d linehor\n",$a+$yorg);
+ $ycoord{$a+0}=1;
+}
+
+sub linevert # x
+{
+ my $a=$_[0];
+ printf("%d linevert\n",$a+$xorg);
+ $xcoord{$a+0}=1;
+}
+
+sub hstem # from width
+{
+ my ($from, $width)=@_;
+ $stemhused=1;
+ printf("%d %d %d %d drawstem %% %d %d h \n", -$stemwd, $width,
+ $bbox[0]-2-$stemhgrp*$stemwd, $from,
+ $from, $width);
+ printf("%d %d %d %d drawstem %% %d %d h \n", $stemwd, $width,
+ $bbox[2]+2+$stemhgrp*$stemwd, $from,
+ $from, $width);
+}
+
+sub vstem # from width
+{
+ my ($from, $width)=@_;
+ $stemvused=1;
+ printf("%d %d %d %d drawstem %% %d %d v \n", $width, -$stemwd,
+ $from, $bbox[1]-2-$stemhgrp*$stemwd,
+ $from, $width);
+ printf("%d %d %d %d drawstem %% %d %d v \n", $width, $stemwd,
+ $from, $bbox[3]+2+$stemhgrp*$stemwd,
+ $from, $width);
+}
+
+sub nextstemgrp
+{
+ if($stemhused || $stemvused) {
+ $stemhgrp++;
+ $stemhused=0;
+ $stemvgrp++;
+ $stemvused=0;
+ }
+}
+
+sub substems # fname subrlist
+{
+ my $fname = shift;
+ my $i, $cmd, @vals;
+
+ print("\nstemcolor\n");
+
+ for $i (@_) {
+ &nextstemgrp();
+ for $_ (split(/\n/, $fsubrs{$fname}{$i})) {
+ s/^\s+//;
+ @vals=split(/\s+/, $_);
+ $cmd=$vals[$#vals];
+ if($cmd eq "hstem") {
+ &hstem($vals[0], $vals[1]);
+ } elsif($cmd eq "vstem") {
+ &vstem($vals[0], $vals[1]);
+ }
+ }
+ }
+ print("\n");
+}
+
+sub drawcharwstems # charstring
+{
+ my($x,$y)=(0,0);
+ my @vals, $cmd, $i;
+
+ print("\nmainstemcolor\n");
+ &nextstemgrp();
+ for $_ (split(/\n/, $_[0])) {
+ s/^\s+//;
+ @vals=split(/\s+/, $_);
+ $cmd=$vals[$#vals];
+
+ if($cmd eq "hsbw") {
+ $x=$vals[0]+0;
+ } elsif($cmd eq "hstem") {
+ &hstem($vals[0], $vals[1]);
+ } elsif($cmd eq "hstem3") {
+ &hstem($vals[0], $vals[1]);
+ &hstem($vals[2], $vals[3]);
+ &hstem($vals[4], $vals[5]);
+ } elsif($cmd eq "vstem") {
+ &vstem($vals[0], $vals[1]);
+ } elsif($cmd eq "vstem3") {
+ &vstem($vals[0], $vals[1]);
+ &vstem($vals[2], $vals[3]);
+ &vstem($vals[4], $vals[5]);
+ } elsif($cmd eq "rmoveto") {
+ # a shortcut
+ last;
+ }
+ }
+ &drawchar("drawchar", 1, "contourcolor", $_[0]);
+}
+
+sub drawchar #procname wantgrid color charstring
+{
+ my($procname, $wantgrid, $color, $charstring) = @_;
+ my($x,$y)=(0,0);
+ my @vals, $cmd, $i;
+ my %xv=();
+ my %yv=();
+
+ printf("\n/%s {\n",$procname);
+ printf("\ngsave 72 72 translate fnt2pt fnt2pt scale %d %d translate\n", $xorg, $yorg);
+ printf("%s 1 setlinewidth newpath\n", $color);
+ for $_ (split(/\n/, $charstring)) {
+ s/^\s+//;
+ @vals=split(/\s+/, $_);
+ $cmd=$vals[$#vals];
+
+ if($cmd eq "callsubr" && $vals[1] == 4) {
+ push(@subrlist, $vals[0]);
+ } elsif($cmd eq "amoveto") {
+ $x=$vals[0]+0;
+ $y=$vals[1]+0;
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("%d %d moveto\n", $x, $y);
+ printf("%d %d 5 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "rmoveto") {
+ $x+=$vals[0];
+ $y+=$vals[1];
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("%d %d moveto\n", $x, $y);
+ printf("%d %d 5 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "hmoveto") {
+ $x+=$vals[0];
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("%d %d moveto\n", $x, $y);
+ printf("%d %d 5 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "vmoveto") {
+ $y+=$vals[0];
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("%d %d moveto\n", $x, $y);
+ printf("%d %d 5 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "alineto") {
+ $x=$vals[0]+0;
+ $y=$vals[1]+0;
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("%d %d lineto\n", $x, $y);
+ printf("%d %d 3 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "rlineto") {
+ $x+=$vals[0];
+ $y+=$vals[1];
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("%d %d lineto\n", $x, $y);
+ printf("%d %d 3 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "hlineto") {
+ $x+=$vals[0];
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("%d %d lineto\n", $x, $y);
+ printf("%d %d 3 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "vlineto") {
+ $y+=$vals[0];
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("%d %d lineto\n", $x, $y);
+ printf("%d %d 3 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "arcurveto") {
+ for $i (0,2,4) {
+ $x=$vals[$i]+0;
+ $y=$vals[$i+1]+0;
+ printf("%d %d ", $x, $y);
+ }
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("curveto\n");
+ printf("%d %d 3 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "rrcurveto") {
+ for $i (0,2,4) {
+ $x+=$vals[$i];
+ $y+=$vals[$i+1];
+ printf("%d %d \n", $x, $y);
+ }
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("curveto\n");
+ printf("%d %d 3 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "hvcurveto") {
+ $x+=$vals[0];
+ printf("%d %d \n", $x, $y);
+ $x+=$vals[1];
+ $y+=$vals[2];
+ printf("%d %d \n", $x, $y);
+ $y+=$vals[3];
+ printf("%d %d \n", $x, $y);
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("curveto\n");
+ printf("%d %d 3 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "vhcurveto") {
+ $y+=$vals[0];
+ printf("%d %d \n", $x, $y);
+ $x+=$vals[1];
+ $y+=$vals[2];
+ printf("%d %d \n", $x, $y);
+ $x+=$vals[3];
+ printf("%d %d \n", $x, $y);
+ $xv{$x+0}=1; $yv{$y+0}=1;
+ printf("curveto\n");
+ printf("%d %d 3 0 360 arc %d %d moveto\n", $x, $y, $x, $y);
+ } elsif($cmd eq "closepath") {
+ printf("closepath stroke newpath\n");
+ }
+ }
+
+ printf("grestore } bind def\n");
+ if($wantgrid) {
+ printf("coordcolor\n");
+ for $x (keys %xv) {
+ &linevert($x);
+ }
+ for $y (keys %yv) {
+ &linehor($y);
+ }
+ }
+}
+
+$pages=0;
+
+for $arg (@ARGV) {
+ undef $name, $code;
+
+ if( $arg =~ /^\/(.*)/ ) {
+ $name=$1;
+ } elsif( $arg =~ /^\.(.)/ ) {
+ $code=ord($1);
+ } else {
+ $code=$arg;
+ }
+
+ $pages++;
+
+ $stemhgrp=0;
+ $stemhused=0;
+ $stemvgrp=0;
+ $stemvused=0;
+ $stemwd=10;
+ undef %xcoord;
+ undef %ycoord;
+
+ if( defined $name ) {
+ $xname = $name;
+ $xcode = $frevenc{$fname}{$name};
+ if( $xcode eq "" ) {
+ $xcode = "**UNKNOWN**";
+ }
+ } else {
+ $xname = $fenc{$fname}{$code};
+ if( $xname eq "" ) {
+ $xname = "**UNKNOWN**";
+ }
+ $xcode = $code;
+ }
+
+ printf("%%%%Page: %d %d\n", $pages, $pages);
+ printf("gsave
+
+0 setlinewidth
+36 72 translate
+
+gsave
+contourcolor
+72 72 scale
+newpath
+0 0 moveto
+7 0 rlineto
+0 7 rlineto
+-7 0 rlineto
+closepath
+stroke
+1 1 translate
+newpath
+0 0 moveto
+5 0 rlineto
+0 5 rlineto
+-5 0 rlineto
+closepath
+stroke
+grestore
+
+");
+
+ undef @subrlist;
+
+
+ @bbox=@{$fbbox{$fname}};
+
+ print("coordcolor\n");
+ printf("0 linehor %d linehor %d linehor\n", $bbox[1]+$yorg, $bbox[3]+$yorg);
+ printf("%d linevert %d linevert\n", $bbox[0]+$xorg, $bbox[2]+$xorg);
+
+ %vals=@{$fblues{$fname}};
+ for $i (keys %vals) {
+ &bluezone($i, $vals{$i});
+ }
+
+ $havechar = 1;
+ if( defined $fchars{$fname}{$xname} ) {
+ &drawcharwstems($fchars{$fname}{$xname});
+ } else {
+ $havechar = 0;
+ if(defined $name) {
+ printf(STDERR "WARNING: %s nas no character with name \"%s\"\n", $fname, $name);
+ } else {
+ printf(STDERR "WARNING: %s nas no character with code \"%s\"\n", $fname, $code);
+ }
+ }
+
+ &substems($fname, @subrlist);
+
+ printf(STDERR "glyph name:%s code:%s (%d substituted stem groups)\n", $xname, $xcode, scalar @subrlist);
+
+ $cmpfidx = 0;
+ for $cmpf(@cmpfiles) {
+ undef $cname, $ccode;
+
+ if( defined $name ) {
+ if ( ! defined $fchars{$cmpf}{$name} && defined $fenc{$cmpf}{$xcode}) {
+ printf(STDERR " NOTE: %s nas no glyph with name \"%s\", guessed by code\n", $cmpf, $name);
+ $cname = $fenc{$cmpf}{$xcode};
+ if( $cname eq "" ) {
+ $cname = "**UNKNOWN**";
+ }
+ $ccode = $xcode;
+ } else {
+ $cname = $name;
+ $ccode = $frevenc{$cmpf}{$name};
+ if( $ccode eq "" ) {
+ $ccode = "**UNKNOWN**";
+ }
+ }
+ } else {
+ $cname = $fenc{$cmpf}{$code};
+ if( $cname eq "" ) {
+ $cname = "**UNKNOWN**";
+ }
+ $ccode = $code;
+ }
+
+ if( defined $fchars{$cmpf}{$cname} ) {
+ &drawchar("drawcmpchar", 0, sprintf("%d cmpfcolor", $cmpfidx),
+ $fchars{$cmpf}{$cname});
+ printf("drawcmpchar\n\n");
+ printf(STDERR " in %s glyph name:%s code:%s\n", $cmpf, $cname, $ccode);
+ } else {
+ if(defined $name) {
+ printf(STDERR " WARNING: %s nas no character with name \"%s\"\n", $cmpf, $name);
+ } else {
+ printf(STDERR " WARNING: %s nas no character with code \"%s\"\n", $cmpf, $code);
+ }
+ }
+ $cmpfidx++;
+ }
+
+ if($havechar) {
+ printf("drawchar\n\n");
+ }
+
+ # flush the last group
+ &nextstemgrp();
+
+ # the values of coordinates
+ printf("/fontsz 8 fnt2pt div def\n");
+ printf("/Myfont /Courier findfont fontsz scalefont def\n\n");
+ printf("contourcolor Myfont setfont\n");
+
+ for $org (0, $xorg+$bbox[2]+$stemwd*$stemhgrp+72/$fnt2pt) {
+ printf("gsave\n");
+ printf("/maxx 72 fnt2pt div %d sub def /curx 0 def /lasty -10000 def\n",
+ 2+$stemhgrp*$stemwd-$xorg-$bbox[0]);
+ printf("0 72 translate fnt2pt fnt2pt scale %f yorg translate 1 setlinewidth\n", $org);
+ for $y (sort {$a <=> $b} keys %ycoord) {
+ printf("(%d) getlen %d label\n", $y, $y);
+ }
+ printf("grestore\n");
+ }
+
+ for $org (0, $yorg+$bbox[3]+$stemwd*$stemvgrp+72/$fnt2pt) {
+ printf("gsave\n");
+ printf("/maxx 72 fnt2pt div %d sub def /curx 0 def /lasty -10000 def\n",
+ 2+$stemvgrp*$stemwd-$yorg-$bbox[1]);
+ printf("72 0 translate fnt2pt fnt2pt scale xorg %f translate 90 rotate 1 setlinewidth\n", $org);
+ for $x (sort {$a <=> $b} keys %xcoord) {
+ printf("(%d) getlen %d label\n", $x, -$x);
+ }
+ printf("grestore\n");
+ }
+
+ printf("gsave 0 %d translate\n", 7.5*72 );
+ printf("contourcolor /Courier findfont 12 scalefont setfont\n");
+ $line = 0;
+
+ $cmpfidx = $#cmpfiles;
+ if( $cmpfidx > (2.5*72/15)-4 ) {
+ $cmpfidx = (2.5*72/15)-4;
+ }
+ for(; $cmpfidx>=0; $cmpfidx--) {
+ $cmpf = $cmpfiles[$cmpfidx];
+ printf("%d cmpfcolor\n", $cmpfidx);
+ printf("newpath 20 %d moveto 0 10 rlineto 10 0 rlineto 0 -10 rlineto closepath fill\n",
+ 15*$line, $cmpf);
+ printf("contourcolor 40 %d moveto (%s %s) show\n", 15*$line, $cmpf, $fontname{$cmpf});
+ $line++;
+ }
+ if( $#cmpfiles >=0 ) {
+ printf("0 %d moveto (Comparison files:) show\n", 15*$line++);
+ }
+ printf("0 %d moveto (code: %d name: %s) show\n", 15*$line++, $xcode, $xname);
+ printf("0 %d moveto (%s) show\n", 15*$line++, $fname);
+ printf("0 %d moveto (%s) show\n", 15*$line++, $fontname{$fname});
+ printf("grestore\n\n");
+
+ printf("showpage grestore\n\n");
+}
+printf("%%%%Pages: %d\n", $pages);