summaryrefslogtreecommitdiff
path: root/Build/source/texk/lcdf-typetools/mmpfb
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2008-02-17 19:29:39 +0000
committerKarl Berry <karl@freefriends.org>2008-02-17 19:29:39 +0000
commitfc3b5d4d4f684baa6216685a0696efb853141529 (patch)
tree0694ed01c09b3c97fcd64453e2c1f647a3fb31ad /Build/source/texk/lcdf-typetools/mmpfb
parent5fc0a693ca037d37d815b00c49660c138b332224 (diff)
move lcdf-typetools to texk and update to 2.66
git-svn-id: svn://tug.org/texlive/trunk@6662 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/lcdf-typetools/mmpfb')
-rw-r--r--Build/source/texk/lcdf-typetools/mmpfb/Makefile.am17
-rw-r--r--Build/source/texk/lcdf-typetools/mmpfb/Makefile.in477
-rw-r--r--Build/source/texk/lcdf-typetools/mmpfb/main.cc462
-rw-r--r--Build/source/texk/lcdf-typetools/mmpfb/mmpfb.1209
-rw-r--r--Build/source/texk/lcdf-typetools/mmpfb/myfont.cc300
-rw-r--r--Build/source/texk/lcdf-typetools/mmpfb/myfont.hh31
-rw-r--r--Build/source/texk/lcdf-typetools/mmpfb/t1minimize.cc41
-rw-r--r--Build/source/texk/lcdf-typetools/mmpfb/t1minimize.hh7
-rw-r--r--Build/source/texk/lcdf-typetools/mmpfb/t1rewrit.cc922
-rw-r--r--Build/source/texk/lcdf-typetools/mmpfb/t1rewrit.hh68
10 files changed, 2534 insertions, 0 deletions
diff --git a/Build/source/texk/lcdf-typetools/mmpfb/Makefile.am b/Build/source/texk/lcdf-typetools/mmpfb/Makefile.am
new file mode 100644
index 00000000000..5d579edca5c
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/mmpfb/Makefile.am
@@ -0,0 +1,17 @@
+## Process this file with automake to produce Makefile.in
+AUTOMAKE_OPTIONS = foreign
+
+bin_PROGRAMS = mmpfb
+man_MANS = mmpfb.1
+
+mmpfb_SOURCES = myfont.cc myfont.hh \
+ main.cc \
+ t1minimize.cc t1minimize.hh \
+ t1rewrit.cc t1rewrit.hh
+
+mmpfb_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a
+
+INCLUDES = -I$(top_srcdir)/include
+CLEANFILES = @TEMPLATE_OBJS@
+
+EXTRA_DIST = mmpfb.1
diff --git a/Build/source/texk/lcdf-typetools/mmpfb/Makefile.in b/Build/source/texk/lcdf-typetools/mmpfb/Makefile.in
new file mode 100644
index 00000000000..764d39a37e9
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/mmpfb/Makefile.in
@@ -0,0 +1,477 @@
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+top_builddir = ..
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+INSTALL = @INSTALL@
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+bin_PROGRAMS = mmpfb$(EXEEXT)
+subdir = mmpfb
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS)
+am_mmpfb_OBJECTS = myfont.$(OBJEXT) main.$(OBJEXT) \
+ t1minimize.$(OBJEXT) t1rewrit.$(OBJEXT)
+mmpfb_OBJECTS = $(am_mmpfb_OBJECTS)
+mmpfb_DEPENDENCIES = ../libefont/libefont.a ../liblcdf/liblcdf.a
+DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+ -o $@
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+SOURCES = $(mmpfb_SOURCES)
+DIST_SOURCES = $(mmpfb_SOURCES)
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(man_MANS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMDEP_FALSE = @AMDEP_FALSE@
+AMDEP_TRUE = @AMDEP_TRUE@
+AMTAR = @AMTAR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FIXLIBC_O = @FIXLIBC_O@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+KPSEINTERFACE_O = @KPSEINTERFACE_O@
+LDFLAGS = @LDFLAGS@
+LIBKPATHSEA = @LIBKPATHSEA@
+LIBKPATHSEA_DEP = @LIBKPATHSEA_DEP@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
+MAKEINFO = @MAKEINFO@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SELECTED_SUBDIRS = @SELECTED_SUBDIRS@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+TEMPLATE_OBJS = @TEMPLATE_OBJS@
+VERSION = @VERSION@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
+am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
+am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
+am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
+am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build_alias = @build_alias@
+datadir = @datadir@
+exec_prefix = @exec_prefix@
+host_alias = @host_alias@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+AUTOMAKE_OPTIONS = foreign
+man_MANS = mmpfb.1
+mmpfb_SOURCES = myfont.cc myfont.hh \
+ main.cc \
+ t1minimize.cc t1minimize.hh \
+ t1rewrit.cc t1rewrit.hh
+
+mmpfb_LDADD = ../libefont/libefont.a ../liblcdf/liblcdf.a
+INCLUDES = -I$(top_srcdir)/include
+CLEANFILES = @TEMPLATE_OBJS@
+EXTRA_DIST = mmpfb.1
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign mmpfb/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign mmpfb/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+mmpfb$(EXEEXT): $(mmpfb_OBJECTS) $(mmpfb_DEPENDENCIES)
+ @rm -f mmpfb$(EXEEXT)
+ $(CXXLINK) $(mmpfb_LDFLAGS) $(mmpfb_OBJECTS) $(mmpfb_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/myfont.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1minimize.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t1rewrit.Po@am__quote@
+
+.cc.o:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
+@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+uninstall-info-am:
+install-man1: $(man1_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man1dir)" || $(mkdir_p) "$(DESTDIR)$(man1dir)"
+ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 1*) ;; \
+ *) ext='1' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \
+ done
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 1*) ;; \
+ *) ext='1' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
+ list='$(DISTFILES)'; for file in $$list; do \
+ case $$file in \
+ $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
+ $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
+ esac; \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test "$$dir" != "$$file" && test "$$dir" != "."; then \
+ dir="/$$dir"; \
+ $(mkdir_p) "$(distdir)$$dir"; \
+ else \
+ dir=''; \
+ fi; \
+ if test -d $$d/$$file; then \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+check: check-am
+all-am: Makefile $(PROGRAMS) $(MANS)
+installdirs:
+ for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
+ test -z "$$dir" || $(mkdir_p) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man
+
+install-exec-am: install-binPROGRAMS
+
+install-info: install-info-am
+
+install-man: install-man1
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-binPROGRAMS uninstall-info-am uninstall-man
+
+uninstall-man: uninstall-man1
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
+ clean-generic ctags distclean distclean-compile \
+ distclean-generic distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-binPROGRAMS \
+ install-data install-data-am install-exec install-exec-am \
+ install-info install-info-am install-man install-man1 \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-compile mostlyclean-generic pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-info-am uninstall-man uninstall-man1
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Build/source/texk/lcdf-typetools/mmpfb/main.cc b/Build/source/texk/lcdf-typetools/mmpfb/main.cc
new file mode 100644
index 00000000000..b323882ecbd
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/mmpfb/main.cc
@@ -0,0 +1,462 @@
+/* main.cc -- driver for mmpfb program
+ *
+ * Copyright (c) 1997-2006 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <efont/psres.hh>
+#include <efont/t1rw.hh>
+#include <efont/t1mm.hh>
+#include "myfont.hh"
+#include "t1rewrit.hh"
+#include "t1minimize.hh"
+#include <lcdf/clp.h>
+#include <lcdf/error.hh>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <errno.h>
+#ifdef HAVE_CTIME
+# include <time.h>
+#endif
+#if defined(_MSDOS) || defined(_WIN32)
+# include <fcntl.h>
+# include <io.h>
+#endif
+
+#define WEIGHT_OPT 300
+#define WIDTH_OPT 301
+#define OPSIZE_OPT 302
+#define STYLE_OPT 303
+#define N1_OPT 304
+#define N2_OPT 305
+#define N3_OPT 306
+#define N4_OPT 307
+#define VERSION_OPT 308
+#define AMCP_INFO_OPT 309
+#define HELP_OPT 310
+#define PFA_OPT 311
+#define PFB_OPT 312
+#define OUTPUT_OPT 313
+#define QUIET_OPT 314
+#define PRECISION_OPT 315
+#define SUBRS_OPT 316
+#define MINIMIZE_OPT 317
+
+Clp_Option options[] = {
+ { "1", '1', N1_OPT, Clp_ArgDouble, 0 },
+ { "2", '2', N2_OPT, Clp_ArgDouble, 0 },
+ { "3", '3', N3_OPT, Clp_ArgDouble, 0 },
+ { "4", '4', N4_OPT, Clp_ArgDouble, 0 },
+ { "amcp-info", 0, AMCP_INFO_OPT, 0, 0 },
+ { "help", 'h', HELP_OPT, 0, 0 },
+ { "minimize", 'm', MINIMIZE_OPT, 0, Clp_Negate },
+ { "optical-size", 'O', OPSIZE_OPT, Clp_ArgDouble, 0 },
+ { "output", 'o', OUTPUT_OPT, Clp_ArgString, 0 },
+ { "pfa", 'a', PFA_OPT, 0, 0 },
+ { "pfb", 'b', PFB_OPT, 0, 0 },
+ { "precision", 'p', PRECISION_OPT, Clp_ArgUnsigned, 0 },
+ { "quiet", 'q', QUIET_OPT, 0, Clp_Negate },
+ { "style", 0, STYLE_OPT, Clp_ArgDouble, 0 },
+ { "subrs", 0, SUBRS_OPT, Clp_ArgInt, Clp_Negate },
+ { "version", 'v', VERSION_OPT, 0, 0 },
+ { "wd", 0, WIDTH_OPT, Clp_ArgDouble, 0 },
+ { "weight", 'w', WEIGHT_OPT, Clp_ArgDouble, 0 },
+ { "width", 'W', WIDTH_OPT, Clp_ArgDouble, 0 },
+ { "wt", 0, WEIGHT_OPT, Clp_ArgDouble, 0 },
+};
+
+using namespace Efont;
+
+static const char *program_name;
+static ErrorHandler *errh;
+static MyFont *font;
+static MultipleMasterSpace *mmspace;
+
+static Vector<PermString> ax_names;
+static Vector<int> ax_nums;
+static Vector<double> values;
+
+
+void
+usage_error(const char *error_message, ...)
+{
+ va_list val;
+ va_start(val, error_message);
+ if (!error_message)
+ errh->message("Usage: %s [OPTION]... FONT", program_name);
+ else
+ errh->verror(ErrorHandler::ERR_ERROR, String(), error_message, val);
+ errh->message("Type %s --help for more information.", program_name);
+ exit(1);
+}
+
+void
+usage()
+{
+ printf("\
+'Mmpfb' creates a single-master PostScript Type 1 font by interpolating a\n\
+multiple master font at a point you specify. The resulting font does not\n\
+contain multiple master extensions. It is written to the standard output.\n\
+\n\
+Usage: %s [OPTION]... FONT\n\
+\n\
+FONT is either the name of a PFA or PFB multiple master font file, or a\n\
+PostScript font name. In the second case, mmpfb will find the actual outline\n\
+file using the PSRESOURCEPATH environment variable.\n\
+\n\
+General options:\n\
+ --amcp-info Print AMCP info, if necessary, and exit.\n\
+ -a, --pfa Output PFA font.\n\
+ -b, --pfb Output PFB font. This is the default.\n\
+ -o, --output=FILE Write output to FILE.\n\
+ -p, --precision=N Set precision to N (larger means more precise).\n\
+ --subrs=N Limit output font to at most N subroutines.\n\
+ --no-minimize Do not replace original font's PostScript code.\n\
+ -h, --help Print this message and exit.\n\
+ -q, --quiet Do not generate any error messages.\n\
+ -v, --version Print version number and exit.\n\
+\n\
+Interpolation settings:\n\
+ -w, --weight=N Set weight to N.\n\
+ -W, --width=N Set width to N.\n\
+ -O, --optical-size=N Set optical size to N.\n\
+ --style=N Set style axis to N.\n\
+ --1=N, --2=N, --3=N, --4=N Set first (second, third, fourth) axis to N.\n\
+\n\
+Report bugs to <kohler@cs.ucla.edu>.\n", program_name);
+}
+
+
+static void
+set_design(PermString a, double v)
+{
+ ax_names.push_back(a);
+ ax_nums.push_back(-1);
+ values.push_back(v);
+}
+
+static void
+set_design(int a, double v)
+{
+ ax_names.push_back(PermString());
+ ax_nums.push_back(a);
+ values.push_back(v);
+}
+
+void
+do_file(const char *filename, PsresDatabase *psres)
+{
+ FILE *f;
+ if (strcmp(filename, "-") == 0) {
+ f = stdin;
+ filename = "<stdin>";
+#if defined(_MSDOS) || defined(_WIN32)
+ _setmode(_fileno(f), _O_BINARY);
+#endif
+ } else
+ f = fopen(filename, "rb");
+
+ if (!f) {
+ // check for PostScript or instance name
+ Filename fn = psres->filename_value("FontOutline", filename);
+ const char *underscore = strchr(filename, '_');
+ if (!fn && underscore) {
+ fn = psres->filename_value
+ ("FontOutline", PermString(filename, underscore - filename));
+ int i = 0;
+ while (underscore[0] == '_' && underscore[1]) {
+ double x = strtod(underscore + 1, const_cast<char **>(&underscore));
+ set_design(i, x);
+ i++;
+ }
+ }
+ f = fn.open_read();
+ }
+
+ if (!f)
+ errh->fatal("%s: %s", filename, strerror(errno));
+
+ Type1Reader *reader;
+ int c = getc(f);
+ ungetc(c, f);
+ if (c == EOF)
+ errh->fatal("%s: empty file", filename);
+ if (c == 128)
+ reader = new Type1PFBReader(f);
+ else
+ reader = new Type1PFAReader(f);
+
+ font = new MyFont(*reader);
+ delete reader;
+ if (!font->ok())
+ errh->fatal("%s: invalid font", filename);
+ else if (font->nglyphs() == 0)
+ errh->fatal("%s: font contains no characters", filename);
+
+ mmspace = font->create_mmspace(errh);
+ if (!mmspace)
+ errh->fatal("%s: not a multiple master font", filename);
+
+ font->undo_synthetic();
+}
+
+
+static void
+print_conversion_program(FILE *f, const Type1Charstring &cs, PermString name)
+{
+ if (cs) {
+ const unsigned char *data = cs.data();
+ for (int i = 0; i < cs.length(); ) {
+ int l = cs.length() - i;
+ if (l > 32)
+ l = 32;
+ fprintf(f, "%s <", name.c_str());
+ for (int j = 0; j < l; j++)
+ fprintf(f, "%02X", data[j]);
+ fprintf(f, ">\n");
+ data += l;
+ i += l;
+ }
+ }
+}
+
+
+static void
+print_amcp_info(MultipleMasterSpace *mmspace, FILE *f)
+{
+ const Type1Charstring &ndv = mmspace->ndv();
+ const Type1Charstring &cdv = mmspace->cdv();
+ if (!ndv && !cdv)
+ fprintf(stderr, "%s does not have conversion programs.\n",
+ mmspace->font_name().c_str());
+ else {
+ fprintf(f, "StartConversionPrograms %d %d\n", ndv.length(),
+ cdv.length());
+ print_conversion_program(f, ndv, "NDV");
+ print_conversion_program(f, cdv, "CDV");
+ fprintf(f, "EndConversionPrograms\n");
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ PsresDatabase *psres = new PsresDatabase;
+ psres->add_psres_path(getenv("PSRESOURCEPATH"), 0, false);
+
+ Clp_Parser *clp =
+ Clp_NewParser(argc, (const char * const *)argv, sizeof(options) / sizeof(options[0]), options);
+ program_name = Clp_ProgramName(clp);
+
+ bool write_pfb = true;
+ bool amcp_info = false;
+ bool minimize = true;
+ int precision = 5;
+ int subr_count = -1;
+ FILE *outfile = 0;
+ ::errh =
+ ErrorHandler::static_initialize(new FileErrorHandler(stderr, String(program_name) + ": "));
+
+ while (1) {
+ int opt = Clp_Next(clp);
+ switch (opt) {
+
+ case WEIGHT_OPT:
+ set_design("Weight", clp->val.d);
+ break;
+
+ case WIDTH_OPT:
+ set_design("Width", clp->val.d);
+ break;
+
+ case OPSIZE_OPT:
+ set_design("OpticalSize", clp->val.d);
+ break;
+
+ case STYLE_OPT:
+ set_design("Style", clp->val.d);
+ break;
+
+ case N1_OPT:
+ case N2_OPT:
+ case N3_OPT:
+ case N4_OPT:
+ set_design(opt - N1_OPT, clp->val.d);
+ break;
+
+ case AMCP_INFO_OPT:
+ amcp_info = true;
+ break;
+
+ case PFA_OPT:
+ write_pfb = false;
+ break;
+
+ case PFB_OPT:
+ write_pfb = true;
+ break;
+
+ case PRECISION_OPT:
+ if (clp->val.i > 107) {
+ errh->warning("precision lowered to 107");
+ precision = 107;
+ } else if (clp->val.i < 1) {
+ errh->warning("precision raised to 1");
+ precision = 1;
+ } else
+ precision = clp->val.i;
+ break;
+
+ case SUBRS_OPT:
+ if (clp->negated)
+ subr_count = -1;
+ else if (clp->val.i <= 0)
+ errh->warning("subr count too small");
+ else
+ subr_count = clp->val.i;
+ break;
+
+ case MINIMIZE_OPT:
+ minimize = !clp->negated;
+ break;
+
+ case QUIET_OPT:
+ if (clp->negated)
+ errh = ErrorHandler::default_handler();
+ else
+ errh = new SilentErrorHandler;
+ break;
+
+ case OUTPUT_OPT:
+ if (outfile) errh->fatal("output file already specified");
+ if (strcmp(clp->arg, "-") == 0)
+ outfile = stdout;
+ else {
+ outfile = fopen(clp->arg, "wb");
+ if (!outfile)
+ errh->fatal("%s: %s", clp->arg, strerror(errno));
+ }
+ break;
+
+ case VERSION_OPT:
+ printf("mmpfb (LCDF typetools) %s\n", VERSION);
+ printf("Copyright (C) 1997-2006 Eddie Kohler\n\
+This is free software; see the source for copying conditions.\n\
+There is NO warranty, not even for merchantability or fitness for a\n\
+particular purpose.\n");
+ exit(0);
+ break;
+
+ case HELP_OPT:
+ usage();
+ exit(0);
+ break;
+
+ case Clp_NotOption:
+ do_file(clp->arg, psres);
+ break;
+
+ case Clp_Done:
+ if (!font)
+ usage_error("missing font argument");
+ goto done;
+
+ case Clp_BadOption:
+ usage_error(0);
+ break;
+
+ default:
+ break;
+
+ }
+ }
+
+ done:
+ if (outfile == 0)
+ outfile = stdout;
+
+ if (amcp_info) {
+ print_amcp_info(mmspace, outfile);
+ exit(0);
+ }
+
+ Vector<double> design = mmspace->empty_design_vector();
+ for (int i = 0; i < values.size(); i++)
+ if (ax_names[i])
+ mmspace->set_design(design, ax_names[i], values[i], errh);
+ else
+ mmspace->set_design(design, ax_nums[i], values[i], errh);
+
+ Vector<double> default_design = mmspace->default_design_vector();
+ for (int i = 0; i < mmspace->naxes(); i++)
+ if (!KNOWN(design[i]) && KNOWN(default_design[i])) {
+ errh->warning("using default value %g for %s's %s", default_design[i],
+ font->font_name().c_str(), mmspace->axis_type(i).c_str());
+ design[i] = default_design[i];
+ }
+
+ if (!font->set_design_vector(mmspace, design, errh))
+ exit(1);
+
+ font->interpolate_dicts(minimize, errh);
+ font->interpolate_charstrings(precision, errh);
+
+ if (subr_count >= 0) {
+ Type1SubrRemover sr(font, errh);
+ sr.run(subr_count);
+ }
+
+ font->fill_in_subrs();
+
+ Type1Font *t1font;
+ if (minimize) {
+ t1font = ::minimize(font);
+ delete font;
+ } else
+ t1font = font;
+
+ { // Add an identifying comment.
+#if HAVE_CTIME
+ time_t cur_time = time(0);
+ char *time_str = ctime(&cur_time);
+ int time_len = strlen(time_str) - 1;
+ char *buf = new char[strlen(VERSION) + time_len + 100];
+ sprintf(buf, "%%%% Interpolated by mmpfb-%s on %.*s.", VERSION,
+ time_len, time_str);
+#else
+ char *buf = new char[strlen(VERSION) + 100];
+ sprintf(buf, "%%%% Interpolated by mmpfb-%s.", VERSION);
+#endif
+
+ t1font->add_header_comment(buf);
+ t1font->add_header_comment("%% Mmpfb is free software. See <http://www.lcdf.org/type/>.");
+ delete[] buf;
+ }
+
+ if (write_pfb) {
+#if defined(_MSDOS) || defined(_WIN32)
+ _setmode(_fileno(outfile), _O_BINARY);
+#endif
+ Type1PFBWriter w(outfile);
+ t1font->write(w);
+ } else {
+ Type1PFAWriter w(outfile);
+ t1font->write(w);
+ }
+
+ return 0;
+}
diff --git a/Build/source/texk/lcdf-typetools/mmpfb/mmpfb.1 b/Build/source/texk/lcdf-typetools/mmpfb/mmpfb.1
new file mode 100644
index 00000000000..6cba4d26d3a
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/mmpfb/mmpfb.1
@@ -0,0 +1,209 @@
+.\" -*-nroff-*-
+.ds V 2.66
+.de M
+.BR "\\$1" "(\\$2)\\$3"
+..
+.ds E " \-\-
+.if t .ds E \(em
+.de OP
+.BR "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
+..
+.de OA
+.IR "\fB\\$1\& \|\fI\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
+..
+.de OY
+.BI "\\$1\fR=" "\\$2\fR, " "\\$3\& " "\\$4" "\\$5" "\\$6"
+..
+.de OL
+.BI "\\$1\fR=" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
+..
+.de Sp
+.if n .sp
+.if t .sp 0.4
+..
+.TH MMPFB 1 "LCDF Typetools" "Version \*V"
+.SH NAME
+mmpfb \- creates single-master fonts from multiple master fonts
+'
+.SH SYNOPSIS
+.B mmpfb
+\%[OPTIONS...]
+.I font
+'
+.SH DESCRIPTION
+.B Mmpfb
+creates a normal, single-master PostScript font from a multiple master font
+by interpolation. You pass it a PFB or PFA font and options specifying the
+design point you want; it writes the resulting PFB or PFA font to the
+standard output.
+.PP
+The fonts
+.B mmpfb
+creates are interpolated at a low level to remove multiple master
+instructions from individual characters. Therefore, they can be used by
+programs that don't normally understand multiple master fonts, like
+.BR ps2pk (1).
+.PP
+.B Mmpfb
+supports fonts with intermediate masters, like Adobe Jenson and Kepler. It
+can also create AMCP (Adobe Multiple Master Conversion Program) files for
+use by
+.M mmafm 1 ;
+see
+.B \-\-amcp\-info
+below.
+.PP
+The
+.I font
+argument is either the name of a PFA or PFB font file, or a PostScript font
+name. If you give a font name,
+.B mmpfb
+will find the actual outline file using the PSRESOURCEPATH environment
+variable. This colon-separated path is searched for `PSres.upr' files, an
+Adobe method for indexing PostScript resources.
+.PP
+You can also give the name of a multiple
+master font instance, like `MinionMM_367_400_12_'.
+.B Mmpfb
+will parse the font name and create that instance for you. `PSres.upr'
+files must be set up for this to work.
+'
+'
+.SH EXAMPLE
+'
+.nf
+% mmpfb \-\-weight=400 \-\-width=600 MyriadMM.pfb > MyriadMM_400_600_.pfb
+.fi
+'
+.SH OPTIONS
+Long options may be abbreviated to their unique prefixes.
+'
+.TP 5
+.OY \-\-output file \-o file
+'
+Send output to
+.I file
+instead of standard output.
+'
+.TP
+.BR \-\-pfb ", " \-b
+'
+Output a PFB font. This is the default.
+'
+.TP
+.BR \-\-pfa ", " \-a
+'
+Output a PFA font.
+'
+.TP
+.OP \-\-amcp\-info
+'
+Do not create a font; instead, output an AMCP file for use by
+.M mmafm 1 .
+A message is printed if the font doesn't have intermediate masters, in
+which case no AMCP file is necessary.
+'
+.TP
+.OY \-\-weight N \-w N
+'
+Set the weight axis to
+.IR N .
+'
+.TP
+.OY \-\-width N \-W N
+'
+Set the width axis to
+.IR N .
+'
+.TP
+.OY \-\-optical\-size N \-O N
+'
+Set the optical size axis to
+.IR N .
+'
+.TP
+.OL \-\-style N
+'
+Set the style axis to
+.IR N .
+.TP
+\fB\-\-1\fR=\fIN\fR (\fB\-\-2\fR=\fIN\fR, \fB\-\-3\fR=\fIN\fR, \fB\-\-4\fR=\fIN\fR)
+'
+Set the first (second, third, fourth) axis to
+.IR N .
+'
+.TP
+.OY \-\-precision N \-p N
+'
+Set the output precision to
+.IR N .
+Higher values mean the control points in the output font will be more
+exactly aligned; lower values (1 or 2) create smaller output font
+files, and are close enough for most purposes. A precision of
+.IR N
+means that each point will be within
+.RI 1/ N
+font units of the exact interpolated value. (A font unit is generally
+1/7200 inch for a 10-point font.) The default is 5.
+'
+.TP
+.OL \-\-subrs N
+'
+Limit the output font to at most
+.IR N
+subroutines. 256 is a good value for
+.IR N .
+'
+.TP
+.BR \-\-no\-minimize
+'
+Do not minimize the output font definition. By default,
+.B mmpfb
+removes extra PostScript code and dictionary definitions from the font.
+Supply the
+.B \-\-no\-minimize
+option to avoid this behavior.
+'
+.SH TROUBLESHOOTING
+.LP
+The "IBM" Type 1 font interpreter shipped as part of the X font server and
+.B ps2pk
+(among others) is inappropriately strict about PostScript code embedded in
+a font. The
+.B \-\-minimize
+option (now the default) fixes this problem.
+.LP
+Some versions of Adobe Acrobat Distiller may report "Warning: unable to
+embed font X. Invalid character outline data" when distilling an instance
+generated by
+.BR mmpfb .
+This is due to a limitation in the number of font subroutines Distiller can
+accept. (Multiple master fonts, and the single-master fonts generated by
+.BR mmpfb ,
+tend to have a lot of subroutines.) Try limiting the number of subroutines
+in the generated font with the
+.OP \-\-subrs
+option.
+'
+.SH SEE ALSO
+.M mmafm 1
+'
+.SH DIAGNOSTICS
+.TP 5
+reducing \fIfont\fR to minimum number of subroutines (\fIN\fR)
+You tried to reduce the number of subroutines to less than \fIN\fR using
+the
+.OP \-\-subrs
+option, but the font needs at least \fIN\fR to function. The output font
+will have \fIN\fR subroutines.
+'
+.SH AUTHOR
+.na
+Eddie Kohler, kohler@cs.ucla.edu
+.PP
+The latest version is available from:
+.br
+http://www.lcdf.org/type/
+.PP
+Thanks to Melissa O'Neill <oneill@cs.sfu.ca> for suggestions and patient
+debugging.
diff --git a/Build/source/texk/lcdf-typetools/mmpfb/myfont.cc b/Build/source/texk/lcdf-typetools/mmpfb/myfont.cc
new file mode 100644
index 00000000000..9816daefe47
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/mmpfb/myfont.cc
@@ -0,0 +1,300 @@
+/* myfont.cc -- general multiple- to single-master conversion
+ *
+ * Copyright (c) 1997-2006 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "myfont.hh"
+#include <efont/t1item.hh>
+#include <efont/t1interp.hh>
+#include "t1rewrit.hh"
+#include <efont/t1mm.hh>
+#include <lcdf/error.hh>
+#include <lcdf/straccum.hh>
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+using namespace Efont;
+
+MyFont::MyFont(Type1Reader &reader)
+ : Type1Font(reader)
+{
+}
+
+MyFont::~MyFont()
+{
+}
+
+void
+MyFont::kill_def(Type1Definition *t1d, int whichd)
+{
+ if (!t1d)
+ return;
+
+ if (whichd < 0)
+ for (whichd = dFont; whichd < dLast; whichd = (Dict)(whichd + 1))
+ if (dict(whichd, t1d->name()) == t1d)
+ break;
+ if (whichd < 0 || whichd >= dLast || dict(whichd, t1d->name()) != t1d)
+ return;
+
+ int icount = nitems();
+ for (int i = first_dict_item(whichd); i < icount; i++)
+ if (item(i) == t1d) {
+ StringAccum sa;
+ sa << '%';
+ t1d->gen(sa);
+ PermString name = t1d->name();
+ Type1CopyItem *t1ci = new Type1CopyItem(sa.take_string());
+ set_item(i, t1ci);
+ set_dict(whichd, name, 0);
+ return;
+ }
+
+ assert(0);
+}
+
+bool
+MyFont::set_design_vector(MultipleMasterSpace *mmspace, const Vector<double> &design, ErrorHandler *errh)
+{
+ Type1Definition *t1d = dict("DesignVector");
+ if (t1d) {
+ t1d->set_numvec(design);
+ kill_def(t1d, dFont);
+ }
+
+ t1d = dict("NormDesignVector");
+ if (t1d) {
+ NumVector norm_design;
+ if (mmspace->design_to_norm_design(design, norm_design))
+ t1d->set_numvec(norm_design);
+ kill_def(t1d, dFont);
+ }
+
+ if (!mmspace->design_to_weight(design, _weight_vector, errh))
+ return false;
+
+ // Need to check for case when all design coordinates are unspecified. The
+ // font file contains a default WeightVector, but possibly NOT a default
+ // DesignVector; we don't want to generate a FontName like
+ // `MyriadMM_-9.79797979e97_-9.79797979e97_' because the DesignVector
+ // components are unknown.
+ if (!KNOWN(design[0])) {
+ errh->error("must specify %s's %s coordinate", font_name().c_str(),
+ mmspace->axis_type(0).c_str());
+ return false;
+ }
+
+ t1d = dict("WeightVector");
+ if (t1d) {
+ t1d->set_numvec(_weight_vector);
+ kill_def(t1d, dFont);
+ }
+
+ int naxes = design.size();
+ _nmasters = _weight_vector.size();
+
+ PermString name;
+ t1d = dict("FontName");
+ if (t1d && t1d->value_name(name)) {
+ StringAccum sa(name);
+ for (int a = 0; a < naxes; a++)
+ sa << '_' << design[a];
+ // Multiple masters require an underscore AFTER the font name
+ sa << '_';
+ t1d->set_name(sa.c_str());
+ uncache_defs(); // remove cached font name
+ }
+
+ // add a FullName too
+ String full_name;
+ t1d = fi_dict("FullName");
+ if (t1d && t1d->value_string(full_name)) {
+ StringAccum sa(full_name);
+ for (int a = 0; a < naxes; a++) {
+ sa << (a ? ' ' : '_') << design[a];
+ PermString label = mmspace->axis_abbreviation(a);
+ if (label)
+ sa << ' ' << label;
+ }
+ t1d->set_string(sa.c_str());
+ }
+
+ // save UniqueID, then kill its definition
+ int uniqueid;
+ t1d = dict("UniqueID");
+ bool have_uniqueid = (t1d && t1d->value_int(uniqueid));
+ kill_def(t1d, dFont);
+
+ // prepare XUID
+ t1d = dict("XUID");
+ NumVector xuid;
+ if (!t1d || !t1d->value_numvec(xuid)) {
+ if (have_uniqueid) {
+ t1d = ensure(dFont, "XUID");
+ xuid.clear();
+ xuid.push_back(1);
+ xuid.push_back(uniqueid);
+ } else if (t1d) {
+ kill_def(t1d, dFont);
+ t1d = 0;
+ }
+ }
+ if (t1d) {
+ // Append design vector values to the XUID to prevent cache pollution.
+ for (int a = 0; a < naxes; a++)
+ xuid.push_back((int)(design[a] * 100));
+ t1d->set_numvec(xuid);
+ }
+
+ return true;
+}
+
+void
+MyFont::interpolate_dict_int(PermString name, Dict the_dict, ErrorHandler *errh)
+{
+ Type1Definition *def = dict(the_dict, name);
+ Type1Definition *blend_def = dict(the_dict + dBlend, name);
+ NumVector blend;
+
+ if (def && blend_def && blend_def->value_numvec(blend)) {
+ int n = _nmasters;
+ double val = 0;
+ for (int m = 0; m < n; m++)
+ val += blend[m] * _weight_vector[m];
+ int ival = (int)floor(val + 0.50001);
+ if (fabs(val - ival) >= 0.001)
+ errh->warning("interpolated %s should be an integer (it is %g)", name.c_str(), val);
+ def->set_num(ival);
+ kill_def(blend_def, the_dict + dBlend);
+ }
+}
+
+void
+MyFont::interpolate_dict_num(PermString name, Dict the_dict, bool force_integer)
+{
+ Type1Definition *def = dict(the_dict, name);
+ Type1Definition *blend_def = dict(the_dict + dBlend, name);
+ NumVector blend;
+
+ if (def && blend_def && blend_def->value_numvec(blend)) {
+ int n = _nmasters;
+ double val = 0;
+ for (int m = 0; m < n; m++)
+ val += blend[m] * _weight_vector[m];
+ if (force_integer)
+ val = floor(val + 0.50001);
+ def->set_num(val);
+ kill_def(blend_def, the_dict + dBlend);
+ } else if (def && !blend_def && force_integer) {
+ double val;
+ if (def->value_num(val))
+ def->set_num(floor(val + 0.50001));
+ }
+}
+
+void
+MyFont::interpolate_dict_numvec(PermString name, Dict the_dict, int round_mode, bool executable)
+{
+ Type1Definition *def = dict(the_dict, name);
+ Type1Definition *blend_def = dict(the_dict + dBlend, name);
+ Vector<NumVector> blend;
+
+ if (def && blend_def && blend_def->value_numvec_vec(blend)) {
+ int n = blend.size();
+ NumVector val;
+ for (int i = 0; i < n; i++) {
+ double d = 0;
+ for (int m = 0; m < _nmasters; m++)
+ d += blend[i][m] * _weight_vector[m];
+ if (round_mode == 2 && i < 2)
+ d = floor(d - 0.50001);
+ else if (round_mode)
+ d = floor(d + 0.50001);
+ val.push_back(d);
+ }
+ def->set_numvec(val, executable);
+ kill_def(blend_def, the_dict + dBlend);
+ }
+}
+
+void
+MyFont::interpolate_dicts(bool force_integer, ErrorHandler *errh)
+{
+ // Unfortunately, some programs (acroread) expect the FontBBox to consist
+ // of integers. Round its elements away from zero (this is what the
+ // Acrobat distiller seems to do).
+ interpolate_dict_numvec("FontBBox", dFont, 2, true);
+
+ interpolate_dict_numvec("BlueValues", dPrivate, force_integer);
+ interpolate_dict_numvec("OtherBlues", dPrivate, force_integer);
+ interpolate_dict_numvec("FamilyBlues", dPrivate, force_integer);
+ interpolate_dict_numvec("FamilyOtherBlues", dPrivate, force_integer);
+ interpolate_dict_numvec("StdHW", dPrivate);
+ interpolate_dict_numvec("StdVW", dPrivate);
+ interpolate_dict_numvec("StemSnapH", dPrivate);
+ interpolate_dict_numvec("StemSnapV", dPrivate);
+
+ interpolate_dict_num("BlueScale", dPrivate);
+ interpolate_dict_num("BlueShift", dPrivate, force_integer);
+ interpolate_dict_int("BlueFuzz", dPrivate, errh);
+
+ {
+ Type1Definition *def = p_dict("ForceBold");
+ Type1Definition *blend_def = bp_dict("ForceBold");
+ Type1Definition *thresh = p_dict("ForceBoldThreshold");
+ Vector<PermString> namevec;
+ double thresh_val;
+ if (def && blend_def && thresh && blend_def->value_namevec(namevec)
+ && thresh->value_num(thresh_val) && namevec.size() == _nmasters) {
+ double v = 0;
+ for (int m = 0; m < _nmasters; m++)
+ if (namevec[m] == "true")
+ v += _weight_vector[m];
+ def->set_code(v >= thresh_val ? "true" : "false");
+ kill_def(blend_def, dBlendPrivate);
+ }
+ }
+
+ interpolate_dict_num("UnderlinePosition", dFontInfo);
+ interpolate_dict_num("UnderlineThickness", dFontInfo);
+ interpolate_dict_num("ItalicAngle", dFontInfo);
+
+ if (Type1Definition *def = bp_dict("BuildCharArray"))
+ kill_def(def, dBlendPrivate);
+
+ for (DictHashMap::const_iterator i = dict_begin(dBlend); i; i++) {
+ PermString name = i.key();
+ if (i.value() && name != "Private" && name != "FontInfo"
+ && name != "ConvertDesignVector" && name != "NormalizeDesignVector")
+ errh->warning("didn't interpolate %s in Blend", name.c_str());
+ }
+
+ for (DictHashMap::const_iterator i = dict_begin(dBlendPrivate); i; i++)
+ if (i.value() && i.key() != "Erode")
+ errh->warning("didn't interpolate %s in BlendPrivate", i.key().c_str());
+
+ kill_def(p_dict("NDV"), dPrivate);
+ kill_def(p_dict("CDV"), dPrivate);
+ kill_def(p_dict("UniqueID"), dPrivate);
+ kill_def(fi_dict("BlendDesignPositions"), dFontInfo);
+ kill_def(fi_dict("BlendDesignMap"), dFontInfo);
+ kill_def(fi_dict("BlendAxisTypes"), dFontInfo);
+}
+
+void
+MyFont::interpolate_charstrings(int precision, ErrorHandler *errh)
+{
+ Type1MMRemover remover(this, _weight_vector, precision, errh);
+ remover.run();
+}
diff --git a/Build/source/texk/lcdf-typetools/mmpfb/myfont.hh b/Build/source/texk/lcdf-typetools/mmpfb/myfont.hh
new file mode 100644
index 00000000000..9b29a9f4111
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/mmpfb/myfont.hh
@@ -0,0 +1,31 @@
+#ifndef MYFONT_HH
+#define MYFONT_HH
+#include <efont/t1font.hh>
+namespace Efont { class MultipleMasterSpace; }
+class ErrorHandler;
+
+class MyFont : public Efont::Type1Font { public:
+
+ MyFont(Efont::Type1Reader &);
+ ~MyFont();
+
+ bool set_design_vector(Efont::MultipleMasterSpace *, const Vector<double> &, ErrorHandler * = 0);
+
+ void interpolate_dicts(bool force_integers, ErrorHandler *);
+ void interpolate_charstrings(int precision, ErrorHandler * = 0);
+
+ private:
+
+ typedef Vector<double> NumVector;
+
+ int _nmasters;
+ Vector<double> _weight_vector;
+
+ void interpolate_dict_int(PermString, Dict, ErrorHandler *);
+ void interpolate_dict_num(PermString, Dict, bool round_integer = false);
+ void interpolate_dict_numvec(PermString, Dict, int round_mode = 0, bool executable = false);
+ void kill_def(Efont::Type1Definition *, int which_dict = -1);
+
+};
+
+#endif
diff --git a/Build/source/texk/lcdf-typetools/mmpfb/t1minimize.cc b/Build/source/texk/lcdf-typetools/mmpfb/t1minimize.cc
new file mode 100644
index 00000000000..4d970a15c7d
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/mmpfb/t1minimize.cc
@@ -0,0 +1,41 @@
+/* t1minimize.cc -- make minimal copy of a Type 1 font
+ *
+ * Copyright (c) 2003-2006 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "t1minimize.hh"
+#include <efont/t1item.hh>
+#include <stdio.h>
+
+using namespace Efont;
+
+Type1Font *
+minimize(Type1Font *font)
+{
+ Vector<double> xuid_extension;
+ xuid_extension.push_back(0x000395C1);
+ Type1Font *output = Type1Font::skeleton_make_copy(font, font->font_name(), &xuid_extension);
+
+ // Subrs
+ for (int i = 0; i < font->nsubrs(); i++)
+ if (Type1Subr *s = font->subr_x(i))
+ output->set_subr(s->subrno(), s->t1cs(), s->definer());
+
+ // CharStrings
+ for (int i = 0; i < font->nglyphs(); i++)
+ if (Type1Subr *g = font->glyph_x(i))
+ output->add_glyph(Type1Subr::make_glyph(g->name(), g->t1cs(), g->definer()));
+
+ return output;
+}
diff --git a/Build/source/texk/lcdf-typetools/mmpfb/t1minimize.hh b/Build/source/texk/lcdf-typetools/mmpfb/t1minimize.hh
new file mode 100644
index 00000000000..a5c3ea04906
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/mmpfb/t1minimize.hh
@@ -0,0 +1,7 @@
+#ifndef EFONT_T1MINIMIZE_HH
+#define EFONT_T1MINIMIZE_HH
+#include <efont/t1font.hh>
+
+Efont::Type1Font *minimize(Efont::Type1Font *);
+
+#endif
diff --git a/Build/source/texk/lcdf-typetools/mmpfb/t1rewrit.cc b/Build/source/texk/lcdf-typetools/mmpfb/t1rewrit.cc
new file mode 100644
index 00000000000..2c402964626
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/mmpfb/t1rewrit.cc
@@ -0,0 +1,922 @@
+/* t1rewrit.cc -- routines for multiple- to single-master charstring conversion
+ *
+ * Copyright (c) 1997-2006 Eddie Kohler
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version. This program is distributed in the hope that it will be
+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+ * Public License for more details.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "t1rewrit.hh"
+#include <efont/t1item.hh>
+#include <efont/t1csgen.hh>
+#include <lcdf/error.hh>
+#include <lcdf/straccum.hh>
+#include <stdio.h>
+#include <math.h>
+
+using namespace Efont;
+
+static bool itc_complained = false;
+static ErrorHandler *itc_errh;
+
+void
+itc_complain()
+{
+ //itc_errh->warning("strange `callothersubr'; is this an ITC font?");
+ itc_complained = true;
+}
+
+
+/*****
+ * HintReplacementDetector
+ **/
+
+class HintReplacementDetector : public CharstringInterp { public:
+
+ HintReplacementDetector(Type1Font *, int);
+ HintReplacementDetector(Type1Font *, const Vector<double> &, int);
+
+ bool is_hint_replacement(int i) const { return _hint_replacements[i] != 0; }
+ int call_count(int i) const { return _call_counts[i]; }
+
+ bool type1_command(int);
+
+ bool run(Type1Font *, Type1Charstring &);
+
+ private:
+
+ Vector<int> _hint_replacements;
+ Vector<int> _call_counts;
+ int _subr_level;
+ int _count_calls_below;
+
+};
+
+HintReplacementDetector::HintReplacementDetector(Type1Font *f, int b)
+ : CharstringInterp(),
+ _hint_replacements(f->nsubrs(), 0), _call_counts(f->nsubrs(), 0),
+ _count_calls_below(b)
+{
+}
+
+HintReplacementDetector::HintReplacementDetector(Type1Font *f, const Vector<double> &wv, int b)
+ : CharstringInterp(wv),
+ _hint_replacements(f->nsubrs(), 0), _call_counts(f->nsubrs(), 0),
+ _count_calls_below(b)
+{
+}
+
+bool
+HintReplacementDetector::type1_command(int cmd)
+{
+ switch (cmd) {
+
+ case Cs::cCallothersubr: {
+ if (size() < 2)
+ goto unknown;
+ int command = (int)top(0);
+ int n = (int)top(1);
+ if (command == Cs::othcReplacehints && n == 1) {
+ pop(2);
+ _hint_replacements[(int)top()] = 1;
+ ps_clear();
+ ps_push(top());
+ pop();
+ break;
+ } else if (command >= Cs::othcMM1 && command <= Cs::othcMM6) {
+ pop(2);
+ return mm_command(command, n);
+ } else if (command >= Cs::othcITC_load && command <= Cs::othcITC_random) {
+ pop(2);
+ return itc_command(command, n);
+ } else
+ goto unknown;
+ }
+
+ case Cs::cCallsubr: {
+ if (size() < 1)
+ return error(errUnderflow, cmd);
+ int which = (int)pop();
+ if (!_count_calls_below || _subr_level < _count_calls_below)
+ _call_counts[which]++;
+
+ Charstring *subr_cs = get_subr(which);
+ if (!subr_cs)
+ return error(errSubr, which);
+
+ _subr_level++;
+ subr_cs->process(*this);
+ _subr_level--;
+
+ if (error() != errOK)
+ return false;
+ return !done();
+ }
+
+ case Cs::cEndchar:
+ case Cs::cReturn:
+ return CharstringInterp::type1_command(cmd);
+
+ case Cs::cBlend:
+ case Cs::cAbs:
+ case Cs::cAdd:
+ case Cs::cSub:
+ case Cs::cDiv:
+ case Cs::cNeg:
+ case Cs::cRandom:
+ case Cs::cMul:
+ case Cs::cSqrt:
+ case Cs::cDrop:
+ case Cs::cExch:
+ case Cs::cIndex:
+ case Cs::cRoll:
+ case Cs::cDup:
+ case Cs::cAnd:
+ case Cs::cOr:
+ case Cs::cNot:
+ case Cs::cEq:
+ case Cs::cIfelse:
+ return arith_command(cmd);
+
+ case Cs::cPop:
+ if (ps_size() >= 1)
+ push(ps_pop());
+ break;
+
+ default:
+ unknown:
+ clear();
+ break;
+
+ }
+ return true;
+}
+
+bool
+HintReplacementDetector::run(Type1Font *f, Type1Charstring &cs)
+{
+ _subr_level = 0;
+ CharstringInterp::interpret(f, &cs);
+ return error() == errOK;
+}
+
+
+/*****
+ * Type1OneMMRemover
+ **/
+
+class Type1OneMMRemover: public CharstringInterp { public:
+
+ Type1OneMMRemover(Type1MMRemover *);
+
+ bool type1_command(int);
+
+ inline bool run_fresh_subr(const Type1Charstring &, bool);
+ inline bool run_fresh_glyph(const Type1Charstring &);
+ inline bool rerun_subr(const Type1Charstring &);
+
+ Type1Charstring *output_prefix();
+ void output_main(Type1Charstring &);
+
+ private:
+
+ Type1MMRemover *_remover;
+ Type1CharstringGen _prefix_gen;
+ Type1CharstringGen _main_gen;
+
+ int _subr_level;
+ bool _in_subr;
+ bool _in_prefix;
+ bool _must_expand;
+
+ inline void run_subr(Type1Charstring *);
+ bool itc_command(int command, int on_stack);
+
+ bool run(const Type1Charstring &, bool, bool, bool);
+
+};
+
+/* For version 1.1
+ *
+ * Problem: Sometimes a charstring will call one subroutine, which will call
+ * another, etc., which finally does a multiple master CallOtherSubr! The
+ * required arguments might build up only gradually over all the subrs. This
+ * makes it hard to remove the eventual CallOtherSubr!
+ *
+ * Partial solution: Divide each subroutine into two parts: the initial
+ * "prefix" contains the closure of any initial multiple-master commands
+ * (including those from sub-subroutines), the following "main" part has all
+ * the other commands. In a situation like this:
+ *
+ * subr-1 = 8 15 callothersubr pop pop pop return
+ * subr-2 = 4 5 6 1 callsubr return
+ * subr-3 = 1 2 3 2 callsubr return
+ *
+ * we'll divide it up like this: (prefix || main)
+ *
+ * subr-1 = 8 15 callothersubr pop pop pop || (nothing)
+ * subr-2 = 4 5 6 8 15 callothersubr pop pop pop || (nothing)
+ * subr-3 = 1 2 3 4 5 6 8 15 callothersubr pop pop pop || (nothing)
+ *
+ * Now, when we call a subroutine, we EXECUTE its prefix part. Then, if its
+ * main part is nonempty, we output the original call to the subroutine to
+ * take care of the main part. */
+
+
+Type1OneMMRemover::Type1OneMMRemover(Type1MMRemover *remover)
+ : CharstringInterp(remover->weight_vector()),
+ _remover(remover), _prefix_gen(remover->precision()),
+ _main_gen(remover->precision())
+{
+}
+
+inline void
+Type1OneMMRemover::run_subr(Type1Charstring *cs)
+{
+ _subr_level++;
+ cs->process(*this);
+ _subr_level--;
+}
+
+bool
+Type1OneMMRemover::itc_command(int command, int on_stack)
+{
+ const Vector<double> &weight = weight_vector();
+ assert(weight.size());
+ Vector<double> *scratch = scratch_vector();
+ Type1CharstringGen *gen =
+ (_in_prefix ? &_prefix_gen : (_in_subr ? &_main_gen : 0));
+
+ int base = size() - on_stack - 2;
+ switch (command) {
+
+ case Cs::othcITC_load: {
+ if (on_stack != 1)
+ return false;
+ int offset = (int)at(base);
+ for (int i = 0; i < weight.size(); i++)
+ vec(scratch, offset+i) = weight.at_u(i);
+ // save load command, so we expand its effects into the scratch
+ // vector
+ if (gen) {
+ gen->gen_number(offset);
+ gen->gen_number(1);
+ gen->gen_number(Cs::othcITC_load);
+ gen->gen_command(Cs::cCallothersubr);
+ }
+ break;
+ }
+
+ case Cs::othcITC_put: {
+ if (on_stack != 2)
+ return false;
+ int offset = (int)at(base+1);
+ vec(scratch, offset) = at(base);
+ // save put command, so we expand its effects into the scratch
+ // vector
+ if (gen) {
+ gen->gen_number(at(base));
+ gen->gen_number(offset);
+ gen->gen_number(2);
+ gen->gen_number(Cs::othcITC_put);
+ gen->gen_command(Cs::cCallothersubr);
+ }
+ break;
+ }
+
+ case Cs::othcITC_get: {
+ if (on_stack != 1)
+ return false;
+ int offset = (int)at(base);
+ double d = vec(scratch, offset);
+ if (!KNOWN(d)) {
+ _must_expand = true;
+ return false;
+ }
+ ps_push(d);
+ break;
+ }
+
+ case Cs::othcITC_add: {
+ if (on_stack != 2)
+ return false;
+ ps_push(at(base) + at(base+1));
+ break;
+ }
+
+ case Cs::othcITC_sub: {
+ if (on_stack != 2)
+ return false;
+ ps_push(at(base) - at(base+1));
+ break;
+ }
+
+ case Cs::othcITC_mul: {
+ if (on_stack != 2)
+ return false;
+ ps_push(at(base) * at(base+1));
+ break;
+ }
+
+ case Cs::othcITC_div: {
+ if (on_stack != 2)
+ return false;
+ ps_push(at(base) / at(base+1));
+ break;
+ }
+
+ case Cs::othcITC_ifelse: {
+ if (on_stack != 4)
+ return false;
+ if (at(base+2) <= at(base+3))
+ ps_push(at(base));
+ else
+ ps_push(at(base+1));
+ break;
+ }
+
+ default:
+ return false;
+
+ }
+
+ pop(on_stack + 2);
+ return true;
+}
+
+bool
+Type1OneMMRemover::type1_command(int cmd)
+{
+ switch (cmd) {
+
+ case Cs::cCallothersubr: {
+ // Expand known othersubr calls. If we cannot expand the othersubr
+ // call completely, then write it to the expander.
+ if (size() < 2)
+ goto partial_othersubr;
+ int command = (int)top(0);
+ int n = (int)top(1);
+ if (command >= Cs::othcITC_load && command <= Cs::othcITC_random) {
+ if (!itc_complained)
+ itc_complain();
+ if (size() < 2 + n || !itc_command(command, n))
+ goto partial_othersubr;
+ } else if (command >= Cs::othcMM1 && command <= Cs::othcMM6) {
+ if (size() < 2 + n)
+ goto partial_othersubr;
+ pop(2);
+ mm_command(command, n);
+ } else
+ goto normal;
+ break;
+ }
+
+ partial_othersubr: {
+ if (!_in_prefix) {
+ _must_expand = true;
+ goto normal;
+ }
+ _prefix_gen.gen_stack(*this, 0);
+ _prefix_gen.gen_command(Cs::cCallothersubr);
+ break;
+ }
+
+ case Cs::cCallsubr: {
+ // expand subroutines in line if necessary
+ if (size() < 1)
+ goto normal;
+ int subrno = (int)pop();
+ if (_subr_level < 1) { // otherwise, have already included prefix
+ if (Type1Charstring *cs = _remover->subr_prefix(subrno))
+ run_subr(cs);
+ }
+ if (Type1Charstring *cs = _remover->subr_expander(subrno))
+ run_subr(cs);
+ else {
+ push(subrno);
+ goto normal;
+ }
+ break;
+ }
+
+ case Cs::cPop:
+ if (ps_size() >= 1)
+ push(ps_pop());
+ else if (_in_prefix && ps_size() == 0) {
+ _prefix_gen.gen_stack(*this, 0);
+ _prefix_gen.gen_command(Cs::cPop);
+ } else
+ goto normal;
+ break;
+
+ case Cs::cDiv:
+ if (size() < 2)
+ goto normal;
+ top(1) /= top(0);
+ pop();
+ break;
+
+ case Cs::cReturn:
+ return false;
+
+ normal:
+ default:
+ _main_gen.gen_stack(*this, cmd);
+ _main_gen.gen_command(cmd);
+ _in_prefix = 0;
+ return (cmd != Cs::cEndchar);
+
+ }
+ return true;
+}
+
+
+bool
+Type1OneMMRemover::run(const Type1Charstring &cs,
+ bool in_subr, bool do_prefix, bool fresh)
+{
+ _prefix_gen.clear();
+ _main_gen.clear();
+ _in_subr = in_subr;
+ _in_prefix = do_prefix;
+ _subr_level = (fresh ? 0 : 1);
+ _must_expand = false;
+ Vector<double> *scratch = scratch_vector();
+ scratch->assign(scratch->size(), UNKDOUBLE);
+
+ CharstringInterp::interpret(_remover->program(), &cs);
+
+ if (in_subr) {
+ _main_gen.gen_stack(*this, Cs::cReturn);
+ _main_gen.gen_command(Cs::cReturn);
+ }
+ if (_must_expand)
+ return true;
+ if (fresh && in_subr) {
+ if (_main_gen.length() == 0
+ || (_main_gen.length() == 1 && _main_gen.data()[0] == Cs::cReturn))
+ return true;
+ }
+ return false;
+}
+
+inline bool
+Type1OneMMRemover::run_fresh_subr(const Type1Charstring &cs, bool do_prefix)
+{
+ return run(cs, true, do_prefix, true);
+}
+
+inline bool
+Type1OneMMRemover::run_fresh_glyph(const Type1Charstring &cs)
+{
+ return run(cs, false, false, true);
+}
+
+inline bool
+Type1OneMMRemover::rerun_subr(const Type1Charstring &cs)
+{
+ return run(cs, true, false, false);
+}
+
+Type1Charstring *
+Type1OneMMRemover::output_prefix()
+{
+ if (_prefix_gen.length() > 0) {
+ _prefix_gen.gen_command(Cs::cReturn);
+ return _prefix_gen.output();
+ } else
+ return 0;
+}
+
+void
+Type1OneMMRemover::output_main(Type1Charstring &cs)
+{
+ _main_gen.output(cs);
+}
+
+
+/*****
+ * Type1BadCallRemover
+ **/
+
+class Type1BadCallRemover: public CharstringInterp { public:
+
+ Type1BadCallRemover(Type1MMRemover *);
+
+ bool type1_command(int);
+
+ bool run(Type1Charstring &);
+
+ private:
+
+ Type1CharstringGen _gen;
+ Type1MMRemover *_remover;
+
+};
+
+Type1BadCallRemover::Type1BadCallRemover(Type1MMRemover *remover)
+ : CharstringInterp(remover->weight_vector()),
+ _gen(remover->precision()), _remover(remover)
+{
+}
+
+bool
+Type1BadCallRemover::type1_command(int cmd)
+{
+ switch (cmd) {
+
+ case Cs::cCallsubr: {
+ if (size() < 1)
+ goto normal;
+ int subrno = (int)top();
+ if (!get_subr(subrno)) {
+ pop();
+ return false;
+ } else
+ goto normal;
+ }
+
+ normal:
+ default:
+ _gen.gen_stack(*this, 0);
+ _gen.gen_command(cmd);
+ return (cmd != Cs::cEndchar && cmd != Cs::cReturn);
+
+ }
+}
+
+bool
+Type1BadCallRemover::run(Type1Charstring &cs)
+{
+ _gen.clear();
+ CharstringInterp::interpret(_remover->program(), &cs);
+ _gen.output(cs);
+ return error() == errOK;
+}
+
+
+/*****
+ * Type1MMRemover
+ **/
+
+Type1MMRemover::Type1MMRemover(Type1Font *font, const Vector<double> &wv,
+ int precision, ErrorHandler *errh)
+ : _font(font), _weight_vector(wv), _precision(precision),
+ _nsubrs(font->nsubrs()),
+ _subr_done(_nsubrs, 0),
+ _subr_prefix(_nsubrs, (Type1Charstring *)0),
+ _must_expand_subr(_nsubrs, 0),
+ _hint_replacement_subr(_nsubrs, 0),
+ _expand_all_subrs(false), _errh(errh)
+{
+ itc_errh = _errh;
+
+ // find subroutines needed for hint replacement
+ HintReplacementDetector hr(font, wv, 0);
+ for (int i = 0; i < _font->nglyphs(); i++)
+ if (Type1Subr *g = _font->glyph_x(i))
+ hr.run(font, g->t1cs());
+ for (int i = 0; i < _nsubrs; i++)
+ if (hr.is_hint_replacement(i))
+ _hint_replacement_subr[i] = 1;
+
+ // don't get rid of first 4 subrs
+ for (int i = 0; i < _nsubrs && i < 4; i++)
+ _subr_done[i] = 1;
+}
+
+Type1MMRemover::~Type1MMRemover()
+{
+ for (int i = 0; i < _nsubrs; i++)
+ if (_subr_prefix[i])
+ delete _subr_prefix[i];
+}
+
+
+Type1Charstring *
+Type1MMRemover::subr_prefix(int subrno)
+{
+ if (subrno < 0 || subrno >= _nsubrs)
+ return 0;
+
+ if (!_subr_done[subrno]) {
+ _subr_done[subrno] = 1;
+
+ Type1Charstring *subr = _font->subr(subrno);
+ if (!subr)
+ return 0;
+
+ Type1OneMMRemover one(this);
+ if (one.run_fresh_subr(*subr, !_hint_replacement_subr[subrno]))
+ _must_expand_subr[subrno] = true;
+ _subr_prefix[subrno] = one.output_prefix();
+ one.output_main(*subr);
+ }
+
+ return _subr_prefix[subrno];
+}
+
+Type1Charstring *
+Type1MMRemover::subr_expander(int subrno)
+{
+ if (subrno < 0 || subrno >= _nsubrs)
+ return 0;
+ if (!_subr_done[subrno])
+ (void)subr_prefix(subrno);
+ if (!_expand_all_subrs && !_must_expand_subr[subrno])
+ return 0;
+ return _font->subr(subrno);
+}
+
+extern "C" {
+static int CDECL
+sort_permstring_compare(const void *v1, const void *v2)
+{
+ const PermString *s1 = (const PermString *)v1;
+ const PermString *s2 = (const PermString *)v2;
+ return strcmp(s1->c_str(), s2->c_str());
+}
+}
+
+void
+Type1MMRemover::run()
+{
+ Type1OneMMRemover one(this);
+
+ // check subroutines
+ for (int subrno = 0; subrno < _nsubrs; subrno++)
+ (void)subr_prefix(subrno);
+
+ // expand glyphs
+ Vector<PermString> bad_glyphs;
+ for (int i = 0; i < _font->nglyphs(); i++) {
+ Type1Subr *g = _font->glyph_x(i);
+ if (g) {
+ if (one.run_fresh_glyph(g->t1cs())) {
+ // Every glyph should be fully expandable without encountering
+ // a MM command. If we fail the first time, try again,
+ // expanding ALL subroutines. This catches, for example, SUBR
+ // 1 { 1 0 return }; GLYPH g { 1 callsubr 2 blend }; This will
+ // fail the first time, because `1 callsubr' will be left as a
+ // subroutine call, so `1 0' (required arguments to `blend')
+ // won't be visible.
+ _expand_all_subrs = true;
+ if (one.run_fresh_glyph(g->t1cs()))
+ bad_glyphs.push_back(g->name());
+ _expand_all_subrs = false;
+ }
+ one.output_main(g->t1cs());
+ }
+ }
+
+ // remove uncalled subroutines, expand hint replacement subroutines
+ HintReplacementDetector hr(_font, _weight_vector, 0);
+ for (int i = 0; i < _font->nglyphs(); i++)
+ if (Type1Subr *g = _font->glyph_x(i))
+ hr.run(_font, g->t1cs());
+ // don't remove first four subroutines!
+ for (int subrno = 4; subrno < _nsubrs; subrno++)
+ if (hr.call_count(subrno) || _hint_replacement_subr[subrno]) {
+ Type1Charstring *cs = _font->subr(subrno);
+ if (one.rerun_subr(*cs)) {
+ _expand_all_subrs = true;
+ if (one.rerun_subr(*cs))
+ bad_glyphs.push_back(permprintf("subr %d", subrno));
+ _expand_all_subrs = false;
+ }
+ one.output_main(*cs);
+ } else
+ _font->remove_subr(subrno);
+
+ // remove calls to removed subroutines
+ Type1BadCallRemover bcr(this);
+ for (int i = 0; i < _font->nglyphs(); i++)
+ if (Type1Subr *g = _font->glyph_x(i))
+ bcr.run(g->t1cs());
+ for (int subrno = 4; subrno < _nsubrs; subrno++)
+ if (Type1Charstring *cs = _font->subr(subrno))
+ bcr.run(*cs);
+
+ // report warnings
+ if (bad_glyphs.size()) {
+ qsort(&bad_glyphs[0], bad_glyphs.size(), sizeof(PermString), sort_permstring_compare);
+ _errh->error("could not fully interpolate the following glyphs:");
+ StringAccum sa;
+ for (int i = 0; i < bad_glyphs.size(); i++) {
+ PermString n = bad_glyphs[i];
+ bool comma = (i < bad_glyphs.size() - 1);
+ if (sa.length() && sa.length() + 1 + n.length() + comma > 70) {
+ _errh->message(" %s", sa.c_str());
+ sa.clear();
+ }
+ sa << (sa.length() ? " " : "") << n << (comma ? "," : "");
+ }
+ _errh->message(" %s", sa.c_str());
+ }
+}
+
+
+/*****
+ * SubrExpander
+ **/
+
+class SubrExpander : public CharstringInterp { public:
+
+ SubrExpander();
+
+ void set_renumbering(const Vector<int> *v) { _renumbering = v; }
+
+ bool type1_command(int);
+
+ bool run(Type1Font *, Type1Charstring &);
+
+ private:
+
+ Type1CharstringGen _gen;
+ const Vector<int> *_renumbering;
+ int _subr_level;
+
+};
+
+SubrExpander::SubrExpander()
+ : CharstringInterp(), _gen(0), _renumbering(0)
+{
+}
+
+bool
+SubrExpander::type1_command(int cmd)
+{
+ switch (cmd) {
+
+ case Cs::cCallsubr: {
+ if (size() < 1)
+ goto unknown;
+ int subrno = (int)top(0);
+ int renumber_subrno = (subrno >= 0 && subrno < _renumbering->size() ? (*_renumbering)[subrno] : subrno);
+ if (renumber_subrno >= 0) {
+ top(0) = renumber_subrno;
+ goto unknown;
+ }
+ pop();
+ if (Charstring *subr_cs = get_subr(subrno)) {
+ _subr_level++;
+ subr_cs->process(*this);
+ _subr_level--;
+ }
+ return !done();
+ }
+
+ case Cs::cEndchar:
+ set_done();
+ goto end_cs;
+
+ case Cs::cReturn:
+ if (_subr_level)
+ return false;
+ goto end_cs;
+
+ end_cs:
+ _gen.gen_stack(*this, cmd);
+ _gen.gen_command(cmd);
+ return false;
+
+ default:
+ unknown:
+ _gen.gen_stack(*this, cmd);
+ _gen.gen_command(cmd);
+ break;
+
+ }
+ return true;
+}
+
+bool
+SubrExpander::run(Type1Font *font, Type1Charstring &cs)
+{
+ _gen.clear();
+ _subr_level = 0;
+ CharstringInterp::interpret(font, &cs);
+ _gen.output(cs);
+ return error() == errOK;
+}
+
+
+/*****
+ * Type1SubrRemover
+ **/
+
+Type1SubrRemover::Type1SubrRemover(Type1Font *font, ErrorHandler *errh)
+ : _font(font), _nsubrs(font->nsubrs()),
+ _renumbering(_nsubrs, REMOVABLE), _cost(_nsubrs, 0),
+ _save_count(0), _nonexist_count(0), _errh(errh)
+{
+ // find subroutines needed for hint replacement
+ HintReplacementDetector hr(font, 2);
+ for (int i = 0; i < _font->nglyphs(); i++) {
+ Type1Subr *g = _font->glyph_x(i);
+ if (g)
+ hr.run(_font, g->t1cs());
+ }
+
+ // save necessary subroutines
+ for (int i = 0; i < 4; i++) {
+ _renumbering[i] = i;
+ _save_count++;
+ }
+ // save hint-replacement subroutines
+ for (int i = 0; i < _nsubrs; i++) {
+ Type1Subr *cs = _font->subr_x(i);
+ if (!cs) {
+ _renumbering[i] = DEAD;
+ _nonexist_count++;
+ } else if (hr.is_hint_replacement(i)) {
+ _renumbering[i] = i;
+ _save_count++;
+ } else
+ _cost[i] = hr.call_count(i) * (cs->t1cs().length() - (i <= 107 ? 2 : 3));
+ }
+}
+
+Type1SubrRemover::~Type1SubrRemover()
+{
+}
+
+static Vector<int> *sort_keys;
+
+extern "C" {
+static int CDECL
+sort_permute_compare(const void *v1, const void *v2)
+{
+ const int *i1 = (const int *)v1;
+ const int *i2 = (const int *)v2;
+ return (*sort_keys)[*i1] - (*sort_keys)[*i2];
+}
+}
+
+bool
+Type1SubrRemover::run(int lower_to)
+{
+ if (lower_to < 0)
+ lower_to = _nsubrs;
+ if (lower_to < _save_count) {
+ _errh->warning("reducing %s to minimum number of subroutines (%d)",
+ _font->font_name().c_str(), _save_count - _nonexist_count);
+ lower_to = _save_count;
+ }
+ int to_remove = _nsubrs - _nonexist_count - lower_to;
+ if (to_remove < 0)
+ to_remove = 0;
+
+ // multiply by lost bytes per call
+ Vector<int> permute;
+ for (int i = 0; i < _nsubrs; i++)
+ permute.push_back(i);
+
+ // sort them by least frequent use -> most frequent use
+ sort_keys = &_cost;
+ qsort(&permute[0], _nsubrs, sizeof(int), sort_permute_compare);
+
+ // mark first portion of `permute' to be removed
+ int removed = 0;
+ for (int i = 0; i < _nsubrs; i++) {
+ int p = permute[i];
+ if (_renumbering[p] == REMOVABLE && removed < to_remove) {
+ _renumbering[p] = DEAD;
+ removed++;
+ }
+ }
+
+ // renumber the rest
+ int renumber_pos = 0;
+ for (int i = 0; i < _nsubrs; i++)
+ if (_renumbering[i] == REMOVABLE) { // save it
+ while (_renumbering[renumber_pos] >= 0)
+ renumber_pos++;
+ _renumbering[i] = renumber_pos++;
+ }
+ SubrExpander rem0;
+ rem0.set_renumbering(&_renumbering);
+
+ // go through and change them all
+ for (int i = 0; i < _nsubrs; i++) {
+ Type1Subr *s = _font->subr_x(i);
+ if (s && _renumbering[i] >= 0)
+ rem0.run(_font, s->t1cs());
+ }
+ for (int i = 0; i < _font->nglyphs(); i++)
+ if (Type1Subr *g = _font->glyph_x(i))
+ rem0.run(_font, g->t1cs());
+
+ // actually remove subroutines
+ _font->renumber_subrs(_renumbering);
+
+ return true;
+}
diff --git a/Build/source/texk/lcdf-typetools/mmpfb/t1rewrit.hh b/Build/source/texk/lcdf-typetools/mmpfb/t1rewrit.hh
new file mode 100644
index 00000000000..238f93dc630
--- /dev/null
+++ b/Build/source/texk/lcdf-typetools/mmpfb/t1rewrit.hh
@@ -0,0 +1,68 @@
+#ifndef T1REWRIT_HH
+#define T1REWRIT_HH
+#include <efont/t1interp.hh>
+#include <efont/t1font.hh>
+#include <lcdf/straccum.hh>
+
+class Type1MMRemover { public:
+
+ Type1MMRemover(Efont::Type1Font *, const Vector<double> &weight_vec, int, ErrorHandler *);
+ ~Type1MMRemover();
+
+ Efont::CharstringProgram *program() const { return _font; }
+ const Vector<double> &weight_vector() const { return _weight_vector; }
+ int nmasters() const { return _weight_vector.size(); }
+ int precision() const { return _precision; }
+
+ Efont::Type1Charstring *subr_prefix(int);
+ Efont::Type1Charstring *subr_expander(int);
+
+ void run();
+
+ private:
+
+ Efont::Type1Font *_font;
+ Vector<double> _weight_vector;
+ int _precision;
+
+ int _nsubrs;
+ Vector<int> _subr_done;
+ Vector<Efont::Type1Charstring *> _subr_prefix;
+ Vector<int> _must_expand_subr;
+ Vector<int> _hint_replacement_subr;
+ bool _expand_all_subrs;
+
+ ErrorHandler *_errh;
+
+};
+
+
+class Type1SubrRemover { public:
+
+ Type1SubrRemover(Efont::Type1Font *, ErrorHandler *);
+ ~Type1SubrRemover();
+
+ Efont::CharstringProgram *program() const { return _font; }
+ ErrorHandler *errh() const { return _errh; }
+
+ int save_count() const { return _save_count; }
+
+ bool run(int);
+
+ private:
+
+ Efont::Type1Font *_font;
+
+ int _nsubrs;
+ enum { REMOVABLE = -1, DEAD = -2 };
+ Vector<int> _renumbering;
+ Vector<int> _cost;
+ int _save_count;
+ int _nonexist_count;
+
+ ErrorHandler *_errh;
+
+};
+
+
+#endif