FreeType 1.31.1

This commit is contained in:
2023-08-27 18:03:45 +02:00
commit 5edbb7a80a
454 changed files with 173977 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
ttf2tfm
ttf2pk
.libs
MakeSub
config.status
config.cache
config.log
Makefile

3
contrib/ttf2pk/BUGS Normal file
View File

@@ -0,0 +1,3 @@
Some characters (Arial A) have a bounding box that extends outside the
character width... such a character will get an italic correction.

View File

@@ -0,0 +1,6 @@
# This file is part of the ttf2pk package
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@

View File

@@ -0,0 +1,71 @@
# Makefile for ttf2pk -- loyer@enst.fr, wl@gnu.org
#
# This Makefile assumes that you've already built and installed
# the FreeType library.
#
# It builds the ttf2pk and ttf2tfm for emx-gcc.
#
# You will need dmake.
#
# Use this file while with the following statement:
#
# dmake -r -f Makefile.dm
.IMPORT: COMSPEC
SHELL := $(COMSPEC)
SHELLFLAGS := /c
GROUPSHELL := $(SHELL)
GROUPFLAGS := $(SHELLFLAGS)
GROUPSUFFIX := .bat
SHELLMETAS := *"?<>&|
CC = gcc
LIBDIR = ../../lib
INCDIR = -I$(LIBDIR) -I.
# CFLAGS = -Wall -O2 -g $(INCDIR) -fbounds-checking -DHAVE_EMTEXDIR -DMSDOS
CFLAGS = -Wall -O2 -s $(INCDIR) -DHAVE_EMTEXDIR -DMSDOS
SRC = case.c emdir.c emtexdir.c errormsg.c filesrch.c ligkern.c newobj.c \
parse.c pklib.c subfont.c texenc.c tfmaux.c ttf2pk.c ttf2tfm.c \
ttfaux.c ttfenc.c ttflib.c vplaux.c
ttf2pkobjs = emdir.o emtexdir.o errormsg.o filesrch.o ligkern.o newobj.o \
parse.o pklib.o subfont.o texenc.o ttf2pk.o ttfenc.o ttflib.o
ttf2tfmobjs = case.o emdir.o emtexdir.o errormsg.o filesrch.o ligkern.o \
newobj.o parse.o subfont.o texenc.o tfmaux.o ttf2tfm.o \
ttfaux.o ttfenc.o vplaux.o
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $<
%.exe:
$(CC) $(CFLAGS) -o $@ @$(mktmp $(&:t"\n")\n)
PROGRAMS = ttf2pk.exe ttf2tfm.exe
.PHONY: all clean distclean
all: $(PROGRAMS)
ttf2pk.exe: $(ttf2pkobjs) $(LIBDIR)/libttf.a
ttf2tfm.exe: $(ttf2tfmobjs) $(LIBDIR)/libttf.a
clean:
-[
del *.o
]
distclean: clean
-[
del dep.end
del *.exe
del core
]
#end of Makefile.dm

116
contrib/ttf2pk/Makefile.in Normal file
View File

@@ -0,0 +1,116 @@
# Makefile for ttf2pk -- loyer@enst.fr, wl@gnu.org
#
# This Makefile assumes that you've already built and installed
# the FreeType library.
VPATH = @srcdir@
srcdir = @srcdir@
RM = @RM@
RMF = @RM@ -f
RMDIR = @RMDIR@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
CC = @CC@
CPP = @CPP@
LIBTOOL = ../../libtool
MKINSTALLDIRS = $(srcdir)/../../mkinstalldirs
include MakeSub
CFLAGS = @CFLAGS@ @XX_CFLAGS@
CPPFLAGS = @CPPFLAGS@ @DEFS@
FT_CFLAGS = $(CFLAGS) $(CPPFLAGS)
LDFLAGS = @LDFLAGS@ @LIBS@
LIBDIR = ../../lib
SRC = $(srcdir)/case.c \
$(srcdir)/errormsg.c \
$(srcdir)/filesrch.c \
$(srcdir)/ligkern.c \
$(srcdir)/newobj.c \
$(srcdir)/parse.c \
$(srcdir)/pklib.c \
$(srcdir)/subfont.c \
$(srcdir)/texenc.c \
$(srcdir)/tfmaux.c \
$(srcdir)/ttf2pk.c \
$(srcdir)/ttf2tfm.c \
$(srcdir)/ttfaux.c \
$(srcdir)/ttfenc.c \
$(srcdir)/ttflib.c \
$(srcdir)/vplaux.c
ttf2pkobjs = errormsg.o filesrch.o ligkern.o newobj.o parse.o pklib.o \
subfont.o texenc.o ttf2pk.o ttfenc.o ttflib.o
ttf2tfmobjs = case.o errormsg.o filesrch.o ligkern.o newobj.o parse.o \
subfont.o texenc.o tfmaux.o ttf2tfm.o ttfaux.o ttfenc.o \
vplaux.o
.c.o:
$(CC) -c $(FT_CFLAGS) $<
PROGRAMS = ttf2pk ttf2tfm
default all: $(PROGRAMS)
ttf2pk: $(ttf2pkobjs) $(LIBDIR)/libttf.la
$(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) -o ttf2pk $(ttf2pkobjs) \
$(LIBDIR)/libttf.la $(LDFLAGS)
ttf2tfm: $(ttf2tfmobjs) $(LIBDIR)/libttf.la
$(LIBTOOL) --mode=link $(CC) $(FT_CFLAGS) -o ttf2tfm $(ttf2tfmobjs) \
$(LIBDIR)/libttf.la $(LDFLAGS)
install: $(PROGRAMS)
$(MKINSTALLDIRS) $(bindir) $(mandir)/man1
for P in $(PROGRAMS) ; do \
$(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$P $(bindir)/$$P ; \
$(INSTALL_DATA) $(srcdir)/$$P.1 $(mandir)/man1 ; \
done
uninstall:
-for P in $(PROGRAMS) ; do \
$(LIBTOOL) --mode=uninstall $(RM) $(bindir)/$$P ; \
$(RMF) $(mandir)/man1/$$P.1 ; \
done
clean: do_clean
distclean: do_clean
-$(RMF) dep.end $(PROGRAMS)
-$(RMF) *~ *.orig core *.core
-$(RMF) config.cache config.log config.status Makefile MakeSub
-$(RMF) .libs/*
-$(RMDIR) .libs
do_clean:
-$(RMF) *.o
depend:
(echo '/^#.* PUT NO STUFF BELOW/,$$d' ; echo w ; echo q) | \
ed - Makefile
echo '# Dependencies generated by make depend: PUT NO STUFF BELOW' \
>> Makefile
for file in $(SRC) ; do \
$(CPP) $(CPPFLAGS) $$file | \
sed -n -e 's|^# [1-9][0-9]* "\([^/].*\.h\)".*|\1|p' \
-e 's|^# [1-9][0-9]* "\($(srcdir)/.*\.h\)".*|\1|p' | \
sed -e 's|/\./|.|g' -e "s/^/`basename $$file .c`.o: /" ; \
done | \
sort -u | \
awk '{ if (LINE == 1) \
{ line = last = $$1 } \
else if ($$1 != last) \
{ print line ; line = last = $$1 } \
line = line " " $$2 } \
END { print line }' >> Makefile
# Dependencies generated by make depend: PUT NO STUFF BELOW

104
contrib/ttf2pk/README Normal file
View File

@@ -0,0 +1,104 @@
This directory contains ttf2tfm and ttf2pk, two utilities based on
afm2tfm (dvipsk distribution),
gsftopkk (dvipsk distribution),
and the FreeType rasterizer for TrueType fonts.
Compile the FreeType library first! It is recommended to use the kpathsea
library if you want to use the programs with web2c resp. teTeX. Source files
for emTeX-like search routines are included; similarly, support for MiKTeX
file searching routines is available if `MIKTEX' is defined during
compilation. Nevertheless, as a last resort, you can compile both programs
without a search library too.
The kpathsea library is *not* part of the ttf2pk package (see notes below).
Under UNIX-like systems say
./configure --prefix=/usr/local/TeX --with-kpathsea-dir=<DIR>
make
make install
for a normal compilation and installation. Replace `/usr/local/TeX' with a
path to your TeX distribution.
[Note 1:
Try to find `libkpathsea.*' on your system. Use the directory above this
one as the argument for --with-kpathsea-dir. This should work in most
cases. If you can't find the library, you probably have a web2c package
with statically linked binaries. This means that you have to get the web2c
sources from CTAN, configure it with something like
./configure --prefix=/usr/local/TeX --datadir=/usr/local/TeX \
--enable-shared --disable-static
according to your setup; then change to the kpathsea directory and say
`make' and `make install' (Do the latter with caution not to overwrite
binaries like kpsewhich).
It even works with the source tree from the TeX Live CD 3! You just have
to add a proper --srcdir option to the configure script.
Unfortunately, teTeX-0.4 uses a very old kpathsea library version without
automatical shared-library support, thus you have to install the static
libraries:
.) unpack the sources (basically you need only the contents of kpse-2.6
and the two subdirs `kpathsea' and `make'.
.) say
./configure --prefix=...
make
in the kpse-2.6 directory
.) say
make install-library
in the kpathsea subdirectory. See Note 2 also.
DON'T USE A NEWER KPATHSEA VERSION IF YOU USE teTeX 0.4 BINARIES! Newer
kpathsea versions are not compatible with version 2.6.
Note 2:
It seems that c-auto.h created during the kpathsea library compiling
process won't be installed for some older web2c versions. You should add
it manually, i.e., copy <web2c source tree>/kpathsea/c-auto.h to the
location where the other kpathsea header files have been installed.
Note 3:
If you want to use the --srcdir option of the configure script, you must
compile FreeType with --srcdir too. You have to use the same directory
structure to make it work (i.e., if you have said for FreeType
`./configure --srcdir=foo', and you are in the `bar' directory, FreeType's
configure script will generate all the needed subdirs for compiling
FreeType. You've then manually to add the directory `bar/contrib/ttf2pk';
there you should start to say ./configure --srcdir=foo/contrib/ttf2pk').]
Use Makefile.dm for emx + dmake and say
dmake -r -f Makefile.dm
[Note: It should work with djgpp too, but I haven't tested this.]
ttf2pk and ttf2tfm are already part of MiKTeX.
Primary author of afm2tfm: T. Rokicki,
Primary author of gsftopk: P.Vojta
Primary author of the kpathsea library,
afm2tfm/gsftopk adaptation: K. Berry.
--
Frederic Loyer <loyer@ensta.fr>
Werner Lemberg <wl@gnu.org>

22
contrib/ttf2pk/TODO Normal file
View File

@@ -0,0 +1,22 @@
. multiple configuration files similar to newer versions of gsftopk(k).
. support for different horizontal and vertical resolutions.
. character composition via the vpl file.
. using GSUB for accessing small caps (if available).
. enabling -v and -V at the same time.
. Omega support
. afm output
. possibility to create `real' fonts, i.e., avoiding virtual fonts for small
caps etc. -- some dvi previewers still can't handle virtual fonts. Due to
the huge amount of work to support this it is rather unlikely that I'll do
it.
. using hash tables to store glyph names for better performance
. show replacement glyphs too in glyph listings

23
contrib/ttf2pk/c-auto.h Normal file
View File

@@ -0,0 +1,23 @@
/*
* c-auto.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef C_AUTO_H
#define C_AUTO_H
/*
* We need to get kpathsea's configuration file.
*/
#include "kpathsea/c-auto.h"
#endif /* C_AUTO_H */
/* end */

179
contrib/ttf2pk/case.c Normal file
View File

@@ -0,0 +1,179 @@
/*
* case.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <stdlib.h> /* for definition of NULL */
#include "case.h"
/* This is a table of uppercase/lowercase pairs which can't be deduced */
/* by lowercasing the uppercase Adobe glyph name. */
/* It has been extracted from the ucs2ps.um database compiled by */
/* Bjorn Brox <brox@corena.no>. */
Case casetable[] =
{
{"afii10017", "afii10065"},
{"afii10018", "afii10066"},
{"afii10019", "afii10067"},
{"afii10020", "afii10068"},
{"afii10021", "afii10069"},
{"afii10022", "afii10070"},
{"afii10023", "afii10071"},
{"afii10024", "afii10072"},
{"afii10025", "afii10073"},
{"afii10026", "afii10074"},
{"afii10027", "afii10075"},
{"afii10028", "afii10076"},
{"afii10029", "afii10077"},
{"afii10030", "afii10078"},
{"afii10031", "afii10079"},
{"afii10032", "afii10080"},
{"afii10033", "afii10081"},
{"afii10034", "afii10082"},
{"afii10035", "afii10083"},
{"afii10036", "afii10084"},
{"afii10037", "afii10085"},
{"afii10038", "afii10086"},
{"afii10039", "afii10087"},
{"afii10040", "afii10088"},
{"afii10041", "afii10089"},
{"afii10042", "afii10090"},
{"afii10043", "afii10091"},
{"afii10044", "afii10092"},
{"afii10045", "afii10093"},
{"afii10046", "afii10094"},
{"afii10047", "afii10095"},
{"afii10048", "afii10096"},
{"afii10049", "afii10097"},
{"afii10050", "afii10098"},
{"afii10051", "afii10099"},
{"afii10052", "afii10100"},
{"afii10053", "afii10101"},
{"afii10054", "afii10102"},
{"afii10055", "afii10103"},
{"afii10056", "afii10104"},
{"afii10057", "afii10105"},
{"afii10058", "afii10106"},
{"afii10059", "afii10107"},
{"afii10060", "afii10108"},
{"afii10061", "afii10109"},
{"afii10062", "afii10110"},
{"afii10145", "afii10193"},
{"afii10146", "afii10194"},
{"afii10147", "afii10195"},
{"afii10148", "afii10196"},
{"afii10149", "afii10197"},
{"afii10152", "afii10200"},
{"afii10202", "afii10154"},
{"afii10155", "afii10203"},
{"afii10156", "afii10204"},
{"afii10157", "afii10205"},
{"afii10158", "afii10206"},
{"afii10160", "afii10208"},
{"afii10161", "afii10209"},
{"afii10162", "afii10210"},
{"afii10163", "afii10211"},
{"afii10164", "afii10212"},
{"afii10166", "afii10214"},
{"afii10167", "afii10215"},
{"afii10168", "afii10216"},
{"afii10170", "afii10218"},
{"afii10171", "afii10219"},
{"afii10172", "afii10220"},
{"afii10173", "afii10221"},
{"afii10174", "afii10222"},
{"afii10176", "afii10224"},
{"afii10178", "afii10226"},
{"afii10179", "afii10227"},
{"afii10181", "afii10229"},
{"afii10182", "afii10230"},
{"afii10184", "afii10232"},
{"afii10185", "afii10233"},
{"afii10187", "afii10235"},
{"afii10188", "afii10236"},
{"afii10190", "afii10238"},
{"afii10785", "afii10833"},
{"afii10786", "afii10834"},
{"afii10787", "afii10835"},
{"afii10795", "afii10843"},
{"afii10798", "afii10846"},
{"afii10799", "afii10847"},
{"afii10800", "afii10848"},
{"afii10801", "afii10849"},
{"afii64308", "afii64436"},
{"afii10803", "afii10851"},
{"afii10808", "afii10856"},
{"afii10809", "afii10857"},
{"afii10810", "afii10858"},
{"afii10811", "afii10859"},
{"afii10817", "afii10865"},
{"afii10818", "afii10866"},
{"afii10819", "afii10867"},
{"afii10822", "afii10870"},
{"afii10827", "afii10875"},
{"afii10914", "afii10962"},
{"afii10920", "afii10968"},
{"afii10924", "afii10972"},
{"afii10927", "afii10975"},
{"afii10929", "afii10977"},
{"afii10930", "afii10978"},
{"afii10931", "afii10979"},
{"afii10932", "afii10980"},
{"afii10934", "afii10982"},
{"afii10943", "afii10991"},
{"afii10944", "afii10992"},
{"afii10951", "afii10967"},
/*{? "ash"} */
{"Beta", "beta1"},
{"Bhook", "bhooktop"},
{"Chook", "chooktop"},
/*{"Oopen" "cturn" ?} */
{"Dbar1", "dbar"},
{"Dhook", "dhooktop"},
{"Dmacron", "dmacron3"},
{"Dslash", "dmacron"},
{"I", "dotlessi"},
{"J", "dotlessj"},
/*{"Dbar", "drighttail" ?} */
/*{"Dbar" "drthook" ?} */
/*{"Dslash", ?} */
{"Fhook", "fscript"},
{"Ghook", "ghooktop"},
{"Ibar", "ibarred"},
{"I", "iundotted"},
{"Kappa", "kappa1"},
{"Khook", "khooktop"},
{"S", "longs"},
{"mcapturn", "mturn"},
{"mcapturn", "mturned"},
{"Mu", "mu1"},
{"Nhook", "nlefthookatleft"},
{"Nhook", "nlftlfthook"},
{"Obar", "obarred"},
{"Pi", "omega1"},
{"Phi", "phi1"},
{"Phi", "philatin"},
{"Pi", "pi1"},
{"Rho", "rho1"},
{"Sigma", "sigma1"},
{"Sigma", "sigmafinal"},
{"Sigma", "sigmalunate"},
{"S", "slong"},
{"Theta", "theta1"},
{"Thook", "thooktop"},
{"Trthook", "trighttail"},
{"Upsilon2", "upsilon"},
{"Vcursive", "vscript"},
{NULL, NULL}
};
/* end */

27
contrib/ttf2pk/case.h Normal file
View File

@@ -0,0 +1,27 @@
/*
* case.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef CASE_H
#define CASE_H
struct _Case
{
char *upper;
char *lower;
};
typedef struct _Case Case;
extern Case casetable[];
#endif /* CASE_H */
/* end */

1700
contrib/ttf2pk/configure vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,87 @@
dnl This file is part of the ttf2pk package
dnl Process this file with autoconf to produce a configure script.
dnl Some tests are omitted since we assume that you've built the
dnl FreeType library successfully.
AC_INIT(../../lib/freetype.h)
AC_CANONICAL_SYSTEM
AC_PROG_CC
AC_PROG_CPP
AC_ARG_WITH(kpathsea-dir,
[ --with-kpathsea-dir=DIR Location of the kpathsea base dir (/usr/local)],[
if test x$withval = xyes; then
AC_MSG_WARN(Usage is: --with-kpathsea-dir=basedir)
else
if test x$withval = xno; then
AC_MSG_WARN(Usage is: --with-kpathsea-dir=basedir)
else
kpathsea_dir=$withval
fi
fi
])
if test -n "$kpathsea_dir"; then
LIBS="$LIBS -L$kpathsea_dir/lib"
CPPFLAGS="$CPPFLAGS -I$kpathsea_dir/include -I$srcdir"
dnl the function kpse_set_program_name() is available since kpathsea 3.2
AC_CHECK_LIB(kpathsea, kpse_set_program_name, [[]], AC_DEFINE(OLD_KPATHSEA))
AC_CHECK_LIB(kpathsea, kpse_init_prog, ,[
AC_MSG_ERROR([Can't find kpathsea library! Use --with-kpathsea-dir option.])])
dnl the header file kpathsea.h doesn't exist in kpathsea 2.6 and before
AC_CHECK_HEADER(kpathsea/kpathsea.h, [[]], AC_DEFINE(VERY_OLD_KPATHSEA))
AC_CHECK_HEADER(kpathsea/c-auto.h, ,[
AC_MSG_ERROR([Can't find kpathsea include files! Use --with-kpathsea-dir option.])])
else
CPPFLAGS="$CPPFLAGS -I$srcdir"
fi
AC_CHECK_LIB(m, floor)
AC_CHECK_LIB(intl, gettext)
OLDLIBS=$LIBS
LIBS="$LIBS -L../../lib/.libs"
CPPFLAGS="-I$srcdir/../../lib $CPPFLAGS"
AC_CHECK_LIB(ttf, TT_Init_FreeType, LIBS="$LIBS -lttf",[
AC_MSG_ERROR([Can't find ttf library! Compile FreeType first.])])
LIBS=$OLDLIBS
dnl get Compiler flags right.
if test "x$CC" = xgcc; then
XX_CFLAGS="-Wall -pedantic"
else
case "$host" in
alpha-dec-osf*)
XX_CFLAGS="-std1 -O2 -g3"
;;
*)
XX_CFLAGS=
;;
esac
fi
AC_SUBST(XX_CFLAGS)
AC_CHECK_PROG(RM, rm, rm)
AC_CHECK_PROG(RMDIR, rmdir, rmdir)
AC_PROG_INSTALL
if test -z "$kpathsea_dir"; then
AC_MSG_WARN([
The binaries will be compiled without file search library support!
For kpathsea support use the --with-kpathsea-dir option.
])
fi
AC_OUTPUT(Makefile MakeSub)
dnl end of configure.in

View File

@@ -0,0 +1,65 @@
# Big5.sfd
#
# subfont numbers for Big 5 encoding and its corresponding code ranges
# to be used with the CJK package for LaTeX.
01 0xA140_0xA17E 0xA1A1_0xA1FE 0xA240_0xA27E 0xA2A1_0xA2C4
02 0xA2C5_0xA2FE 0xA340_0xA37E 0xA3A1_0xA3FE 0xA440_0xA468
03 0xA469_0xA47E 0xA4A1_0xA4FE 0xA540_0xA57E 0xA5A1_0xA5ED
04 0xA5EE_0xA5FE 0xA640_0xA67E 0xA6A1_0xA6FE 0xA740_0xA77E 0xA7A1_0xA7B3
05 0xA7B4_0xA7FE 0xA840_0xA87E 0xA8A1_0xA8FE 0xA940_0xA957
06 0xA958_0xA97E 0xA9A1_0xA9FE 0xAA40_0xAA7E 0xAAA1_0xAADC
07 0xAADD_0xAAFE 0xAB40_0xAB7E 0xABA1_0xABFE 0xAC40_0xAC7E 0xACA1_0xACA2
08 0xACA3_0xACFE 0xAD40_0xAD7E 0xADA1_0xADFE 0xAE40_0xAE46
09 0xAE47_0xAE7E 0xAEA1_0xAEFE 0xAF40_0xAF7E 0xAFA1_0xAFCB
10 0xAFCC_0xAFFE 0xB040_0xB07E 0xB0A1_0xB0FE 0xB140_0xB16F
11 0xB170_0xB17E 0xB1A1_0xB1FE 0xB240_0xB27E 0xB2A1_0xB2F4
12 0xB2F5_0xB2FE 0xB340_0xB37E 0xB3A1_0xB3FE 0xB440_0xB47E 0xB4A1_0xB4BA
13 0xB4BB_0xB4FE 0xB540_0xB57E 0xB5A1_0xB5FE 0xB640_0xB65E
14 0xB65F_0xB67E 0xB6A1_0xB6FE 0xB740_0xB77E 0xB7A1_0xB7E3
15 0xB7E4_0xB7FE 0xB840_0xB87E 0xB8A1_0xB8FE 0xB940_0xB97E 0xB9A1_0xB9A9
16 0xB9AA_0xB9FE 0xBA40_0xBA7E 0xBAA1_0xBAFE 0xBB40_0xBB4D
17 0xBB4E_0xBB7E 0xBBA1_0xBBFE 0xBC40_0xBC7E 0xBCA1_0xBCD2
18 0xBCD3_0xBCFE 0xBD40_0xBD7E 0xBDA1_0xBDFE 0xBE40_0xBE76
19 0xBE77_0xBE7E 0xBEA1_0xBEFE 0xBF40_0xBF7E 0xBFA1_0xBFFB
20 0xBFFC_0xBFFE 0xC040_0xC07E 0xC0A1_0xC0FE 0xC140_0xC17E 0xC1A1_0xC1C1
21 0xC1C2_0xC1FE 0xC240_0xC27E 0xC2A1_0xC2FE 0xC340_0xC365
22 0xC366_0xC37E 0xC3A1_0xC3FE 0xC440_0xC47E 0xC4A1_0xC4EA
23 0xC4EB_0xC4FE 0xC540_0xC57E 0xC5A1_0xC5FE 0xC640_0xC67E 0xC6A1_0xC6B0
24 0xC6B1_0xC6FE 0xC740_0xC77E 0xC7A1_0xC7FE 0xC840_0xC854
25 0xC855_0xC87E 0xC8A1_0xC8FE 0xC940_0xC97E 0xC9A1_0xC9D9
26 0xC9DA_0xC9FE 0xCA40_0xCA7E 0xCAA1_0xCAFE 0xCB40_0xCB7D
27 0xCB7E 0xCBA1_0xCBFE 0xCC40_0xCC7E 0xCCA1_0xCCFE 0xCD40_0xCD43
28 0xCD44_0xCD7E 0xCDA1_0xCDFE 0xCE40_0xCE7E 0xCEA1_0xCEC8
29 0xCEC9_0xCEFE 0xCF40_0xCF7E 0xCFA1_0xCFFE 0xD040_0xD06C
30 0xD06D_0xD07E 0xD0A1_0xD0FE 0xD140_0xD17E 0xD1A1_0xD1F1
31 0xD1F2_0xD1FE 0xD240_0xD27E 0xD2A1_0xD2FE 0xD340_0xD37E 0xD3A1_0xD3B7
32 0xD3B8_0xD3FE 0xD440_0xD47E 0xD4A1_0xD4FE 0xD540_0xD55B
33 0xD55C_0xD57E 0xD5A1_0xD5FE 0xD640_0xD67E 0xD6A1_0xD6E0
34 0xD6E1_0xD6FE 0xD740_0xD77E 0xD7A1_0xD7FE 0xD840_0xD87E 0xD8A1_0xD8A6
35 0xD8A7_0xD8FE 0xD940_0xD97E 0xD9A1_0xD9FE 0xDA40_0xDA4A
36 0xDA4B_0xDA7E 0xDAA1_0xDAFE 0xDB40_0xDB7E 0xDBA1_0xDBCF
37 0xDBD0_0xDBFE 0xDC40_0xDC7E 0xDCA1_0xDCFE 0xDD40_0xDD73
38 0xDD74_0xDD7E 0xDDA1_0xDDFE 0xDE40_0xDE7E 0xDEA1_0xDEF8
39 0xDEF9_0xDEFE 0xDF40_0xDF7E 0xDFA1_0xDFFE 0xE040_0xE07E 0xE0A1_0xE0BE
40 0xE0BF_0xE0FE 0xE140_0xE17E 0xE1A1_0xE1FE 0xE240_0xE262
41 0xE263_0xE27E 0xE2A1_0xE2FE 0xE340_0xE37E 0xE3A1_0xE3E7
42 0xE3E8_0xE3FE 0xE440_0xE47E 0xE4A1_0xE4FE 0xE540_0xE57E 0xE5A1_0xE5AD
43 0xE5AE_0xE5FE 0xE640_0xE67E 0xE6A1_0xE6FE 0xE740_0xE751
44 0xE752_0xE77E 0xE7A1_0xE7FE 0xE840_0xE87E 0xE8A1_0xE8D6
45 0xE8D7_0xE8FE 0xE940_0xE97E 0xE9A1_0xE9FE 0xEA40_0xEA7A
46 0xEA7B_0xEA7E 0xEAA1_0xEAFE 0xEB40_0xEB7E 0xEBA1_0xEBFE 0xEC40
47 0xEC41_0xEC7E 0xECA1_0xECFE 0xED40_0xED7E 0xEDA1_0xEDC5
48 0xEDC6_0xEDFE 0xEE40_0xEE7E 0xEEA1_0xEEFE 0xEF40_0xEF69
49 0xEF6A_0xEF7E 0xEFA1_0xEFFE 0xF040_0xF07E 0xF0A1_0xF0EE
50 0xF0EF_0xF0FE 0xF140_0xF17E 0xF1A1_0xF1FE 0xF240_0xF27E 0xF2A1_0xF2B4
51 0xF2B5_0xF2FE 0xF340_0xF37E 0xF3A1_0xF3FE 0xF440_0xF458
52 0xF459_0xF47E 0xF4A1_0xF4FE 0xF540_0xF57E 0xF5A1_0xF5DD
53 0xF5DE_0xF5FE 0xF640_0xF67E 0xF6A1_0xF6FE 0xF740_0xF77E 0xF7A1_0xF7A3
54 0xF7A4_0xF7FE 0xF840_0xF87E 0xF8A1_0xF8FE 0xF940_0xF947
55 0xF948_0xF97E 0xF9A1_0xF9FE 0xFA40_0xFA7E 0xFAA1_0xFACC
56 0xFACD_0xFAFE 0xFB40_0xFB7E 0xFBA1_0xFBFE 0xFC40_0xFC70
57 0xFC71_0xFC7E 0xFCA1_0xFCFE 0xFD40_0xFD7E 0xFDA1_0xFDF5
58 0xFDF6_0xFDFE 0xFE40_0xFE7E 0xFEA1_0xFEFE
# eof

119
contrib/ttf2pk/data/ET5.enc Normal file
View File

@@ -0,0 +1,119 @@
% ET5.enc
%
%
% This is LaTeX ET5 encoding for Vietnamese.
%
%
% LIGKERN question quoteleft =: questiondown ;
% LIGKERN exclam quoteleft =: exclamdown ;
% LIGKERN hyphen hyphen =: endash ;
% LIGKERN endash hyphen =: emdash ;
% LIGKERN quoteleft quoteleft =: quotedblleft ;
% LIGKERN quoteright quoteright =: quotedblright ;
% LIGKERN comma comma =: quotedblbase ;
%
% LIGKERN f i =: fi ;
% LIGKERN f l =: fl ;
% LIGKERN f f =: ff ;
% LIGKERN ff i =: ffi ;
% LIGKERN ff l =: ffl ;
%
% We blow away kerns to and from spaces (TeX doesn't have a
% space) and also remove any kerns from the numbers.
%
% LIGKERN space {} * ; * {} space ;
% LIGKERN zero {} * ; * {} zero ;
% LIGKERN one {} * ; * {} one ;
% LIGKERN two {} * ; * {} two ;
% LIGKERN three {} * ; * {} three ;
% LIGKERN four {} * ; * {} four ;
% LIGKERN five {} * ; * {} five ;
% LIGKERN six {} * ; * {} six ;
% LIGKERN seven {} * ; * {} seven ;
% LIGKERN eight {} * ; * {} eight ;
% LIGKERN nine {} * ; * {} nine ;
/ET5encoding [
% 0x00
/Abrevehookabove /Abrevetilde /Acircumflextilde /Yhookabove
/Ytilde /Ydotbelow /Sigma /Upsilon
/Phi /Psi /Omega /ff
/fi /fl /ffi /ffl
% 0x10
/dotlessi /dotlessj /grave /acute
/caron /breve /macron /ring
/cedilla /germandbls /ae /oe
/oslash /AE /OE /Oslash
% 0x20
/.notdef /exclam /quotedblright /numbersign
/dollar /percent /ampersand /quoteright
/parenleft /parenright /asterisk /plus
/comma /hyphen /period /slash
% 0x30
/zero /one /two /three
/four /five /six /seven
/eight /nine /colon /semicolon
/exclamdown /equal /questiondown /question
% 0x40
/at /A /B /C
/D /E /F /G
/H /I /J /K
/L /M /N /O
% 0x50
/P /Q /R /S
/T /U /V /W
/X /Y /Z /bracketleft
/quotedblleft /bracketright /circumflex /dotaccent
% 0x60
/quoteleft /a /b /c
/d /e /f /g
/h /i /j /k
/l /m /n /o
% 0x70
/p /q /r /s
/t /u /v /w
/x /y /z /endash
/emdash /hungarumlaut /tilde /dieresis
% 0x80
/Adotbelow /Abreveacute /Abrevegrave /Abrevedotbelow
/Acircumflexacute /Acircumflexgrave /Acircumflexhookabove /Acircumflexdotbelow
/Etilde /Edotbelow /Ecircumflexacute /Ecircumflexgrave
/Ecircumflexhookabove /Ecircumflextilde /Ecircumflexdotbelow /Ocircumflexacute
% 0x90
/Ocircumflexgrave /Ocircumflexhookabove /Ocircumflextilde /Ocircumflexdotbelow
/Ohorndotbelow /Ohornacute /Ohorngrave /Ohornhookabove
/Idotbelow /Ohookabove /Odotbelow /Ihookabove
/Uhookabove /Utilde /Udotbelow /Ygrave
% 0xA0
/Otilde /abreveacute /abrevegrave /abrevedotbelow
/acircumflexacute /acircumflexgrave /acircumflexhookabove /acircumflexdotbelow
/etilde /edotbelow /ecircumflexacute /ecircumflexgrave
/ecircumflexhookabove /ecircumflextilde /ecircumflexdotbelow /ocircumflexacute
% 0xB0
/ocircumflexgrave /ocircumflexhookabove /ocircumflextilde /Ohorntilde
/Ohorn /ocircumflexdotbelow /ohorngrave /ohornhookabove
/idotbelow /Uhorndotbelow /Uhornacute /Uhorngrave
/Uhornhookabove /ohorn /ohornacute /Uhorn
% 0xC0
/Agrave /Aacute /Acircumflex /Atilde
/Ahookabove /Abreve /abrevehookabove /abrevetilde
/Egrave /Eacute /Ecircumflex /Ehookabove
/Igrave /Iacute /Itilde /ygrave
% 0xD0
/Dbar /uhornacute /Ograve /Oacute
/Ocircumflex /adotbelow /yhookabove /uhorngrave
/uhornhookabove /Ugrave /Uacute /ytilde
/ydotbelow /Yacute /ohorntilde /uhorn
% 0xE0
/agrave /aacute /acircumflex /atilde
/ahookabove /abreve /uhorntilde /acircumflextilde
/egrave /eacute /ecircumflex /ehookabove
/igrave /iacute /itilde /ihookabove
% 0xF0
/dbar /uhorndotbelow /ograve /oacute
/ocircumflex /otilde /ohookabove /odotbelow
/udotbelow /ugrave /uacute /utilde
/uhookabove /yacute /ohorndotbelow /Uhorntilde
] def
% eof

View File

@@ -0,0 +1,49 @@
# EUC.sfd
#
# subfont numbers for character sets in EUC encoding and its corresponding
# code ranges to be used with the CJK package for LaTeX.
#
# Examples for such character sets:
#
# GB 2312-1980,
# KS X 1001:1992 (=KS C 5601-1992),
# JIS X 0208:1997,
# CNS 11643-1992 planes 1-7.
01 0xA1A1_0xA1FE 0xA2A1_0xA2FE 0xA3A1_0xA3E4
02 0xA3E5_0xA3FE 0xA4A1_0xA4FE 0xA5A1_0xA5FE 0xA6A1_0xA6CA
03 0xA6CB_0xA6FE 0xA7A1_0xA7FE 0xA8A1_0xA8FE 0xA9A1_0xA9B0
04 0xA9B1_0xA9FE 0xAAA1_0xAAFE 0xABA1_0xABF4
05 0xABF5_0xABFE 0xACA1_0xACFE 0xADA1_0xADFE 0xAEA1_0xAEDA
06 0xAEDB_0xAEFE 0xAFA1_0xAFFE 0xB0A1_0xB0FE 0xB1A1_0xB1C0
07 0xB1C1_0xB1FE 0xB2A1_0xB2FE 0xB3A1_0xB3FE 0xB4A1_0xB4A6
08 0xB4A7_0xB4FE 0xB5A1_0xB5FE 0xB6A1_0xB6EA
09 0xB6EB_0xB6FE 0xB7A1_0xB7FE 0xB8A1_0xB8FE 0xB9A1_0xB9D0
10 0xB9D1_0xB9FE 0xBAA1_0xBAFE 0xBBA1_0xBBFE 0xBCA1_0xBCB6
11 0xBCB7_0xBCFE 0xBDA1_0xBDFE 0xBEA1_0xBEFA
12 0xBEFB_0xBEFE 0xBFA1_0xBFFE 0xC0A1_0xC0FE 0xC1A1_0xC1E0
13 0xC1E1_0xC1FE 0xC2A1_0xC2FE 0xC3A1_0xC3FE 0xC4A1_0xC4C6
14 0xC4C7_0xC4FE 0xC5A1_0xC5FE 0xC6A1_0xC6FE 0xC7A1_0xC7AC
15 0xC7AD_0xC7FE 0xC8A1_0xC8FE 0xC9A1_0xC9F0
16 0xC9F1_0xC9FE 0xCAA1_0xCAFE 0xCBA1_0xCBFE 0xCCA1_0xCCD6
17 0xCCD7_0xCCFE 0xCDA1_0xCDFE 0xCEA1_0xCEFE 0xCFA1_0xCFBC
18 0xCFBD_0xCFFE 0xD0A1_0xD0FE 0xD1A1_0xD1FE 0xD2A1_0xD2A2
19 0xD2A3_0xD2FE 0xD3A1_0xD3FE 0xD4A1_0xD4E6
20 0xD4E7_0xD4FE 0xD5A1_0xD5FE 0xD6A1_0xD6FE 0xD7A1_0xD7CC
21 0xD7CD_0xD7FE 0xD8A1_0xD8FE 0xD9A1_0xD9FE 0xDAA1_0xDAB2
22 0xDAB3_0xDAFE 0xDBA1_0xDBFE 0xDCA1_0xDCF6
23 0xDCF7_0xDCFE 0xDDA1_0xDDFE 0xDEA1_0xDEFE 0xDFA1_0xDFDC
24 0xDFDD_0xDFFE 0xE0A1_0xE0FE 0xE1A1_0xE1FE 0xE2A1_0xE2C2
25 0xE2C3_0xE2FE 0xE3A1_0xE3FE 0xE4A1_0xE4FE 0xE5A1_0xE5A8
26 0xE5A9_0xE5FE 0xE6A1_0xE6FE 0xE7A1_0xE7EC
27 0xE7ED_0xE7FE 0xE8A1_0xE8FE 0xE9A1_0xE9FE 0xEAA1_0xEAD2
28 0xEAD3_0xEAFE 0xEBA1_0xEBFE 0xECA1_0xECFE 0xEDA1_0xEDB8
29 0xEDB9_0xEDFE 0xEEA1_0xEEFE 0xEFA1_0xEFFC
30 0xEFFD_0xEFFE 0xF0A1_0xF0FE 0xF1A1_0xF1FE 0xF2A1_0xF2E2
31 0xF2E3_0xF2FE 0xF3A1_0xF3FE 0xF4A1_0xF4FE 0xF5A1_0xF5C8
32 0xF5C9_0xF5FE 0xF6A1_0xF6FE 0xF7A1_0xF7FE 0xF8A1_0xF8AE
33 0xF8AF_0xF8FE 0xF9A1_0xF9FE 0xFAA1_0xFAF2
34 0xFAF3_0xFAFE 0xFBA1_0xFBFE 0xFCA1_0xFCFE 0xFDA1_0xFDD8
35 0xFDD9_0xFDFE 0xFEA1_0xFEFE
# eof

View File

@@ -0,0 +1,52 @@
# SJIS.sfd
#
# subfont numbers for SJIS encoding and its corresponding code ranges
# to be used with the CJK package for LaTeX.
01 0x8140_0x817E 0x8180_0x81FC 0x8240_0x827E 0x8280_0x8284
02 0x8285_0x82FC 0x8340_0x837E 0x8380_0x83C8
03 0x83C9_0x83FC 0x8440_0x847E 0x8480_0x84FC 0x8540_0x854F
04 0x8550_0x857E 0x8580_0x85FC 0x8640_0x867E 0x8680_0x8694
05 0x8695_0x86FC 0x8740_0x877E 0x8780_0x87D8
06 0x87D9_0x87FC 0x8840_0x887E 0x8880_0x88FC 0x8940_0x895F
07 0x8960_0x897E 0x8980_0x89FC 0x8A40_0x8A7E 0x8A80_0x8AA4
08 0x8AA5_0x8AFC 0x8B40_0x8B7E 0x8B80_0x8BE8
09 0x8BE9_0x8BFC 0x8C40_0x8C7E 0x8C80_0x8CFC 0x8D40_0x8D6F
10 0x8D70_0x8D7E 0x8D80_0x8DFC 0x8E40_0x8E7E 0x8E80_0x8EB4
11 0x8EB5_0x8EFC 0x8F40_0x8F7E 0x8F80_0x8FF8
12 0x8FF9_0x8FFC 0x9040_0x907E 0x9080_0x90FC 0x9140_0x917E 0x9180
13 0x9181_0x91FC 0x9240_0x927E 0x9280_0x92C4
14 0x92C5_0x92FC 0x9340_0x937E 0x9380_0x93FC 0x9440_0x944B
15 0x944C_0x947E 0x9480_0x94FC 0x9540_0x957E 0x9580_0x9590
16 0x9591_0x95FC 0x9640_0x967E 0x9680_0x96D4
17 0x96D5_0x96FC 0x9740_0x977E 0x9780_0x97FC 0x9840_0x985B
18 0x985C_0x987E 0x9880_0x98FC 0x9940_0x997E 0x9980_0x99A0
19 0x99A1_0x99FC 0x9A40_0x9A7E 0x9A80_0x9AE4
20 0x9AE5_0x9AFC 0x9B40_0x9B7E 0x9B80_0x9BFC 0x9C40_0x9C6B
21 0x9C6C_0x9C7E 0x9C80_0x9CFC 0x9D40_0x9D7E 0x9D80_0x9DB0
22 0x9DB1_0x9DFC 0x9E40_0x9E7E 0x9E80_0x9EF4
23 0x9EF5_0x9EFC 0x9F40_0x9F7E 0x9F80_0x9FFC 0xE040_0xE07B
24 0xE07C_0xE07E 0xE080_0xE0FC 0xE140_0xE17E 0xE180_0xE1C0
25 0xE1C1_0xE1FC 0xE240_0xE27E 0xE280_0xE2FC 0xE340_0xE347
26 0xE348_0xE37E 0xE380_0xE3FC 0xE440_0xE47E 0xE480_0xE48C
27 0xE48D_0xE4FC 0xE540_0xE57E 0xE580_0xE5D0
28 0xE5D1_0xE5FC 0xE640_0xE67E 0xE680_0xE6FC 0xE740_0xE757
29 0xE758_0xE77E 0xE780_0xE7FC 0xE840_0xE87E 0xE880_0xE89C
30 0xE89D_0xE8FC 0xE940_0xE97E 0xE980_0xE9E0
31 0xE9E1_0xE9FC 0xEA40_0xEA7E 0xEA80_0xEAFC 0xEB40_0xEB67
32 0xEB68_0xEB7E 0xEB80_0xEBFC 0xEC40_0xEC7E 0xEC80_0xECAC
33 0xECAD_0xECFC 0xED40_0xED7E 0xED80_0xEDF0
34 0xEDF1_0xEDFC 0xEE40_0xEE7E 0xEE80_0xEEFC 0xEF40_0xEF77
35 0xEF78_0xEF7E 0xEF80_0xEFFC 0xF040_0xF07E 0xF080_0xF0BC
36 0xF0BD_0xF0FC 0xF140_0xF17E 0xF180_0xF1FC 0xF240_0xF243
37 0xF244_0xF27E 0xF280_0xF2FC 0xF340_0xF37E 0xF380_0xF388
38 0xF389_0xF3FC 0xF440_0xF47E 0xF480_0xF4CC
39 0xF4CD_0xF4FC 0xF540_0xF57E 0xF580_0xF5FC 0xF640_0xF653
40 0xF654_0xF67E 0xF680_0xF6FC 0xF740_0xF77E 0xF780_0xF798
41 0xF799_0xF7FC 0xF840_0xF87E 0xF880_0xF8DC
42 0xF8DD_0xF8FC 0xF940_0xF97E 0xF980_0xF9FC 0xFA40_0xFA63
43 0xFA64_0xFA7E 0xFA80_0xFAFC 0xFB40_0xFB7E 0xFB80_0xFBA8
44 0xFBA9_0xFBFC 0xFC40_0xFC7E 0xFC80_0xFCEC
45 0xFCED_0xFCFC
# eof

View File

@@ -0,0 +1,128 @@
% T1-WGL4.enc
%
%
% This is LaTeX T1 encoding for WGL4 encoded TrueType fonts
% (e.g. from Windows 95)
%
%
% Note that /hyphen appears twice (for the T1 code points `hyphen' 0x2d
% and `hyphenchar' 0x7f).
%
%
% LIGKERN space l =: lslash ;
% LIGKERN space L =: Lslash ;
% LIGKERN question quoteleft =: questiondown ;
% LIGKERN exclam quoteleft =: exclamdown ;
% LIGKERN hyphen hyphen =: endash ;
% LIGKERN endash hyphen =: emdash ;
% LIGKERN quoteleft quoteleft =: quotedblleft ;
% LIGKERN quoteright quoteright =: quotedblright ;
% LIGKERN comma comma =: quotedblbase ;
% LIGKERN less less =: guillemotleft ;
% LIGKERN greater greater =: guillemotright ;
%
% LIGKERN f i =: fi ;
% LIGKERN f l =: fl ;
% LIGKERN f f =: ff ;
% LIGKERN ff i =: ffi ;
% LIGKERN ff l =: ffl ;
%
% We blow away kerns to and from spaces (TeX doesn't have a
% space) and also remove any kerns from the numbers.
%
% LIGKERN space {} * ; * {} space ;
% LIGKERN zero {} * ; * {} zero ;
% LIGKERN one {} * ; * {} one ;
% LIGKERN two {} * ; * {} two ;
% LIGKERN three {} * ; * {} three ;
% LIGKERN four {} * ; * {} four ;
% LIGKERN five {} * ; * {} five ;
% LIGKERN six {} * ; * {} six ;
% LIGKERN seven {} * ; * {} seven ;
% LIGKERN eight {} * ; * {} eight ;
% LIGKERN nine {} * ; * {} nine ;
/T1Encoding [ % now 256 chars follow
% 0x00
/grave /acute /circumflex /tilde
/dieresis /hungarumlaut /ring /caron
/breve /macron /dotaccent /cedilla
/ogonek /quotesinglbase /guilsinglleft /guilsinglright
% 0x10
/quotedblleft /quotedblright /quotedblbase /guillemotleft
/guillemotright /endash /emdash /compwordmark
/perthousandzero /dotlessi /dotlessj /ff
/fi /fl /ffi /ffl
% 0x20
/visualspace /exclam /quotedbl /numbersign
/dollar /percent /ampersand /quoteright
/parenleft /parenright /asterisk /plus
/comma /hyphen /period /slash
% 0x30
/zero /one /two /three
/four /five /six /seven
/eight /nine /colon /semicolon
/less /equal /greater /question
% 0x40
/at /A /B /C
/D /E /F /G
/H /I /J /K
/L /M /N /O
% 0x50
/P /Q /R /S
/T /U /V /W
/X /Y /Z /bracketleft
/backslash /bracketright /asciicircum /underscore
% 0x60
/quoteleft /a /b /c
/d /e /f /g
/h /i /j /k
/l /m /n /o
% 0x70
/p /q /r /s
/t /u /v /w
/x /y /z /braceleft
/bar /braceright /asciitilde /hyphen
% 0x80
/Abreve /Aogonek /Cacute /Ccaron
/Dcaron /Ecaron /Eogonek /Gbreve
/Lacute /Lcaron /Lslash /Nacute
/Ncaron /Eng /Odblacute /Racute
% 0x90
/Rcaron /Sacute /Scaron /Scedilla
/Tcaron /Tcedilla /Udblacute /Uring
/Ydieresis /Zacute /Zcaron /Zdot
/IJ /Idot /dmacron /section
% 0xA0
/abreve /aogonek /cacute /ccaron
/dcaron /ecaron /eogonek /gbreve
/lacute /lcaron /lslash /nacute
/ncaron /eng /odblacute /racute
% 0xB0
/rcaron /sacute /scaron /scedilla
/tcaron /tcedilla /udblacute /uring
/ydieresis /zacute /zcaron /zdot
/ij /exclamdown /questiondown /sterling
% 0xC0
/Agrave /Aacute /Acircumflex /Atilde
/Adieresis /Aring /AE /Ccedilla
/Egrave /Eacute /Ecircumflex /Edieresis
/Igrave /Iacute /Icircumflex /Idieresis
% 0xD0
/Eth /Ntilde /Ograve /Oacute
/Ocircumflex /Otilde /Odieresis /OE
/Oslash /Ugrave /Uacute /Ucircumflex
/Udieresis /Yacute /Thorn /Germandbls
% 0xE0
/agrave /aacute /acircumflex /atilde
/adieresis /aring /ae /ccedilla
/egrave /eacute /ecircumflex /edieresis
/igrave /iacute /icircumflex /idieresis
% 0xF0
/eth /ntilde /ograve /oacute
/ocircumflex /otilde /odieresis /oe
/oslash /ugrave /uacute /ucircumflex
/udieresis /yacute /thorn /germandbls
] def
% eof

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1114
contrib/ttf2pk/data/UGB.sfd Normal file

File diff suppressed because it is too large Load Diff

3002
contrib/ttf2pk/data/UGBK.sfd Normal file

File diff suppressed because it is too large Load Diff

1114
contrib/ttf2pk/data/UJIS.sfd Normal file

File diff suppressed because it is too large Load Diff

1114
contrib/ttf2pk/data/UKS.sfd Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,265 @@
# Unicode.sfd
#
# subfont numbers for Unicode encoding and its corresponding code ranges
# to be used with the CJK package for LaTeX.
00 0x0_0xFF
01 0x100_0x1FF
02 0x200_0x2FF
03 0x300_0x3FF
04 0x400_0x4FF
05 0x500_0x5FF
06 0x600_0x6FF
07 0x700_0x7FF
08 0x800_0x8FF
09 0x900_0x9FF
0a 0xA00_0xAFF
0b 0xB00_0xBFF
0c 0xC00_0xCFF
0d 0xD00_0xDFF
0e 0xE00_0xEFF
0f 0xF00_0xFFF
10 0x1000_0x10FF
11 0x1100_0x11FF
12 0x1200_0x12FF
13 0x1300_0x13FF
14 0x1400_0x14FF
15 0x1500_0x15FF
16 0x1600_0x16FF
17 0x1700_0x17FF
18 0x1800_0x18FF
19 0x1900_0x19FF
1a 0x1A00_0x1AFF
1b 0x1B00_0x1BFF
1c 0x1C00_0x1CFF
1d 0x1D00_0x1DFF
1e 0x1E00_0x1EFF
1f 0x1F00_0x1FFF
20 0x2000_0x20FF
21 0x2100_0x21FF
22 0x2200_0x22FF
23 0x2300_0x23FF
24 0x2400_0x24FF
25 0x2500_0x25FF
26 0x2600_0x26FF
27 0x2700_0x27FF
28 0x2800_0x28FF
29 0x2900_0x29FF
2a 0x2A00_0x2AFF
2b 0x2B00_0x2BFF
2c 0x2C00_0x2CFF
2d 0x2D00_0x2DFF
2e 0x2E00_0x2EFF
2f 0x2F00_0x2FFF
30 0x3000_0x30FF
31 0x3100_0x31FF
32 0x3200_0x32FF
33 0x3300_0x33FF
34 0x3400_0x34FF
35 0x3500_0x35FF
36 0x3600_0x36FF
37 0x3700_0x37FF
38 0x3800_0x38FF
39 0x3900_0x39FF
3a 0x3A00_0x3AFF
3b 0x3B00_0x3BFF
3c 0x3C00_0x3CFF
3d 0x3D00_0x3DFF
3e 0x3E00_0x3EFF
3f 0x3F00_0x3FFF
40 0x4000_0x40FF
41 0x4100_0x41FF
42 0x4200_0x42FF
43 0x4300_0x43FF
44 0x4400_0x44FF
45 0x4500_0x45FF
46 0x4600_0x46FF
47 0x4700_0x47FF
48 0x4800_0x48FF
49 0x4900_0x49FF
4a 0x4A00_0x4AFF
4b 0x4B00_0x4BFF
4c 0x4C00_0x4CFF
4d 0x4D00_0x4DFF
4e 0x4E00_0x4EFF
4f 0x4F00_0x4FFF
50 0x5000_0x50FF
51 0x5100_0x51FF
52 0x5200_0x52FF
53 0x5300_0x53FF
54 0x5400_0x54FF
55 0x5500_0x55FF
56 0x5600_0x56FF
57 0x5700_0x57FF
58 0x5800_0x58FF
59 0x5900_0x59FF
5a 0x5A00_0x5AFF
5b 0x5B00_0x5BFF
5c 0x5C00_0x5CFF
5d 0x5D00_0x5DFF
5e 0x5E00_0x5EFF
5f 0x5F00_0x5FFF
60 0x6000_0x60FF
61 0x6100_0x61FF
62 0x6200_0x62FF
63 0x6300_0x63FF
64 0x6400_0x64FF
65 0x6500_0x65FF
66 0x6600_0x66FF
67 0x6700_0x67FF
68 0x6800_0x68FF
69 0x6900_0x69FF
6a 0x6A00_0x6AFF
6b 0x6B00_0x6BFF
6c 0x6C00_0x6CFF
6d 0x6D00_0x6DFF
6e 0x6E00_0x6EFF
6f 0x6F00_0x6FFF
70 0x7000_0x70FF
71 0x7100_0x71FF
72 0x7200_0x72FF
73 0x7300_0x73FF
74 0x7400_0x74FF
75 0x7500_0x75FF
76 0x7600_0x76FF
77 0x7700_0x77FF
78 0x7800_0x78FF
79 0x7900_0x79FF
7a 0x7A00_0x7AFF
7b 0x7B00_0x7BFF
7c 0x7C00_0x7CFF
7d 0x7D00_0x7DFF
7e 0x7E00_0x7EFF
7f 0x7F00_0x7FFF
80 0x8000_0x80FF
81 0x8100_0x81FF
82 0x8200_0x82FF
83 0x8300_0x83FF
84 0x8400_0x84FF
85 0x8500_0x85FF
86 0x8600_0x86FF
87 0x8700_0x87FF
88 0x8800_0x88FF
89 0x8900_0x89FF
8a 0x8A00_0x8AFF
8b 0x8B00_0x8BFF
8c 0x8C00_0x8CFF
8d 0x8D00_0x8DFF
8e 0x8E00_0x8EFF
8f 0x8F00_0x8FFF
90 0x9000_0x90FF
91 0x9100_0x91FF
92 0x9200_0x92FF
93 0x9300_0x93FF
94 0x9400_0x94FF
95 0x9500_0x95FF
96 0x9600_0x96FF
97 0x9700_0x97FF
98 0x9800_0x98FF
99 0x9900_0x99FF
9a 0x9A00_0x9AFF
9b 0x9B00_0x9BFF
9c 0x9C00_0x9CFF
9d 0x9D00_0x9DFF
9e 0x9E00_0x9EFF
9f 0x9F00_0x9FFF
a0 0xA000_0xA0FF
a1 0xA100_0xA1FF
a2 0xA200_0xA2FF
a3 0xA300_0xA3FF
a4 0xA400_0xA4FF
a5 0xA500_0xA5FF
a6 0xA600_0xA6FF
a7 0xA700_0xA7FF
a8 0xA800_0xA8FF
a9 0xA900_0xA9FF
aa 0xAA00_0xAAFF
ab 0xAB00_0xABFF
ac 0xAC00_0xACFF
ad 0xAD00_0xADFF
ae 0xAE00_0xAEFF
af 0xAF00_0xAFFF
b0 0xB000_0xB0FF
b1 0xB100_0xB1FF
b2 0xB200_0xB2FF
b3 0xB300_0xB3FF
b4 0xB400_0xB4FF
b5 0xB500_0xB5FF
b6 0xB600_0xB6FF
b7 0xB700_0xB7FF
b8 0xB800_0xB8FF
b9 0xB900_0xB9FF
ba 0xBA00_0xBAFF
bb 0xBB00_0xBBFF
bc 0xBC00_0xBCFF
bd 0xBD00_0xBDFF
be 0xBE00_0xBEFF
bf 0xBF00_0xBFFF
c0 0xC000_0xC0FF
c1 0xC100_0xC1FF
c2 0xC200_0xC2FF
c3 0xC300_0xC3FF
c4 0xC400_0xC4FF
c5 0xC500_0xC5FF
c6 0xC600_0xC6FF
c7 0xC700_0xC7FF
c8 0xC800_0xC8FF
c9 0xC900_0xC9FF
ca 0xCA00_0xCAFF
cb 0xCB00_0xCBFF
cc 0xCC00_0xCCFF
cd 0xCD00_0xCDFF
ce 0xCE00_0xCEFF
cf 0xCF00_0xCFFF
d0 0xD000_0xD0FF
d1 0xD100_0xD1FF
d2 0xD200_0xD2FF
d3 0xD300_0xD3FF
d4 0xD400_0xD4FF
d5 0xD500_0xD5FF
d6 0xD600_0xD6FF
d7 0xD700_0xD7FF
# Surrogates
#
# d8 0xD800_0xD8FF
# d9 0xD900_0xD9FF
# da 0xDA00_0xDAFF
# db 0xDB00_0xDBFF
dc 0xDC00_0xDCFF
dd 0xDD00_0xDDFF
de 0xDE00_0xDEFF
df 0xDF00_0xDFFF
e0 0xE000_0xE0FF
e1 0xE100_0xE1FF
e2 0xE200_0xE2FF
e3 0xE300_0xE3FF
e4 0xE400_0xE4FF
e5 0xE500_0xE5FF
e6 0xE600_0xE6FF
e7 0xE700_0xE7FF
e8 0xE800_0xE8FF
e9 0xE900_0xE9FF
ea 0xEA00_0xEAFF
eb 0xEB00_0xEBFF
ec 0xEC00_0xECFF
ed 0xED00_0xEDFF
ee 0xEE00_0xEEFF
ef 0xEF00_0xEFFF
f0 0xF000_0xF0FF
f1 0xF100_0xF1FF
f2 0xF200_0xF2FF
f3 0xF300_0xF3FF
f4 0xF400_0xF4FF
f5 0xF500_0xF5FF
f6 0xF600_0xF6FF
f7 0xF700_0xF7FF
f8 0xF800_0xF8FF
f9 0xF900_0xF9FF
fa 0xFA00_0xFAFF
fb 0xFB00_0xFBFF
fc 0xFC00_0xFCFF
fd 0xFD00_0xFDFF
fe 0xFE00_0xFEFF
ff 0xFF00_0xFFFF
# eof

244
contrib/ttf2pk/data/VPS.rpl Normal file
View File

@@ -0,0 +1,244 @@
% VPS.rpl
%
%
% This file maps VPS encoding for Vietnamese to Adobe glyph names used
% in the file ET5.enc.
%
% VPS is a commonly used program to write Vietnamese.
%
% This file has been tested with the font vpsdlac.ttf using cmap (3,0)
.c0x0002 Adotbelow
.c0x0003 Acircumflexdotbelow
.c0x0004 Abrevedotbelow
.c0x0005 Edotbelow
.c0x0006 Ecircumflexdotbelow
.c0x0015 Uhorndotbelow
.c0x0019 Ydotbelow
.c0x001c Acircumflextilde
.c0x001d Uhorntilde
.c0x0020 space
.c0x0021 exclam
.c0x0022 quotedbl
.c0x0023 numbersign
.c0x0024 dollar
.c0x0025 percent
.c0x0026 ampersand
.c0x0027 quotesingle
.c0x0028 parenleft
.c0x0029 parenright
.c0x002a asterisk
.c0x002b plus
.c0x002c comma
.c0x002d hyphen
.c0x002e period
.c0x002f slash
.c0x0030 zero
.c0x0031 one
.c0x0032 two
.c0x0033 three
.c0x0034 four
.c0x0035 five
.c0x0036 six
.c0x0037 seven
.c0x0038 eight
.c0x0039 nine
.c0x003a colon
.c0x003b semicolon
.c0x003c less
.c0x003d equal
.c0x003e greater
.c0x003f question
.c0x0040 at
.c0x0041 A
.c0x0042 B
.c0x0043 C
.c0x0044 D
.c0x0045 E
.c0x0046 F
.c0x0047 G
.c0x0048 H
.c0x0049 I
.c0x004a J
.c0x004b K
.c0x004c L
.c0x004d M
.c0x004e N
.c0x004f O
.c0x0050 P
.c0x0051 Q
.c0x0052 R
.c0x0053 S
.c0x0054 T
.c0x0055 U
.c0x0056 V
.c0x0057 W
.c0x0058 X
.c0x0059 Y
.c0x005a Z
.c0x005b bracketleft
.c0x005c backslash
.c0x005d bracketright
.c0x005e asciicircum
.c0x005f underscore
.c0x0060 grave
.c0x0061 a
.c0x0062 b
.c0x0063 c
.c0x0064 d
.c0x0065 e
.c0x0066 f
.c0x0067 g
.c0x0068 h
.c0x0069 i
.c0x006a j
.c0x006b k
.c0x006c l
.c0x006d m
.c0x006e n
.c0x006f o
.c0x0070 p
.c0x0071 q
.c0x0072 r
.c0x0073 s
.c0x0074 t
.c0x0075 u
.c0x0076 v
.c0x0077 w
.c0x0078 x
.c0x0079 y
.c0x007a z
.c0x007b braceleft
.c0x007c bar
.c0x007d braceright
.c0x007e asciitilde
.c0x0080 Agrave
.c0x0081 Ahookabove
.c0x008d Abreveacute
.c0x008e Abrevegrave
.c0x008f Abrevehookabove
.c0x0090 Ecircumflexacute
.c0x009d Ohornacute
.c0x009e Ohorngrave
.c0x00a0 nbspace
.c0x00a1 abreveacute
.c0x00a2 abrevegrave
.c0x00a3 abrevehookabove
.c0x00a4 abrevetilde
.c0x00a5 abrevedotbelow
.c0x00a6 Ohorntilde
.c0x00a7 ohornacute
.c0x00a8 Ugrave
.c0x00a9 ohorngrave
.c0x00aa ohornhookabove
.c0x00ab ohorntilde
.c0x00ac Utilde
.c0x00ad Uhornacute
.c0x00ae ohorndotbelow
.c0x00af Uhorngrave
.c0x00b0 ocircumflexhookabove
.c0x00b1 Uhornhookabove
.c0x00b2 Ygrave
.c0x00b3 Ytilde
.c0x00b4 Iacute
.c0x00b5 Igrave
.c0x00b6 ocircumflexdotbelow
.c0x00b8 Itilde
.c0x00b9 Oacute
.c0x00ba uhornhookabove
.c0x00bb uhorntilde
.c0x00bc Ograve
.c0x00bd Ohookabove
.c0x00be Otilde
.c0x00bf uhorndotbelow
.c0x00c0 acircumflexgrave
.c0x00c1 Aacute
.c0x00c2 Acircumflex
.c0x00c3 acircumflexacute
.c0x00c4 acircumflexhookabove
.c0x00c5 acircumflextilde
.c0x00c6 acircumflexdotbelow
.c0x00c7 dbar
.c0x00c8 ehookabove
.c0x00c9 Eacute
.c0x00ca Ecircumflex
.c0x00cb edotbelow
.c0x00cc ihookabove
.c0x00cd ecircumflextilde
.c0x00ce idotbelow
.c0x00cf ytilde
.c0x00d0 Uhorn
.c0x00d1 Uhookabove
.c0x00d2 ocircumflexgrave
.c0x00d3 ocircumflexacute
.c0x00d4 Ocircumflex
.c0x00d5 ohookabove
.c0x00d6 ohorn
.c0x00d7 Egrave
.c0x00d8 uhorngrave
.c0x00d9 uhornacute
.c0x00da Uacute
.c0x00db utilde
.c0x00dc uhorn
.c0x00dd Yacute
.c0x00de Ehookabove
.c0x00df germandbls
.c0x00e0 agrave
.c0x00e1 aacute
.c0x00e2 acircumflex
.c0x00e3 atilde
.c0x00e4 ahookabove
.c0x00e5 adotbelow
.c0x00e6 abreve
.c0x00e7 ccedilla
.c0x00e8 egrave
.c0x00e9 eacute
.c0x00ea ecircumflex
.c0x00eb etilde
.c0x00ec igrave
.c0x00ed iacute
.c0x00ee icircumflex
.c0x00ef itilde
.c0x00f0 Abrevetilde
.c0x00f1 Dbar
.c0x00f2 ograve
.c0x00f3 oacute
.c0x00f4 ocircumflex
.c0x00f5 otilde
.c0x00f6 odieresis
.c0x00f7 Ohorn
.c0x00f8 udotbelow
.c0x00f9 ugrave
.c0x00fa uacute
.c0x00fb uhookabove
.c0x00fc udieresis
.c0x00fd Yhookabove
.c0x00fe Etilde
.c0x00ff ygrave
.c0x0152 ecircumflexdotbelow
.c0x0153 ydotbelow
.c0x0160 ecircumflexgrave
.c0x0161 yacute
.c0x0178 Ohornhookabove
.c0x0192 Acircumflexacute
.c0x02c6 Abreve
.c0x02dc Ocircumflexhookabove
.c0x2013 Ocircumflexacute
.c0x2014 Ocircumflexgrave
.c0x2018 quoteleft
.c0x2019 quoteright
.c0x201a Atilde
.c0x201c Ecircumflexgrave
.c0x201d Ecircumflexhookabove
.c0x201e Acircumflexgrave
.c0x2020 odotbelow
.c0x2021 ocircumflextilde
.c0x2022 Ecircumflextilde
.c0x2026 Acircumflexhookabove
.c0x2030 ecircumflexacute
.c0x2039 ecircumflexhookabove
.c0x203a yhookabove
.c0x2122 Ocircumflextilde
.c0x2219 Ihookabove
% eof

View File

@@ -0,0 +1,18 @@
% These entries are just examples!
arials arial.ttf Slant=0.25
arial arial.ttf Slant=0 Extend=1 Pid = 1 Eid = 0
arialx arial.ttf Slant=0 Extend=1.5
times times.ttf Encoding=T1-WGL4.enc \
.g0xc7=ring .g0xc9=caron .g0xc4=dotlessi
times95 times95.ttf Encoding=T1-WGL4.enc
ntukai@Big5@ ntu_kai.ttf Pid = 3 Eid = 4
cyberb@Unicode@ cyberbit.ttf
% the next entry maps the Unicode encoded font to Big 5 encoding; thus you
% can say \begin{CJK}{Big5}{...} (this is an environment from the CJK
% package for LaTeX).
mingli@UBig5@ mingliu.ttc Fontindex = 0

334
contrib/ttf2pk/dvidrv.btm Normal file
View File

@@ -0,0 +1,334 @@
::
:: This is dvidrv.btm, a batch file for 4DOS/4OS2 written by
:: Werner Lemberg <wl@gnu.org> partially based on the
:: dvidrv.btm file of the 4allTeX package written by Phons Bloemen.
::
:: It is a replacement for dvidrv.exe of the emTeX package.
::
:: Additional features: support of ps2pk
:: support of ttf2pk
:: support of hbf2gf for HBFs (Hanzi bitmap fonts)
::
:: Only quadratic printer modes are supported for ttf2pk!
::
:: All needed binaries will be searched in the path.
iff %# lt 2 then
echo ``
echo Usage: %0 dvi-driver dvi-file [parameters]
quit
endiff
setlocal
:: we set a default value only if the corresponding environment variable
:: is empty. The `=' must follow the variable name immediately.
alias set_def `iff "%[%@word["=",0,%1]]" eq "" then %+ set %& %+ endiff`
:: =========================================
:: ======== User defined variables. ========
:: =========================================
::
:: Can be overridden in the environment (except %ps2pk, %ttf2pk, %hbf2gf,
:: %pre_dpi, and %post_dpi).
:: Set these values to `no' for the programs you don't want to use.
set ps2pk=yes
set ttf2pk=yes
set hbf2gf=yes
:: where the PK files will be installed created by ps2pk, ttf2pk, and
:: hbf2gf.
:: dvidrv.btm adds `\modeless\XXXdpi' to this string (see below for the
:: exact string).
set_def pkdir=%emtexdir\pixel\tmp\pk
:: where the TrueType fonts reside. Supports trailing `!' and `!!'.
set_def ttfonts=%emtexdir\fonts\truetype
:: where auxiliary files of ttf2pk are located. Supports trailing `!'
:: and `!!'.
set_def ttfcfg=%emtexdir\ttf2pk
:: where the HBF files reside. Supports trailing `!' and `!!'.
set_def hbfonts=%emtexdir\fonts\hbf
:: where the hbf2gf config files are. Supports trailing `!' and `!!'.
set_def hbfcfg=%emtexdir\hbf2gf
:: the dpi-subdirectory has various forms; the most common are XXXdpi and
:: dpiXXX, e.g. 300dpi and dpi300. Here we define two variables which
:: control this behaviour.
:: [dpiXXX is used for TDS compatible TeX trees.]
set pre_dpi=dpi
set post_dpi=
:: ================================================
:: ======== End of user defined variables. ========
:: ================================================
:: the base name for log files etc.
set basename=%@name[%1]
:: do we run dvips?
iff "%basename" ne "dvips" then
goto nodvips1
endiff
:: we delete dvips.mfj if it exists.
del dvips.mfj >& nul
:: now we run dvips with all supplied parameters.
%&
:: do we have to generate fonts?
iff exist dvips.mfj then
goto generate_fonts
endiff
:: else all is done.
goto end
:nodvips1
:: here we call the dvi driver with all supplied parameters.
%& -pj:%basename.mfj
:: do we have to generate fonts?
iff errorlevel 8 then
goto generate_fonts
endiff
:: else all is done.
goto end
:generate_fonts
gosub call_mfjob
:: do we run dvips?
iff "%basename" ne "dvips" then
goto nodvips2
endiff
:: we now call dvips a second time
%&
:: since no fonts will be generated in the second run we remove dvips.mfj
del dvips.mfj >& nul
goto end
:nodvips2
:: we call the dvi driver a second time (without font generation).
%& -pj -fm
del %basename.mfj >& nul
goto end
:: this is the main subroutine which calls mfjob and then parses the mfjob
:: file for fonts which can be handled by ps2pk, ttf2pk, or hbf2gf.
:call_mfjob
:: this alias prints a message on the screen and writes it into the logfile.
alias echolog=`echo %& | tee /a %basename.mlg`
echo ======== DVIDRV.BTM logfile ======== > %basename.mlg
echo Commandline: dvidrv.btm %& >> %basename.mlg
echo `` >> %basename.mlg
echo basename=%basename >> %basename.mlg
echo emtexdir=%emtexdir >> %basename.mlg
echo dvidrvfonts=%dvidrvfonts >> %basename.mlg
echo mfinput=%mfinput >> %basename.mlg
echo mfjobopt=%mfjobopt >> %basename.mlg
echo textfm=%textfm >> %basename.mlg
echo psfonts=%psfonts >> %basename.mlg
echo ttfonts=%ttfonts >> %basename.mlg
echo ttfcfg=%ttfcfg >> %basename.mlg
echo hbfonts=%hbfonts >> %basename.mlg
echo hbfcfg=%hbfcfg >> %basename.mlg
echo `` >> %basename.mlg
iff "%@search[mfjob]" eq "" then
echolog MFJOB not found in the path.
echolog Can't generate PK fonts from METAFONT automatically.
echo ``
quit
endiff
:: now we call mfjob.
echolog mfjob %mfjobopt -g%basename.mfl %basename.mfj
mfjob %mfjobopt -g%basename.mfl %basename.mfj
iff %? gt 0 then
echolog ``
echolog Something went wrong while running METAFONT.
echolog Look into the log files...
echolog ``
endiff
:: after running mfjob we scan the mfjob input file for fonts which can
:: be handled by ps2pk, ttf2pk, or hbf2gf.
set lnnr=0
set totlines=%@lines[%basename.mfj]
do while %lnnr le %totlines
:: input a line.
set scratch=%@line[%basename.mfj,%lnnr]
set lnnr=%@inc[%lnnr]
:: get resolutions (METAFONT mode will be ignored).
:: example:
:: mode=lqlores[180 180];
iff %@index[%scratch,mode] ge 0 then
set temp=%@word["[]",1,%scratch]
set xdpi=%@word[0,%temp]
set ydpi=%@word[1,%temp]
endiff
:: get fontname and magnification; we then compute the font resolutions
:: (rounded to the nearest integer---there is no necessity to adjust
:: these values further because of possible rounding errors since both
:: emTeX's dvi drivers and dvips check neighbored values too).
:: example:
:: {font=cmr10; mag=0.5;}
iff %@index[%scratch,{font] ge 0 then
set testfont=%@word["=;",1,%scratch]
set temp=%@word["=;",3,%scratch]
:: we use highest arithmetic precision for these calculations.
:: Additionally we write 1/2 instead of 0.5 to avoid problems with
:: countries which use a comma instead of a colon as the decimal
:: separator.
set fontresx=%@int[%@eval[%xdpi*%temp+1/2=8]]
set fontresy=%@int[%@eval[%ydpi*%temp+1/2=8]]
set pksubdir=modeless\%[pre_dpi]%[fontresx]%post_dpi
set success=0
:: check whether %testfont leads to a PS font (we call ps2pkmfj).
iff %success == 0 .and. "%ps2pk" eq "yes" then
gosub call_ps2pk
endiff
:: check whether %testfont leads to a TrueType font.
iff %success == 0 .and. "%ttf2pk" eq "yes" then
gosub call_ttf2pk
endiff
:: check whether %testfont leads to a HBF file.
iff %success == 0 .and. "%hbf2gf" eq "yes" then
gosub call_hbf2gf
endiff
endiff
enddo
iff exist %basename.mfp then
echo `` >> %basename.mlg
echo `` >> %basename.mlg
echo ======== PS2PK logfile ======== >> %basename.mlg
echo `` >> %basename.mlg
type %basename.mfp >> %basename.mlg
echo `` >> %basename.mlg
del %basename.mfp >& nul
endiff
iff exist %basename.mfl then
echo `` >> %basename.mlg
type %basename.mfl >> %basename.mlg
echo `` >> %basename.mlg
del %basename.mfl >& nul
endiff
return
:call_ttf2pk
iff "%@search[ttf2pk]" eq "" then
echolog TTF2PK not found in the path.
echolog Can't generate PK fonts from TrueType fonts automatically.
echo ``
quit
endiff
echolog ttf2pk -q -n %testfont %fontresx
ttf2pk -q -n %testfont %fontresx
iff %? == 0 then
echolog Font %pkdir\%pksubdir\%testfont.pk generated.
mkdir /s %pkdir\%pksubdir >& nul
move %testfont.pk %pkdir\%pksubdir >& nul
set success=1
elseiff %? == 2 then
echolog (%lnnr/%totlines): Font %testfont is no TrueType font.
set success=0
else
echolog Error running TTF2PK for font %testfont!
endiff
return
:call_hbf2gf
iff "%@search[hbf2gf]" eq "" then
echolog HBF2GF not found in the path.
echolog Can't generate PK fonts from HBF files automatically.
echo ``
quit
endiff
echolog hbf2gf -q -p -n %testfont %fontresx %fontresy
hbf2gf -q -p -n %testfont %fontresx %fontresy
iff %? == 0 then
echolog Font %pkdir\%pksubdir\%testfont.pk generated.
mkdir /s %pkdir\%pksubdir >& nul
gftopk %testfont.gf %testfont.pk
move %testfont.pk %pkdir\%pksubdir >& nul
del %testfont.gf >& nul
set success=1
elseiff %? == 2 then
echolog (%lnnr/%totlines): Font %testfont is no HBF.
set success=0
else
echolog Error running HBF2GF for font %testfont!
endiff
return
:call_ps2pk
iff not exist %pkdir\%pksubdir\%testfont.pk then
iff "%@search[ps2pkmfj]" eq "" .or. "%@search[ps2pk]" eq "" then
echolog PS2PKMFJ and/or PS2PK not found in the path.
echolog Can't generate PK fonts from PostScript fonts automatically.
echo ``
quit
endiff
echolog ps2pkmfj -X%fontresx -Y%fontresy %testfont %testfont.pk
ps2pkmfj -X%fontresx -Y%fontresy %testfont %testfont.pk | input %%pspkline
iff errorlevel != 1 then
%pspkline >> %basename.mfp
iff %? == 0 then
echolog Font %pkdir\%pksubdir\%testfont.pk generated.
mkdir /s %pkdir\%pksubdir >& nul
move %testfont.pk %pkdir\%pksubdir >& nul
success=1
else
echolog Error running PS2PK for font %testfont!
endiff
else
echolog (%lnnr/%totlines): Font %testfont is no PS font.
success=0
endiff
else
echolog Font %pkdir\%pksubdir\%testfont.pk already exists.
endiff
return
:end
endlocal
:: ==== end of dvidrv.btm ====

56
contrib/ttf2pk/dvidrv.doc Normal file
View File

@@ -0,0 +1,56 @@
Using dvidrv.btm [emTeX for DOS and OS/2]
-------------------------------------------
This batch file does the same as MakeTeXPK does; it is a replacement for
dvidrv.exe of emTeX which can handle ttf2pk, hbf2gf, and ps2pk additionally
(the ps2pk part is untested yet; it uses ps2pkmfj of the 4allTeX
distribution and was basically copied from a similar script, also part of
4allTeX).
First of all, create and install a set of TFM files as described in the
previous section.
Then configure the following variables in dvidrv.btm:
ps2pk ... set it to `yes' if you want to use this program
ttf2pk ... ditto
hbf2gf ... ditto
pkdir ... the place where PK files created by ps2pk, ttf2pk,
or hbf2gf should go to. dvidrv.btm adds
`\modeless\XXXdpi' resp. `\modeless\dpiXXX' to this
string (depending on the variables `pre_dpi' and
`post_dpi')
ttfonts ... where the TrueType fonts files reside
ttfcfg ... where the auxiliary data files of ttf2pk reside
hbfonts ... where the HBF files reside
hbfcfg ... the place where the hbf2gf configuration files are
The last four variables in the above list support trailing `!' and `!!' for
recursive directory searching (see the dvidrv.doc of the emTeX package for
details).
Alternatively, you can set these variables in the environment; please note
that no spaces are allowed before and after the equal sign, e.g.
set foo=bar
is OK, but
set foo = bar
will fail.
Rename dvidrv.exe to dvidrv.ori or something similar and copy dvidrv.btm to
a directory in the path.
Don't forget to update the DVIDRVFONTS and TEXTFM environment variables if
necessary.
Under OS/2 dvips will call mfjob or hbf2gf itself; under DOS it will create
a batch file which must be called afterwards.
--- end of dvidrv.doc ---

109
contrib/ttf2pk/emdir.c Normal file
View File

@@ -0,0 +1,109 @@
/* emdir.c -- Written by Eberhard Mattes, donated to the public domain */
#include "emdir.h"
#ifdef OS2
#undef HPS
#define INCL_DOSFILEMGR
#include <os2.h>
#include <string.h>
#define FHDIR(b) (*(HDIR *)(b)->reserved)
static void fconv (struct ll_findbuffer *dst, const FILEFINDBUF *src)
{
dst->attr = src->attrFile;
dst->time = *(unsigned *)&src->ftimeLastWrite;
dst->date = *(unsigned *)&src->fdateLastWrite;
dst->size = src->cbFile;
strcpy (dst->name, src->achName);
}
int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer)
{
USHORT rc;
ULONG count;
HDIR hdir;
FILEFINDBUF ffbuf;
hdir = HDIR_CREATE;
count = 1;
rc = DosFindFirst ((PSZ)path, &hdir, attr, &ffbuf, sizeof (ffbuf),
&count, 0L);
if (rc != 0 || count != 1)
return 0;
FHDIR (buffer) = hdir;
fconv (buffer, &ffbuf);
return 1;
}
int ll_findnext (struct ll_findbuffer *buffer)
{
USHORT rc;
ULONG count;
HDIR hdir;
FILEFINDBUF ffbuf;
hdir = FHDIR (buffer);
count = 1;
rc = DosFindNext (hdir, &ffbuf, sizeof (ffbuf), &count);
if (rc != 0 || count != 1)
{
DosFindClose (hdir);
return 0;
}
fconv (buffer, &ffbuf);
return 1;
}
#elif defined(DJGPP)
/* djgpp support by Hartmut Schirmer (hsc@techfak.uni-kiel.de), May 30, 1997 */
#include <dos.h>
#include <dir.h>
static int ll_attr = 0;
int ll_findnext (struct ll_findbuffer *buffer)
{
int res;
do {
res = _dos_findnext ((struct find_t *)buffer);
if (res != 0) return 0;
} while ( (buffer->attrib&ll_attr) == 0);
return 1;
}
int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer)
{
int res;
ll_attr = attr;
res = _dos_findfirst((char *)path, attr, (struct find_t *)buffer);
if (res != 0) return 0;
if ( (buffer->attrib&ll_attr) == 0)
return ll_findnext(buffer);
return 1;
}
#elif !defined(__EMX__) /* if not OS2 nor DJGPP nor __EMX__ defined */
/* Not tested */
#include <dos.h>
int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer)
{
return _dos_findfirst (path, attr, (struct find_t *)buffer) == 0;
}
int ll_findnext (struct ll_findbuffer *buffer)
{
return _dos_findnext ((struct find_t *)buffer) == 0;
}
#endif

25
contrib/ttf2pk/emdir.h Normal file
View File

@@ -0,0 +1,25 @@
/* emdir.h -- Written by Eberhard Mattes, donated to the public domain */
#if defined(DJGPP)
/* djgpp support by Hartmut Schirmer (hsc@techfak.uni-kiel.de), May 30, 1997 */
#include <dos.h>
#define ll_findbuffer find_t
#define attr attrib
#else
struct ll_findbuffer
{
char reserved[21];
unsigned char attr;
unsigned time;
unsigned date;
long size;
char name[257];
};
#endif
int ll_findfirst (const char *path, int attr, struct ll_findbuffer *buffer);
int ll_findnext (struct ll_findbuffer *buffer);

405
contrib/ttf2pk/emtexdir.c Normal file
View File

@@ -0,0 +1,405 @@
/* emtexdir.c -- written by Eberhard Mattes, donated to the public domain */
#if defined (__EMX__)
#include <emx/syscalls.h>
#else
#include "emdir.h"
#endif
#if defined(DJGPP) || defined(GO32)
#include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include "emtexdir.h"
#define FALSE 0
#define TRUE 1
void (*emtex_dir_find_callback)(const char *name, int ok) = NULL;
static int setup_add (struct emtex_dir *dst, const char *path)
{
char *p;
if (dst->used >= dst->alloc)
{
dst->alloc += 8;
dst->list = realloc (dst->list, dst->alloc * sizeof (*dst->list));
if (dst->list == NULL)
return (FALSE);
}
p = strdup (path);
if (p == NULL)
return (FALSE);
dst->list[dst->used++] = p;
return (TRUE);
}
static int setup_subdir (struct emtex_dir *dst, char *path, size_t add,
unsigned flags, int recurse)
{
int ok, i, end, len;
#if defined (__EMX__)
struct _find find;
#else
struct ll_findbuffer find;
#endif
i = dst->used;
strcpy (path + add, "*.*");
#if defined (__EMX__)
ok = __findfirst (path, 0x10, &find) == 0;
#else
ok = ll_findfirst (path, 0x10, &find);
#endif
while (ok)
{
if ((find.attr & 0x10)
&& !(strcmp (find.name, ".") == 0 || strcmp (find.name, "..") == 0))
{
len = strlen (find.name);
memcpy (path + add, find.name, len);
path[add+len] = '\\';
path[add+len+1] = 0;
if (!setup_add (dst, path))
return (FALSE);
}
#if defined (__EMX__)
ok = __findnext (&find) == 0;
#else
ok = ll_findnext (&find);
#endif
}
if (recurse)
{
end = dst->used;
while (i < end)
{
strcpy (path, dst->list[i]);
if (!setup_subdir (dst, path, strlen (path), flags, TRUE))
return (FALSE);
++i;
}
}
return (TRUE);
}
static int setup_dir (struct emtex_dir *dst, char *path,
const char *base_dir, size_t base_dir_len,
const char *sub_dir,
unsigned flags)
{
size_t i, len;
memcpy (path, base_dir, base_dir_len);
i = base_dir_len;
if ((flags & EDS_BANG) && sub_dir == NULL)
{
flags &= ~(EDS_ONESUBDIR|EDS_ALLSUBDIR);
if (i >= 2 && path[i-1] == '!' && path[i-2] == '!')
{
flags |= EDS_ALLSUBDIR;
i -= 2;
}
else if (i >= 1 && path[i-1] == '!')
{
flags |= EDS_ONESUBDIR;
--i;
}
}
if (sub_dir != NULL && *sub_dir != 0)
{
if (i != 0 && path[i-1] != ':' && path[i-1] != '/' && path[i-1] != '\\')
path[i++] = '\\';
len = strlen (sub_dir);
memcpy (path+i, sub_dir, len);
i += len;
}
if (path[i-1] != ':' && path[i-1] != '/' && path[i-1] != '\\')
path[i++] = '\\';
path[i] = 0;
if (!setup_add (dst, path))
return (FALSE);
if (flags & EDS_ALLSUBDIR)
return (setup_subdir (dst, path, i, flags, TRUE));
else if (flags & EDS_ONESUBDIR)
return (setup_subdir (dst, path, i, flags, FALSE));
else
return (TRUE);
}
/*static */int setup_list (struct emtex_dir *dst, char *path,
const char *list, unsigned flags)
{
const char *end;
size_t i;
for (;;)
{
while (*list == ' ' || *list == '\t')
++list;
if (*list == 0)
return (TRUE);
end = list;
while (*end != 0 && *end != ';')
++end;
i = end - list;
while (i > 0 && (list[i-1] == ' ' || list[i-1] == '\t'))
--i;
if (i != 0 && !setup_dir (dst, path, list, i, NULL, flags))
return (FALSE);
if (*end == 0)
return (TRUE);
list = end + 1;
}
}
int emtex_dir_setup (struct emtex_dir *ed, const char *env, const char *dir,
unsigned flags)
{
const char *val;
char path[260];
ed->alloc = 0;
ed->used = 0;
ed->list = NULL;
if (env != NULL && (val = getenv (env)) != NULL)
return (setup_list (ed, path, val, flags));
else if ((val = getenv ("EMTEXDIR")) != NULL)
return (setup_dir (ed, path, val, strlen (val), dir, flags));
else
return (setup_dir (ed, path, "\\emtex", 6, dir, flags));
}
static void pretty (char *path, unsigned flags)
{
char *p;
if (flags & EDF_FSLASH)
for (p = path; *p != 0; ++p)
if (*p == '\\')
*p = '/';
}
#define ADDCHAR(C) \
if (dst_size < 1) return (EDT_TOOLONG); \
*dst++ = (C); --dst_size
int emtex_dir_trunc (char *dst, size_t dst_size, const char *src,
unsigned flags, int method)
{
int len, truncated, dot;
if (src[0] != 0 && src[1] == ':')
{
ADDCHAR (src[0]);
ADDCHAR (src[1]);
src += 2;
}
truncated = FALSE; dot = FALSE; len = 0;
for (;;)
{
switch (*src)
{
case 0:
ADDCHAR (0);
return (truncated ? EDT_CHANGED : EDT_UNCHANGED);
case ':':
return (EDT_INVALID);
case '/':
case '\\':
ADDCHAR (*src);
len = 0; dot = FALSE;
break;
case '.':
if (dot)
return (EDT_INVALID);
ADDCHAR (*src);
/* ".." is allowed -- don't return EDT_INVALID for the next
dot. */
if (!(len == 0 && src[1] == '.'
&& (src[2] == 0 || src[2] == '/' || src[2] == '\\')))
{
len = 0; dot = TRUE;
}
break;
default:
if (dot && len == 3)
truncated = TRUE;
else if (!dot && len == 8)
{
truncated = TRUE;
if (method == 0)
{
dst[-3] = dst[-2];
dst[-2] = dst[-1];
dst[-1] = *src;
}
}
else
{
ADDCHAR (*src);
++len;
}
break;
}
++src;
}
}
static int find2 (const char *name, unsigned flags)
{
int ok;
ok = (access (name, 4) == 0);
if (flags & EDF_TRACE)
emtex_dir_find_callback (name, ok);
return (ok);
}
static int find1 (char *path, size_t path_size, const char *dir,
const char *fname, unsigned flags)
{
char buf[260];
int method, rc;
size_t len, tmp;
len = 0;
if (dir != NULL)
{
tmp = strlen (dir);
if (tmp >= sizeof (buf))
return (FALSE);
memcpy (buf, dir, tmp);
len = tmp;
}
tmp = strlen (fname);
if (len + tmp >= sizeof (buf))
return (FALSE);
memcpy (buf + len, fname, tmp + 1);
len += tmp;
#if 0 /* wkim */
/* disabled for Win95's long file name support */
/* -- Wonkoo Kim (wkim+@pitt.edu), May 18, 1997 */
if (_osmode == DOS_MODE)
{
rc = emtex_dir_trunc (path, path_size, buf, flags, EDT_5_PLUS_3);
if ((rc == EDT_UNCHANGED || rc == EDT_CHANGED) && find2 (path, flags))
{
pretty (path, flags);
return (TRUE);
}
rc = emtex_dir_trunc (path, path_size, buf, flags, EDT_8);
if (rc == EDT_CHANGED && find2 (path, flags))
{
pretty (path, flags);
return (TRUE);
}
return (FALSE);
}
else
#endif /* wkim */
{
if (len < path_size && find2 (buf, flags))
{
memcpy (path, buf, len + 1);
pretty (path, flags);
return (TRUE);
}
for (method = 0; method < 2; ++method)
{
rc = emtex_dir_trunc (path, path_size, buf, flags, method);
if (rc == EDT_CHANGED && find2 (path, flags))
{
pretty (path, flags);
return (TRUE);
}
}
return (FALSE);
}
}
int emtex_dir_find (char *path, size_t path_size,
const struct emtex_dir *ed,
const char *fname, unsigned flags)
{
int i, absp;
const char *p;
absp = FALSE;
for (p = fname; *p != 0; ++p)
if (*p == ':' || *p == '/' || *p == '\\')
{
absp = TRUE;
break;
}
if (absp)
return (find1 (path, path_size, NULL, fname, flags));
if ((flags & EDF_CWD) && find1 (path, path_size, NULL, fname, flags))
return (TRUE);
for (i = 0; i < ed->used; ++i)
if (find1 (path, path_size, ed->list[i], fname, flags))
return (TRUE);
return (FALSE);
}
#if defined (TEST)
#include <stdio.h>
int main (int argc, char *argv[])
{
struct emtex_dir ed;
int i;
unsigned flags1, flags2;
char path[260];
if (argc != 6)
{
puts ("Usage: emtexdir <flags> <flags> <env> <dir> <fname>");
return (1);
}
flags1 = (unsigned)strtol (argv[1], NULL, 0);
flags2 = (unsigned)strtol (argv[2], NULL, 0);
if (!emtex_dir_setup (&ed, argv[3], argv[4], flags1))
{
fputs ("emtex_dir_setup failed\n", stderr);
return (2);
}
printf ("Directories:\n");
for (i = 0; i < ed.used; ++i)
printf (" %s\n", ed.list[i]);
if (!emtex_dir_find (path, sizeof (path), &ed, argv[5], flags2))
puts ("File not found");
else
printf ("Path: %s\n", path);
return (0);
}
#endif

57
contrib/ttf2pk/emtexdir.h Normal file
View File

@@ -0,0 +1,57 @@
/* emtexdir.h -- written by Eberhard Mattes, donated to the public domain */
#if !defined (_EMTEXDIR_H)
#define _EMTEXDIR_H
#if defined (__cplusplus)
extern "C" {
#endif
/* Flags for emtex_dir_setup */
#define EDS_ONESUBDIR 0x0001
#define EDS_ALLSUBDIR 0x0002
#define EDS_BANG 0x0004
/* Flags for emtex_dir_find */
#define EDF_CWD 0x0001
#define EDF_FSLASH 0x0002
#define EDF_TRACE 0x8000
/* Methods for emtex_dir_trunc */
#define EDT_5_PLUS_3 0 /* 5+3.3 */
#define EDT_8 1 /* 8.3 */
/* Return values for emtex_dir_trunc */
#define EDT_UNCHANGED 0 /* Path name not changed */
#define EDT_CHANGED 1 /* Path name truncated */
#define EDT_TOOLONG 2 /* Path name too long */
#define EDT_INVALID 3 /* Path name invalid */
struct emtex_dir
{
char **list;
int used;
int alloc;
};
extern void (*emtex_dir_find_callback)(const char *name, int ok);
int emtex_dir_setup (struct emtex_dir *ed, const char *env, const char *dir,
unsigned flags);
int emtex_dir_find (char *path, size_t path_size, const struct emtex_dir *ed,
const char *fname, unsigned flags);
int emtex_dir_trunc (char *dst, size_t dst_size, const char *src,
unsigned flags, int method);
#if defined (__cplusplus)
}
#endif
#endif /* !defined (_EMTEXDIR_H) */

96
contrib/ttf2pk/errormsg.c Normal file
View File

@@ -0,0 +1,96 @@
/*
* errormsg.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <stdio.h>
#include <stddef.h> /* for size_t */
#include <stdarg.h>
#include <stdlib.h>
#include "errormsg.h"
extern char progname[]; /* the origin of the error/warning message */
/*
* Print error message and quit.
*/
void
oops(const char *message,
...)
{
va_list args;
va_start(args, message);
fprintf(stderr, "%s: ERROR: ", progname);
vfprintf(stderr, message, args);
va_end(args);
putc('\n', stderr);
exit(1);
}
/*
* Print error message, a buffer, a '^' at the buffer offset, and quit.
*/
void
boops(const char *buffer,
size_t offset,
const char *message,
...)
{
va_list args;
va_start(args, message);
fprintf(stderr, "%s: ERROR: ", progname);
vfprintf(stderr, message, args);
va_end(args);
putc('\n', stderr);
if (*buffer)
{
fprintf(stderr, "%s\n", buffer);
while (offset)
{
fprintf(stderr, " ");
offset--;
}
fprintf(stderr, "^\n");
}
exit(1);
}
/*
* Print warning message and continue.
*/
void
warning(const char *message,
...)
{
va_list args;
va_start(args, message);
fprintf(stderr, "%s: WARNING: ", progname);
vfprintf(stderr, message, args);
va_end(args);
putc('\n', stderr);
}
/* end */

43
contrib/ttf2pk/errormsg.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* errormsg.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef ERRORMSG_H
#define ERRORMSG_H
/*
Disable some annoying warnings when you compile with -W3. Namely the
warnings about missing __cdecl specifiers at some places where they are
not really needed because the compiler can generate them.
This is relevant only if you compile with -Gr option, i.e., use fastcall
calling convention.
This is needed for fpTeX.
*/
#ifdef WIN32
#pragma warning (disable : 4007 4096)
#endif
void oops(const char *message,
...);
void boops(const char *buffer,
size_t offset,
const char *message,
...);
void warning(const char *message,
...);
#endif /* ERRORMSG_H */
/* end */

602
contrib/ttf2pk/filesrch.c Normal file
View File

@@ -0,0 +1,602 @@
/*
* filesrch.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
/*
* Interface to the system specific TeX file search routines.
*/
#include <stddef.h> /* for size_t */
#include <stdlib.h>
#include <string.h>
#include "filesrch.h"
#include "newobj.h"
/****************************
* kpathsea library support *
****************************/
#if defined(HAVE_LIBKPATHSEA)
#ifdef VERY_OLD_KPATHSEA
#include "kpathsea/proginit.h"
#include "kpathsea/progname.h"
#include "kpathsea/tex-glyph.h"
#else
#include "kpathsea/kpathsea.h"
#endif
#ifdef KPSEDLL
/* this is kpathsea 3.3 and newer */
extern KPSEDLL char *kpathsea_version_string;
#else
extern DllImport char *kpathsea_version_string;
#endif
/*
* Initialize kpathsea library; arguments are the full name of the
* executable (e.g. `/usr/bin/ttf2pk') and two identification strings;
* the former for the program itself (to have texmf.cnf constructs like
* `TFMFONTS.ttf2pk'), the latter for the environment (to have environment
* constructs like `TTF2PKMAKEPK').
*/
void
TeX_search_init(char *exec_name,
char *program_identifier,
char *env_identifier)
{
#ifdef OLD_KPATHSEA
kpse_set_progname(exec_name);
#else
kpse_set_program_name(exec_name, program_identifier);
#endif
#ifdef VERY_OLD_KPATHSEA
kpse_init_prog(env_identifier, 300, "cx", true, "cmr10");
#else
kpse_init_prog(env_identifier, 300, "cx", "cmr10");
#endif
}
char *
TeX_search_version(void)
{
return kpathsea_version_string;
}
char *
TeX_search_tfm(char **name)
{
/* no extra extension handling necessary */
return kpse_find_file(*name, kpse_tfm_format, True);
}
char *
TeX_search_encoding_file(char **name)
{
handle_extension(name, ".enc");
#ifdef OLD_KPATHSEA
#ifdef VERY_OLD_KPATHSEA
return kpse_find_file(*name, kpse_dvips_header_format, True);
#else
return kpse_find_file(*name, kpse_tex_ps_header_format, True);
#endif
#else
return kpse_find_file(*name, kpse_program_text_format, True);
#endif
}
char *
TeX_search_replacement_file(char **name)
{
handle_extension(name, ".rpl");
#ifdef OLD_KPATHSEA
#ifdef VERY_OLD_KPATHSEA
return kpse_find_file(*name, kpse_dvips_header_format, True);
#else
return kpse_find_file(*name, kpse_tex_ps_header_format, True);
#endif
#else
return kpse_find_file(*name, kpse_program_text_format, True);
#endif
}
char *
TeX_search_sfd_file(char **name)
{
handle_extension(name, ".sfd");
#ifdef OLD_KPATHSEA
#ifdef VERY_OLD_KPATHSEA
return kpse_find_file(*name, kpse_dvips_header_format, True);
#else
return kpse_find_file(*name, kpse_tex_ps_header_format, True);
#endif
#else
return kpse_find_file(*name, kpse_program_text_format, True);
#endif
}
char *
TeX_search_config_file(char **name)
{
/* no extra extension handling necessary */
#ifdef OLD_KPATHSEA
return kpse_find_file(*name, kpse_dvips_config_format, True);
#else
return kpse_find_file(*name, kpse_program_text_format, True);
#endif
}
char *
TeX_search_ttf_file(char **name)
{
#ifdef OLD_KPATHSEA
size_t l;
char* real_name;
l = strlen(*name);
handle_extension(name, ".ttf");
#ifdef VERY_OLD_KPATHSEA
real_name = kpse_find_file(*name, kpse_dvips_header_format, True);
#else
real_name = kpse_find_file(*name, kpse_type1_format, True);
#endif
/* test for .ttc, but only if no extension was given initially */
if (!real_name && l != strlen(*name))
{
(*name)[strlen(*name) - 1] = 'c';
#ifdef VERY_OLD_KPATHSEA
real_name = kpse_find_file(*name, kpse_dvips_header_format, True);
#else
real_name = kpse_find_file(*name, kpse_type1_format, True);
#endif
}
return real_name;
#else /* OLD_KPATHSEA */
/* no extra extension handling necessary */
return kpse_find_file(*name, kpse_truetype_format, True);
#endif
}
/****************************
* emtexdir library support *
****************************/
#elif defined(HAVE_EMTEXDIR)
#include "emtexdir.h"
#include "errormsg.h"
extern int setup_list(struct emtex_dir *dst, char *path,
const char *list, unsigned flags);
char emtex_version_string[] = "emTeXdir";
struct emtex_dir tfm_path,
enc_path,
rpl_path,
sfd_path,
cfg_path,
ttf_path;
/*
* We slightly modify emtex_dir_setup() to output a warning in case
* the environment variable isn't set properly.
*/
static int
dir_setup(struct emtex_dir *ed,
const char *env,
const char *dir,
unsigned flags)
{
const char *val;
char path[260];
ed->alloc = 0;
ed->used = 0;
ed->list = NULL;
if (env != NULL && (val = getenv(env)) != NULL)
return setup_list(ed, path, val, flags);
else
warning("Environment variable %s not set; use current directory.", env);
return True;
}
static char *
file_find(char *name, struct emtex_dir *list)
{
char buffer[1024];
if (emtex_dir_find(buffer, sizeof (buffer), list, name, EDF_CWD))
return newstring(buffer);
return NULL;
}
/*
* Initialize emtexdir library; arguments are the full name of the
* executable (e.g. `c:\bin\ttf2pk.exe') and two identification strings;
* the former for the program itself, the latter for the environment.
* We ignore all of them.
*/
void
TeX_search_init(char *exec_name,
char *program_identifier,
char *env_identifier)
{
if (!dir_setup(&tfm_path, "TEXTFM", NULL, EDS_BANG))
oops("Cannot setup search path for tfm files");
if (!dir_setup(&enc_path, "TTFCFG", NULL, EDS_BANG))
oops("Cannot setup search path for encoding files");
#if 0
if (!dir_setup(&rpl_path, "TTFCFG", NULL, EDS_BANG))
oops("Cannot setup search path for replacement files");
if (!dir_setup(&sfd_path, "TTFCFG", NULL, EDS_BANG))
oops("Cannot setup search path for subfont definition files");
if (!dir_setup(&cfg_path, "TTFCFG", NULL, EDS_BANG))
oops("Cannot setup search path for configuration file");
#else
rpl_path = sfd_path = cfg_path = enc_path;
#endif
if (!dir_setup(&ttf_path, "TTFONTS", NULL, EDS_BANG))
oops("Cannot setup search path for TrueType font files");
}
char *
TeX_search_version(void)
{
return emtex_version_string;
}
char *
TeX_search_tfm(char **name)
{
handle_extension(name, ".tfm");
return file_find(*name, &tfm_path);
}
char *
TeX_search_encoding_file(char **name)
{
handle_extension(name, ".enc");
return file_find(*name, &enc_path);
}
char *
TeX_search_replacement_file(char **name)
{
handle_extension(name, ".rpl");
return file_find(*name, &rpl_path);
}
char *
TeX_search_sfd_file(char **name)
{
handle_extension(name, ".sfd");
return file_find(*name, &sfd_path);
}
char *
TeX_search_config_file(char **name)
{
/* no extra extension handling necessary */
return file_find(*name, &cfg_path);
}
char *
TeX_search_ttf_file(char **name)
{
size_t l;
char* real_name;
l = strlen(*name);
handle_extension(name, ".ttf");
real_name = file_find(*name, &ttf_path);
/* test for .ttc, but only if no extension was given initially */
if (!real_name && l != strlen(*name))
{
(*name)[strlen(*name) - 1] = 'c';
real_name = file_find(*name, &ttf_path);
}
return real_name;
}
/**************************
* MiKTeX library support *
**************************/
#elif defined(MIKTEX)
#include "miktex.h"
void
TeX_search_init(char *exec_name,
char *program_identifier,
char *env_identifier)
{
/* empty */
}
char *
TeX_search_version(void)
{
char buf[200];
strcpy(buf, "MiKTeX ");
miktex_get_miktex_version_string_ex(buf + 7, sizeof (buf) - 7);
return buf;
}
char *
TeX_search_tfm(char **name)
{
char result[_MAX_PATH];
if (!miktex_find_tfm_file(*name, result))
return 0;
return strdup(result);
}
char *
TeX_search_encoding_file(char **name)
{
char result[_MAX_PATH];
if (!miktex_find_enc_file(*name, result))
return 0;
return strdup(result);
}
char *
TeX_search_replacement_file(char **name)
{
char result[_MAX_PATH];
handle_extension(name, ".rpl");
if (!miktex_find_input_file("ttf2tfm", *name, result))
return 0;
return strdup(result);
}
char *
TeX_search_sfd_file(char **name)
{
char result[_MAX_PATH];
handle_extension(name, ".sfd");
if (!miktex_find_input_file("ttf2tfm", *name, result))
return 0;
return strdup(result);
}
char *
TeX_search_config_file(char **name)
{
char result[_MAX_PATH];
if (!miktex_find_input_file("ttf2tfm", *name, result))
return 0;
return strdup(result);
}
char *
TeX_search_ttf_file(char **name)
{
char result[_MAX_PATH];
if (!miktex_find_ttf_file(*name, result))
return 0;
return strdup(result);
}
/**********************
* no library support *
**********************/
#else
#include <stdio.h>
char version_string[] = "no search library";
void
TeX_search_init(char *exec_name,
char *program_identifier,
char *env_identifier)
{
/* empty */
}
char *
TeX_search_version(void)
{
return version_string;
}
char *
TeX_search_tfm(char **name)
{
handle_extension(name, ".tfm");
return *name;
}
char *
TeX_search_encoding_file(char **name)
{
handle_extension(name, ".enc");
return *name;
}
char *
TeX_search_replacement_file(char **name)
{
handle_extension(name, ".rpl");
return *name;
}
char *
TeX_search_sfd_file(char **name)
{
handle_extension(name, ".sfd");
return *name;
}
char *
TeX_search_config_file(char **name)
{
/* no extra extension handling necessary */
return *name;
}
/* we only handle .ttf extension */
char *
TeX_search_ttf_file(char **name)
{
handle_extension(name, ".ttf");
return *name;
}
#endif
void
get_tfm_fullname(Font *fnt)
{
size_t len = 0;
if (fnt->fullname)
free(fnt->fullname);
if (fnt->outname)
len += strlen(fnt->outname);
if (fnt->subfont_name)
len += strlen(fnt->subfont_name);
if (fnt->outname_postfix)
len += strlen(fnt->outname_postfix);
len++;
fnt->fullname = (char *)mymalloc(len);
fnt->fullname[0] = '\0';
if (fnt->outname)
strcat(fnt->fullname, fnt->outname);
if (fnt->subfont_name)
strcat(fnt->fullname, fnt->subfont_name);
if (fnt->outname_postfix)
strcat(fnt->fullname, fnt->outname_postfix);
}
/*
* This function takes the address of a pointer to a string allocated
* with malloc() and checks whether it has an extension. If not, a default
* extension given as a second argument will be appended using first
* realloc() and then strcat().
*
* '/', ':', and '\\' will be recognized as directory separators.
*/
void
handle_extension(char **stringp,
char *extension)
{
int i, lastext = -1;
for (i = 0; (*stringp)[i]; i++)
if ((*stringp)[i] == '.')
lastext = i;
else if ((*stringp)[i] == '/' ||
(*stringp)[i] == ':' ||
(*stringp)[i] == '\\')
lastext = -1;
if (lastext == -1)
{
*stringp = (char *)myrealloc((void *)*stringp,
strlen(*stringp) + strlen(extension) + 1);
strcat(*stringp, extension);
}
}
/* end */

51
contrib/ttf2pk/filesrch.h Normal file
View File

@@ -0,0 +1,51 @@
/*
* filesrch.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef FILESRCH_H
#define FILESRCH_H
#include "ttf2tfm.h"
/*
* Arguments are the full program name and two identification strings
* (for the program and the environment).
*/
void TeX_search_init(char *exec_name,
char *program_identifier,
char *env_identifier);
/*
* The next function returns a version string.
*/
char *TeX_search_version(void);
/*
* The following functions take a file name (either relative or absolute),
* probably append a default extension, and return the complete path to the
* file.
*/
char *TeX_search_tfm(char **name);
char *TeX_search_encoding_file(char **name);
char *TeX_search_replacement_file(char **name);
char *TeX_search_sfd_file(char **name);
char *TeX_search_config_file(char **name);
char *TeX_search_ttf_file(char **name);
void get_tfm_fullname(Font *fnt);
void handle_extension(char **stringp,
char *extension);
#endif /* FILESRCH_H */
/* end */

275
contrib/ttf2pk/ligkern.c Normal file
View File

@@ -0,0 +1,275 @@
/*
* ligkern.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <string.h>
#include <stdlib.h>
#include <stddef.h> /* for size_t */
#include <ctype.h>
#include "ttf2tfm.h"
#include "ligkern.h"
#include "ttfenc.h"
#include "texenc.h"
#include "newobj.h"
#include "errormsg.h"
static char *
paramstring(char **curp)
{
register char *p, *q;
p = *curp;
while (*p && !isspace(*p))
p++;
q = *curp;
if (*p != '\0')
*p++ = '\0';
while (isspace(*p))
p++;
*curp = p;
return q;
}
/*
* Some routines to remove kerns that match certain patterns.
*/
static kern *
rmkernmatch(kern *k,
char *s)
{
kern *nk;
while (k && strcmp(k->succ, s) == 0)
k = k->next;
if (k)
{
for (nk = k; nk; nk = nk->next)
while (nk->next && strcmp(nk->next->succ, s) == 0)
nk->next = nk->next->next;
}
return k;
}
/*
* Recursive to one level.
*/
static void
rmkern(char *s1, char *s2,
ttfinfo *ti,
Font *fnt)
{
if (ti == NULL)
{
if (strcmp(s1, "*") == 0)
{
for (ti = fnt->charlist; ti; ti = ti->next)
rmkern(s1, s2, ti, fnt);
return;
}
else
{
ti = findadobe(s1, fnt->charlist);
if (ti == NULL)
return;
}
}
if (strcmp(s2, "*") == 0)
ti->kerns = NULL; /* drop them on the floor */
else
ti->kerns = rmkernmatch(ti->kerns, s2);
}
/*
* Make the kerning for character S1 equivalent to that for S2.
* If either S1 or S2 do not exist, do nothing.
* If S1 already has kerning, do nothing.
*/
static void
addkern(char *s1, char *s2,
Font *fnt)
{
ttfinfo *ti1 = findadobe(s1, fnt->charlist);
ttfinfo *ti2 = findadobe(s2, fnt->charlist);
if (ti1 && ti2 && !ti1->kerns)
{
/* Put the new one at the head of the list, since order is immaterial. */
ttfptr *ap = (ttfptr *)mymalloc(sizeof (ttfptr));
ap->next = ti2->kern_equivs;
ap->ch = ti1;
ti2->kern_equivs = ap;
}
}
/*
* Reads a ligkern line, if this is one. Assumes the first character
* passed is `%'.
*/
void
checkligkern(char *s, Font *fnt)
{
char *mlist[5];
char *os;
char *orig_s, *pos;
size_t offset[5];
int n;
os = newstring(s);
orig_s = s;
s++;
while (isspace(*s))
s++;
if (strncmp(s, "LIGKERN", 7) == 0)
{
fnt->sawligkern = True;
s += 7;
while (isspace(*s))
s++;
pos = s;
while (*pos)
{
for (n = 0; n < 5;)
{
if (*pos == '\0')
break;
offset[n] = pos - orig_s;
mlist[n] = paramstring(&pos);
if (strcmp(mlist[n], ";") == 0)
break;
n++;
}
if (n > 4)
boops(os, pos - orig_s, "Too many parameters in lig kern data.");
if (n < 3)
boops(os, pos - orig_s, "Too few parameters in lig kern data.");
if (n == 3 && strcmp(mlist[1], "{}") == 0) /* rmkern command */
rmkern(mlist[0], mlist[2], (ttfinfo *)0, fnt);
else if (n == 3 && strcmp(mlist[1], "<>") == 0) /* addkern */
addkern(mlist[0], mlist[2], fnt);
else if (n == 3 && strcmp(mlist[0], "||") == 0 &&
strcmp(mlist[1], "=") == 0) /* bc command */
{
ttfinfo *ti = findadobe("||", fnt->charlist);
if (fnt->boundarychar != -1)
boops(os, offset[0], "Multiple boundary character commands?");
if (sscanf(mlist[2], "%d", &n) != 1)
boops(os, offset[2],
"Expected number assignment for boundary char.");
if (n < 0 || n > 0xFF)
boops(os, offset[2], "Boundary character number must be 0..0xFF.");
fnt->boundarychar = n;
if (ti == NULL)
oops("Internal error: boundary char.");
ti->outcode = n; /* prime the pump, so to speak, for lig/kerns */
}
else if (n == 4)
{
int op = -1;
ttfinfo *ti;
for (n = 0; encligops[n]; n++)
if (strcmp(mlist[2], encligops[n]) == 0)
{
op = n;
break;
}
if (op < 0)
boops(os, offset[2], "Bad ligature op specified.");
if (NULL != (ti = findadobe(mlist[0], fnt->charlist)))
{
lig *lig;
if (findadobe(mlist[2], fnt->charlist))
/* remove coincident kerns */
rmkern(mlist[0], mlist[1], ti, fnt);
if (strcmp(mlist[3], "||") == 0)
boops(os, offset[3], "You can't lig to the boundary character!");
if (!fnt->fixedpitch) /* fixed pitch fonts get *0* ligs */
{
for (lig = ti->ligs; lig; lig = lig->next)
if (strcmp(lig->succ, mlist[1]) == 0)
break; /* we'll re-use this structure */
if (lig == NULL)
{
lig = newlig();
lig->succ = newstring(mlist[1]);
lig->next = ti->ligs;
ti->ligs = lig;
}
lig->sub = newstring(mlist[3]);
lig->op = op;
if (strcmp(mlist[1], "||") == 0)
{
lig->boundleft = 1;
if (strcmp(mlist[0], "||") == 0)
boops(os, offset[0],
"You can't lig boundarychar boundarychar!");
}
else
lig->boundleft = 0;
}
}
}
else
boops(os, offset[0], "Bad form in LIGKERN command.");
}
}
free(os);
}
void
getligkerndefaults(Font *fnt)
{
int i;
char *buffer;
for (i = 0; staticligkern[i]; i++)
{
buffer = newstring(staticligkern[i]);
checkligkern(buffer, fnt);
free(buffer);
}
}
/* end */

23
contrib/ttf2pk/ligkern.h Normal file
View File

@@ -0,0 +1,23 @@
/*
* ligkern.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef LIGKERN_H
#define LIGKERN_H
#include "ttf2tfm.h"
void checkligkern(char *s, Font *fnt);
void getligkerndefaults(Font *fnt);
#endif /* LIGKERN_H */
/* end */

352
contrib/ttf2pk/newobj.c Normal file
View File

@@ -0,0 +1,352 @@
/*
* newobj.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <stdlib.h>
#include <stddef.h> /* for size_t */
#include <string.h>
#include "newobj.h"
#include "ttf2tfm.h"
#include "errormsg.h"
#include "texenc.h"
void *
mymalloc(size_t len)
{
void *p;
#ifdef SMALLMALLOC
if (len > 65500L)
oops("Cannot allocate more than 64kByte.");
#endif
if (len)
p = malloc(len);
else
p = malloc(1);
if (p == NULL)
oops("Out of memory.");
return p;
}
void *
myrealloc(void *oldp, size_t len)
{
void *p;
#ifdef SMALLMALLOC
if (len > 65500L)
oops("Cannot allocate more than 64kByte.");
#endif
if (len)
p = realloc(oldp, len);
else
p = realloc(oldp, 1);
if (p == NULL)
oops("Out of memory.");
return p;
}
/*
* This routine gets a line from a file, supporting continuation with
* '\' as the last character on the line.
*
* In case of error, NULL is returned. If EOF is reached a pointer to
* a null string is returned. The final newline will be retained.
*/
char *
get_line(FILE *f)
{
size_t linelen, len;
char *buffer;
int c;
linelen = 80;
len = 0;
buffer = (char *)mymalloc(linelen);
while (1)
{
c = fgetc(f);
buffer[len++] = c;
if (len == linelen - 1)
{
linelen += 80;
buffer = (char *)myrealloc(buffer, linelen);
}
again:
switch (c)
{
case '\\':
c = fgetc(f);
if (c == '\n')
{
len--;
break;
}
else
{
buffer[len++] = c;
goto again;
}
case '\n':
buffer[len] = '\0';
return buffer;
case EOF:
buffer[len - 1] = '\0';
if (feof(f))
return buffer;
else
return NULL;
default:
break;
}
}
}
/*
* getline() is a wrapper function for get_line(). It returns `False' in
* case of error and expects a pointer to a buffer to store the current
* line. Additionally, the final newline character is stripped.
*/
Boolean
getline(char **bufferp, FILE *f)
{
size_t l;
*bufferp = get_line(f);
if (!(*bufferp && **bufferp))
return 0;
l = strlen(*bufferp);
if (l > 0)
(*bufferp)[l - 1] = '\0';
return 1;
}
char *
newstring(char *s)
{
char *q;
if (s)
{
q = mymalloc(strlen(s) + 1);
(void)strcpy(q, s);
return q;
}
else
return NULL;
}
ttfinfo *
newchar(Font *fnt)
{
register ttfinfo *ti;
ti = (ttfinfo *)mymalloc(sizeof (ttfinfo));
ti->next = fnt->charlist;
ti->charcode = -1;
ti->glyphindex = -1;
ti->incode = -1;
ti->outcode = -1;
ti->adobename = NULL;
ti->width = -1;
ti->llx = -1;
ti->lly = -1;
ti->urx = -1;
ti->ury = -1;
ti->ligs = NULL;
ti->kerns = NULL;
ti->kern_equivs = NULL;
ti->pccs = NULL;
ti->constructed = False;
ti->wptr = 0;
ti->hptr = 0;
ti->dptr = 0;
ti->iptr = 0;
fnt->charlist = ti;
return ti;
}
kern *
newkern(void)
{
register kern *nk;
nk = (kern *)mymalloc(sizeof (kern));
nk->next = NULL;
nk->succ = NULL;
nk->delta = 0;
return nk;
}
pcc *
newpcc(void)
{
register pcc *np;
np = (pcc *)mymalloc(sizeof (pcc));
np->next = NULL;
np->partname = NULL;
np->xoffset = 0;
np->yoffset = 0;
return np;
}
lig *
newlig(void)
{
register lig *nl;
nl = (lig *)mymalloc(sizeof (lig));
nl->next = NULL;
nl->succ = NULL;
nl->sub = NULL;
nl->op = 0; /* the default =: op */
nl->boundleft = 0;
return nl;
}
stringlist *
newstringlist(void)
{
register stringlist *sl;
sl = (stringlist *)mymalloc(sizeof (stringlist));
sl->next = NULL;
sl->old_name = NULL;
sl->new_name = NULL;
sl->single_replacement = False;
return sl;
}
void
init_font_structure(Font *fnt)
{
int i;
fnt->ttfname = NULL;
fnt->tfm_path = NULL;
fnt->tfm_ext = NULL;
fnt->outname = NULL;
fnt->subfont_name = NULL;
fnt->outname_postfix = NULL;
fnt->fullname = NULL;
fnt->vplout = NULL;
fnt->tfmout = NULL;
fnt->inencname = NULL;
fnt->inencoding = NULL;
fnt->replacements = NULL;
fnt->replacementname = NULL;
fnt->outencname = NULL;
fnt->outencoding = NULL;
fnt->sfdname = NULL;
fnt->sawligkern = False;
fnt->subfont_ligs = False;
fnt->charlist = NULL;
fnt->boundarychar = -1;
fnt->codingscheme = default_codingscheme;
fnt->titlebuf = NULL;
fnt->units_per_em = 0;
fnt->italicangle = 0.0;
fnt->fixedpitch = 0;
fnt->fontindex = 0;
fnt->pid = 3;
fnt->eid = 1;
fnt->xheight = 400;
fnt->fontspace = 0;
fnt->y_offset = 0.25;
fnt->efactor = 1.0;
fnt->slant = 0;
fnt->capheight = 0.8;
fnt->PSnames = No;
fnt->rotate = No;
fnt->efactorparam = NULL;
fnt->slantparam = NULL;
fnt->fontindexparam = NULL;
fnt->pidparam = NULL;
fnt->eidparam = NULL;
fnt->y_offsetparam = NULL;
for (i = 0; i < 256; i++)
{
fnt->inencptrs[i] = NULL;
fnt->outencptrs[i] = NULL;
fnt->uppercase[i] = NULL;
fnt->lowercase[i] = NULL;
fnt->sf_code[i] = -1;
fnt->nextout[i] = -1; /* encoding chains have length 0 */
}
}
/* end */

43
contrib/ttf2pk/newobj.h Normal file
View File

@@ -0,0 +1,43 @@
/*
* newobj.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef NEWOBJ_H
#define NEWOBJ_H
#include <stdio.h>
#include "ttf2tfm.h"
#if (defined(MSDOS) && defined(__TURBOC__)) || \
(defined(OS2) && defined(_MSC_VER))
#define SMALLMALLOC
#endif
void *mymalloc(size_t len);
void *mycalloc(size_t len);
void *myrealloc(void *oldp, size_t len);
char *get_line(FILE *f);
Boolean getline(char **bufferp, FILE *f);
char *newstring(char *s);
ttfinfo *newchar(Font *fnt);
kern *newkern(void);
pcc *newpcc(void);
lig *newlig(void);
stringlist *newstringlist(void);
void init_font_structure(Font *fnt);
#endif /* NEWOBJ_H */
/* end */

304
contrib/ttf2pk/parse.c Normal file
View File

@@ -0,0 +1,304 @@
/*
* parse.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> /* for size_t */
#include <ctype.h>
#include <string.h>
#include "ttf2tfm.h"
#include "errormsg.h"
#include "newobj.h"
#include "ligkern.h"
#include "texenc.h"
#include "parse.h"
#include "filesrch.h"
/*
* Here we get a token from the encoding file. We parse just as much
* PostScript as we expect to find in an encoding file. We allow
* commented lines and names like 0, .notdef, _foo_. We do not allow
* //abc.
*
* `bufferp' is a pointer to the current line; the offset of the beginning
* of the token to be parsed relative to `bufferp' will be returned in
* `offsetp'. On the first call of gettoken() `init' must be set to 1 and
* to 0 on the following calls.
*
* If `ignoreligkern' is `True', no LIGKERN data will be extracted from the
* encoding file.
*
* Don't modify `bufferp'!
*
* The memory management of `bufferp' will be done by gettoken() itself;
* nevertheless, it returns a pointer to the current token which should be
* freed after it has been used.
*/
static char *
gettoken(char **bufferp, size_t *offsetp, FILE *f, Font *fnt,
Boolean ignoreligkern, Boolean init)
{
char *p, *q;
char tempchar;
static char *curp;
if (init)
curp = NULL;
while (1)
{
while (curp == NULL || *curp == '\0')
{
if (*bufferp)
free(*bufferp);
if (getline(bufferp, f) == False)
oops("Premature end in encoding file.");
curp = *bufferp;
for (p = *bufferp; *p; p++)
if (*p == '%')
{
if (ignoreligkern == False)
checkligkern(p, fnt);
*p = '\0';
break;
}
}
while (isspace(*curp))
curp++;
*offsetp = curp - *bufferp;
if (*curp)
{
if (*curp == '[' || *curp == ']' ||
*curp == '{' || *curp == '}')
q = curp++;
else if (*curp == '/' ||
*curp == '-' || *curp == '_' || *curp == '.' ||
('0' <= *curp && *curp <= '9') ||
('a' <= *curp && *curp <= 'z') ||
('A' <= *curp && *curp <= 'Z'))
{
q = curp++;
while (*curp == '-' || *curp == '_' || *curp == '.' ||
('0' <= *curp && *curp <= '9') ||
('a' <= *curp && *curp <= 'z') ||
('A' <= *curp && *curp <= 'Z'))
curp++;
}
else
q = curp;
tempchar = *curp;
*curp = '\0';
p = newstring(q);
*curp = tempchar;
return p;
}
}
}
/*
* This routine reads in an encoding file, given the name. It returns
* the final total structure. It performs a number of consistency checks.
*/
encoding *
readencoding(char **enc, Font *fnt, Boolean ignoreligkern)
{
char *real_encname;
FILE *enc_file;
char *p, *q, c;
char *buffer;
char numbuf[9];
size_t offset;
int i;
long l;
encoding *e = (encoding *)mymalloc(sizeof (encoding));
if (enc && *enc)
{
real_encname = TeX_search_encoding_file(enc);
if (!real_encname)
oops("Cannot find encoding file `%s'.", *enc);
enc_file = fopen(real_encname, "rt");
if (enc_file == NULL)
oops("Cannot open encoding file `%s'.", real_encname);
buffer = NULL;
p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, True);
if (*p != '/' || p[1] == '\0')
boops(buffer, offset,
"First token in encoding must be literal encoding name.");
e->name = newstring(p + 1);
free(p);
p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False);
if (strcmp(p, "["))
boops(buffer, offset,
"Second token in encoding must be mark ([) token.");
free(p);
for (i = 0; i < 256; i++)
{
p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False);
if (*p != '/' || p[1] == 0)
boops(buffer, offset,
"Tokens 3 to 257 in encoding must be literal names.");
/* now we test for a generic code point resp. glyph index value */
c = p[2];
if (p[1] == '.' && (c == 'c' || c == 'g') && '0' <= p[3] && p[3] <= '9')
{
l = strtol(p + 3, &q, 0);
if (*q != '\0' || l < 0 || l > 0xFFFF)
boops(buffer, offset, "Invalid encoding token.");
sprintf(numbuf, ".%c0x%x", c, (unsigned int)l);
e->vec[i] = newstring(numbuf);
}
else
e->vec[i] = newstring(p + 1);
free(p);
}
p = gettoken(&buffer, &offset, enc_file, fnt, ignoreligkern, False);
if (strcmp(p, "]"))
boops(buffer, offset,
"Token 258 in encoding must be make-array (]).");
free(p);
while (getline(&buffer, enc_file))
{
for (p = buffer; *p; p++)
if (*p == '%')
{
if (ignoreligkern == False)
checkligkern(p, fnt);
*p = '\0';
break;
}
}
fclose(enc_file);
if (ignoreligkern == False && fnt->sawligkern == False)
getligkerndefaults(fnt);
}
else
{
if (ignoreligkern == False)
{
e = &staticencoding;
getligkerndefaults(fnt);
}
else
e = NULL;
}
return e;
}
/*
* We scan a glyph replacement file.
* `%' is the comment character.
*/
void
get_replacements(Font *fnt)
{
char *real_replacement_name;
FILE *replacement_file;
char *buffer = NULL, *oldbuffer = NULL;
char *p;
char *old_name, *new_name;
stringlist *sl;
if (!fnt->replacementname)
return;
real_replacement_name = TeX_search_replacement_file(&fnt->replacementname);
if (!real_replacement_name)
oops("Cannot find replacement file `%s'.", fnt->replacementname);
replacement_file = fopen(real_replacement_name, "rt");
if (replacement_file == NULL)
oops("Cannot open replacement file `%s'.", real_replacement_name);
while (getline(&buffer, replacement_file))
{
for (p = buffer; *p; p++)
if (*p == '%')
{
*p = '\0';
break;
}
if (oldbuffer)
free(oldbuffer);
oldbuffer = newstring(buffer);
p = buffer;
while (isspace(*p))
p++;
if (!*p)
continue;
old_name = p;
while (*p && !isspace(*p))
p++;
if (*p)
*p++ = '\0';
while (*p && isspace(*p))
p++;
if (!*p)
boops(oldbuffer, old_name - oldbuffer, "Replacement glyph missing.");
new_name = p;
while (*p && !isspace(*p))
p++;
if (*p)
*p++ = '\0';
while (*p && isspace(*p))
p++;
if (*p)
boops(oldbuffer, p - oldbuffer, "Invalid replacement syntax.");
sl = newstringlist();
sl->new_name = newstring(new_name);
sl->old_name = newstring(old_name);
sl->next = fnt->replacements;
fnt->replacements = sl;
}
fclose(replacement_file);
}
/* end */

22
contrib/ttf2pk/parse.h Normal file
View File

@@ -0,0 +1,22 @@
/*
* parse.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef PARSE_H
#define PARSE_H
#include "ttf2tfm.h"
encoding *readencoding(char **enc, Font *fnt, Boolean ignoreligkern);
void get_replacements(Font *fnt);
#endif /* PARSE_H */
/* end */

872
contrib/ttf2pk/pklib.c Normal file
View File

@@ -0,0 +1,872 @@
/*
* pklib.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
/*
* This code has been derived from the program gsftopk.
* Here the original copyright.
*/
/*
* Copyright (c) 1994 Paul Vojta. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> /* for size_t */
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "newobj.h"
#include "pklib.h"
#include "errormsg.h"
#include "filesrch.h"
#ifndef MAXPATHLEN
#define MAXPATHLEN 256
#endif
#define PK_PRE (char)247
#define PK_ID 89
#define PK_POST (char)245
#define PK_NOP (char)246
int dpi;
FILE *pk_file;
/*
* Information from the .tfm file.
*/
int tfm_lengths[12];
#define lh tfm_lengths[1]
#define bc tfm_lengths[2]
#define ec tfm_lengths[3]
#define nw tfm_lengths[4]
long checksum;
long design;
byte width_index[256];
long tfm_widths[256];
/*
* Information on the bitmap currently being worked on.
*/
byte *bitmap;
int width;
int skip;
int height;
int hoff;
int voff;
int bytes_wide;
size_t bm_size;
byte *bitmap_end;
int pk_len;
/*
* Here's the path searching stuff. First the typedefs and variables.
*/
static char searchpath[MAXPATHLEN + 1];
#define HUNKSIZE (MAXPATHLEN + 2)
struct spacenode /* used for storage of directory names */
{
struct spacenode *next;
char *sp_end; /* end of data for this chunk */
char sp[HUNKSIZE];
} firstnode;
static FILE *
search_tfm(char **name)
{
char *p;
FILE *f;
p = TeX_search_tfm(name);
if (p == NULL)
return NULL;
strcpy(searchpath, p);
f = fopen(searchpath, "rb");
return f;
}
static long
getlong(FILE *f)
{
unsigned long value;
value = (unsigned long)getc(f) << 24;
value |= (unsigned long)getc(f) << 16;
value |= (unsigned long)getc(f) << 8;
value |= (unsigned long)getc(f);
return value;
}
char line[82];
static byte masks[] = {0, 1, 3, 7, 017, 037, 077, 0177, 0377};
byte flag;
int pk_dyn_f;
int pk_dyn_g;
int base; /* cost of this character if pk_dyn_f = 0 */
int deltas[13]; /* cost of increasing pk_dyn_f from i to i+1 */
/*
* Add up statistics for putting out the given shift count.
*/
static void
tallyup(int n)
{
int m;
if (n > 208)
{
++base;
n -= 192;
for (m = 0x100; m != 0 && m < n; m <<= 4)
base += 2;
if (m != 0 && (m = (m - n) / 15) < 13)
deltas[m] += 2;
}
else if (n > 13)
++deltas[(208 - n) / 15];
else
--deltas[n - 1];
}
/*
* Routines for storing the shift counts.
*/
static Boolean odd = False;
static byte part;
static void
pk_put_nyb(int n)
{
if (odd)
{
*bitmap_end++ = (part << 4) | n;
odd = False;
}
else
{
part = n;
odd = True;
}
}
static void
pk_put_long(int n)
{
if (n >= 16)
{
pk_put_nyb(0);
pk_put_long(n / 16);
}
pk_put_nyb(n % 16);
}
static void
pk_put_count(int n)
{
if (n > pk_dyn_f)
{
if (n > pk_dyn_g)
pk_put_long(n - pk_dyn_g + 15);
else
{
pk_put_nyb(pk_dyn_f + (n - pk_dyn_f + 15) / 16);
pk_put_nyb((n - pk_dyn_f - 1) % 16);
}
}
else
pk_put_nyb(n);
}
static void
trim_bitmap(void)
{
byte *p;
byte mask;
/* clear out garbage bits in bitmap */
if (width % 8 != 0)
{
mask = ~masks[8 - width % 8];
for (p = bitmap + bytes_wide - 1; p < bitmap_end; p += bytes_wide)
*p &= mask;
}
/* Find the bounding box of the bitmap. */
/* trim top */
skip = 0;
mask = 0;
for (;;)
{
if (bitmap >= bitmap_end) /* if bitmap is empty */
{
width = height = hoff = voff = 0;
return;
}
p = bitmap + bytes_wide;
while (p > bitmap)
mask |= *--p;
if (mask)
break;
++skip;
bitmap += bytes_wide;
}
height -= skip;
voff -= skip;
#ifdef DEBUG
if (skip < 2 || skip > 3)
printf("Character has %d empty rows at top\n", skip);
#endif
/* trim bottom */
skip = 0;
mask = 0;
for (;;)
{
p = bitmap_end - bytes_wide;
while (p < bitmap_end)
mask |= *p++;
if (mask)
break;
++skip;
bitmap_end -= bytes_wide;
}
height -= skip;
#ifdef DEBUG
if (skip < 2 || skip > 3)
printf("Character has %d empty rows at bottom\n", skip);
#endif
/* trim right */
skip = 0;
--width;
for (;;)
{
mask = 0;
for (p = bitmap + width / 8; p < bitmap_end; p += bytes_wide)
mask |= *p;
if (mask & (0x80 >> (width % 8)))
break;
--width;
++skip;
}
++width;
#ifdef DEBUG
if (skip < 2 || skip > 3)
printf("Character has %d empty columns at right\n", skip);
#endif
/* trim left */
skip = 0;
for (;;)
{
mask = 0;
for (p = bitmap + skip / 8; p < bitmap_end; p += bytes_wide)
mask |= *p;
if (mask & (0x80 >> (skip % 8)))
break;
++skip;
}
width -= skip;
hoff -= skip;
#ifdef DEBUG
if (skip < 2 || skip > 3)
printf("Character has %d empty columns at left\n", skip);
#endif
bitmap += skip / 8;
skip = skip % 8;
}
/*
* Pack the bitmap using the rll method. (Return false if it's better
* to just pack the bits.)
*/
static Boolean
pk_rll_cvt(void)
{
static int *counts = NULL; /* area for saving bit counts */
static int maxcounts = 0; /* size of this area */
unsigned int ncounts; /* max to allow this time */
int *nextcount; /* next count value */
int *counts_end; /* pointer to end */
byte *rowptr;
byte *p;
byte mask;
byte *rowdup; /* last row checked for dup */
byte paint_switch; /* 0 or 0xff */
int bits_left; /* bits left in row */
int cost;
int i;
/* Allocate space for bit counts. */
ncounts = (width * height + 3) / 4;
if (ncounts > maxcounts)
{
if (counts != NULL)
free(counts);
counts = (int *)mymalloc((ncounts + 2) * sizeof (int));
maxcounts = ncounts;
}
counts_end = counts + ncounts;
/* Form bit counts and collect statistics */
base = 0;
memset(deltas, 0, sizeof (deltas));
rowdup = NULL; /* last row checked for duplicates */
p = rowptr = bitmap;
mask = 0x80 >> skip;
flag = 0;
paint_switch = 0;
if (*p & mask)
{
flag = 8;
paint_switch = 0xff;
}
bits_left = width;
nextcount = counts;
while (rowptr < bitmap_end) /* loop over shift counts */
{
int shift_count = bits_left;
for (;;)
{
if (bits_left == 0)
{
if ((p = rowptr += bytes_wide) >= bitmap_end)
break;
mask = 0x80 >> skip;
bits_left = width;
shift_count += width;
}
if (((*p ^ paint_switch) & mask) != 0)
break;
--bits_left;
mask >>= 1;
if (mask == 0)
{
++p;
while (*p == paint_switch && bits_left >= 8)
{
++p;
bits_left -= 8;
}
mask = 0x80;
}
}
if (nextcount >= counts_end)
return False;
shift_count -= bits_left;
*nextcount++ = shift_count;
tallyup(shift_count);
/* check for duplicate rows */
if (rowptr != rowdup && bits_left != width)
{
byte *p1 = rowptr;
byte *q = rowptr + bytes_wide;
int repeat_count;
while (q < bitmap_end && *p1 == *q)
{
++p1;
++q;
}
repeat_count = (p1 - rowptr) / bytes_wide;
if (repeat_count > 0)
{
*nextcount++ = -repeat_count;
if (repeat_count == 1)
--base;
else
{
++base;
tallyup(repeat_count);
}
rowptr += repeat_count * bytes_wide;
}
rowdup = rowptr;
}
paint_switch = ~paint_switch;
}
#ifdef DEBUG
/*
* Dump the bitmap
*/
for (p = bitmap; p < bitmap_end; p += bytes_wide)
{
byte *p1 = p;
int j;
mask = 0x80 >> skip;
for (j = 0; j < width; ++j)
{
putchar(*p1 & mask ? '@' : '.');
if ((mask >>= 1) == 0)
{
mask = 0x80;
++p1;
}
}
putchar('\n');
}
putchar('\n');
#endif
/* Determine the best pk_dyn_f */
pk_dyn_f = 0;
cost = base += 2 * (nextcount - counts);
for (i = 1; i < 14; ++i)
{
base += deltas[i - 1];
if (base < cost)
{
pk_dyn_f = i;
cost = base;
}
}
/* last chance to bail out */
if (cost * 4 > width * height)
return False;
/* Pack the bit counts */
pk_dyn_g = 208 - 15 * pk_dyn_f;
flag |= pk_dyn_f << 4;
bitmap_end = bitmap;
*nextcount = 0;
nextcount = counts;
while (*nextcount != 0)
{
if (*nextcount > 0)
pk_put_count(*nextcount);
else
if (*nextcount == -1)
pk_put_nyb(15);
else
{
pk_put_nyb(14);
pk_put_count(-*nextcount);
}
++nextcount;
}
if (odd)
{
pk_put_nyb(0);
++cost;
}
if (cost != 2 * (bitmap_end - bitmap))
printf("Cost miscalculation: expected %d, got %ld\n",
cost, (long)(2 * (bitmap_end - bitmap)));
pk_len = bitmap_end - bitmap;
return True;
}
static void
pk_bm_cvt(void)
{
byte *rowptr;
byte *p;
int blib1; /* bits left in byte */
int bits_left; /* bits left in row */
byte *q;
int blib2;
byte nextbyte;
flag = 14 << 4;
q = bitmap;
blib2 = 8;
nextbyte = 0;
for (rowptr = bitmap; rowptr < bitmap_end; rowptr += bytes_wide)
{
p = rowptr;
blib1 = 8 - skip;
bits_left = width;
if (blib2 != 8)
{
int n;
if (blib1 < blib2)
{
nextbyte |= *p << (blib2 - blib1);
n = blib1;
}
else
{
nextbyte |= *p >> (blib1 - blib2);
n = blib2;
}
blib2 -= n;
if ((bits_left -= n) < 0)
{
blib2 -= bits_left;
continue;
}
if ((blib1 -= n) == 0)
{
blib1 = 8;
++p;
if (blib2 > 0)
{
nextbyte |= *p >> (8 - blib2);
blib1 -= blib2;
bits_left -= blib2;
if (bits_left < 0)
{
blib2 = -bits_left;
continue;
}
}
}
*q++ = nextbyte;
}
/* fill up whole (destination) bytes */
while (bits_left >= 8)
{
nextbyte = *p++ << (8 - blib1);
*q++ = nextbyte | (*p >> blib1);
bits_left -= 8;
}
/* now do the remainder */
nextbyte = *p << (8 - blib1);
if (bits_left > blib1)
nextbyte |= p[1] >> blib1;
blib2 = 8 - bits_left;
}
if (blib2 != 8)
*q++ = nextbyte;
pk_len = q - bitmap;
}
static void
putshort(short w)
{
putc(w >> 8, pk_file);
putc(w, pk_file);
}
static void
putmed(long w)
{
putc(w >> 16, pk_file);
putc(w >> 8, pk_file);
putc(w, pk_file);
}
static void
putlong(long w)
{
putc(w >> 24, pk_file);
putc(w >> 16, pk_file);
putc(w >> 8, pk_file);
putc(w, pk_file);
}
char
xgetc(FILE *f)
{
int c;
c = getc(f);
if (c == EOF)
oops("Premature end of file.");
return (byte)c;
}
/*
* Open and read the tfm file.
*/
void
TFMopen(char **filename)
{
FILE *tfm_file;
int i;
int cc;
tfm_file = search_tfm(filename);
if (tfm_file == NULL)
oops("Cannot find tfm file.");
for (i = 0; i < 12; i++)
{
int j;
j = (int)((byte)getc(tfm_file)) << 8;
tfm_lengths[i] = j | (int)((byte)xgetc(tfm_file));
}
checksum = getlong(tfm_file);
design = getlong(tfm_file);
fseek(tfm_file, 4 * (lh + 6), 0);
for (cc = bc; cc <= ec; ++cc)
{
width_index[cc] = (byte)xgetc(tfm_file);
(void)xgetc(tfm_file);
(void)xgetc(tfm_file);
(void)xgetc(tfm_file);
}
for (i = 0; i < nw; ++i)
tfm_widths[i] = getlong(tfm_file);
fclose(tfm_file);
}
/*
* Create pk file and write preamble.
*/
void
PKopen(char *filename,
char *ident,
int resolution)
{
int ppp;
int i;
dpi = resolution;
if ((pk_file = fopen(filename, "wb")) == NULL)
{
perror(filename);
exit(1);
}
putc(PK_PRE, pk_file);
putc(PK_ID, pk_file);
i = strlen(ident);
putc(i, pk_file);
fwrite(ident, 1, i, pk_file);
putlong(design);
putlong(checksum);
ppp = dpi / 72.27 * 65536.0 + 0.5;
putlong(ppp); /* hppp */
putlong(ppp); /* vppp */
}
void
PKputglyph(int cc,
int llx, int lly, int urx, int ury,
int w, int h,
byte *b)
{
float char_width;
long dm;
long tfm_wid;
bitmap = b;
width = w;
height = h;
hoff = -llx;
voff = ury - 2; /* Don't ask me why `-2' */
/* Fred */
if (width != urx - llx || height != ury - lly)
oops("Dimensions do not match: (%d - %d) (%d - %d) <=> %d %d",
llx, lly, urx, ury, width, height);
bytes_wide = (width + 7) / 8;
bm_size = bytes_wide * height;
bitmap_end = bitmap + bm_size;
trim_bitmap();
if (height == 0 || !pk_rll_cvt())
pk_bm_cvt();
if (!width_index[cc])
return;
tfm_wid = tfm_widths[width_index[cc]];
char_width = tfm_wid / 1048576.0 * design / 1048576.0 * dpi / 72.27;
dm = (long)(char_width + 0.5) - (char_width < -0.5);
if (pk_len + 8 < 4 * 256 && tfm_wid < (1<<24) &&
dm >= 0 && dm < 256 && width < 256 && height < 256 &&
hoff >= -128 && hoff < 128 && voff >= -128 && voff < 128)
{
putc(flag | ((pk_len + 8) >> 8), pk_file);
putc(pk_len + 8, pk_file);
putc(cc, pk_file);
putmed(tfm_wid);
putc(dm, pk_file);
putc(width, pk_file);
putc(height, pk_file);
putc(hoff, pk_file);
putc(voff, pk_file);
}
else if (pk_len + 13 < 3 * 65536L && tfm_wid < (1<<24) &&
dm >= 0 && dm < 65536L && width < 65536L && height < 65536L &&
hoff >= -65536L && hoff < 65536L &&
voff >= -65536L && voff < 65536L)
{
putc(flag | 4 | ((pk_len + 13) >> 16), pk_file);
putshort(pk_len + 13);
putc(cc, pk_file);
putmed(tfm_wid);
putshort(dm);
putshort(width);
putshort(height);
putshort(hoff);
putshort(voff);
}
else
{
putc(flag | 7, pk_file);
putlong(pk_len + 28);
putlong(cc);
putlong(tfm_wid);
putlong((long)(char_width * 65536.0 + 0.5) - (char_width < -0.5));
putlong(0);
putlong(width);
putlong(height);
putlong(hoff);
putlong(voff);
}
fwrite(bitmap, 1, pk_len, pk_file);
}
void
PKclose(void)
{
putc(PK_POST, pk_file);
while (ftell(pk_file) % 4 != 0)
putc(PK_NOP, pk_file);
fclose(pk_file);
}
/* end */

29
contrib/ttf2pk/pklib.h Normal file
View File

@@ -0,0 +1,29 @@
/*
* pklib.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef PKLIB_H
#define PKLIB_H
typedef unsigned char byte;
void TFMopen(char **filename);
void PKopen(char *filename, char *ident, int resolution);
void PKputglyph(int cc, int llx, int lly, int urx, int ury,
int w, int h, byte *b);
void PKclose(void);
#endif /* PKLIB_H */
/* end */

View File

@@ -0,0 +1,8 @@
In these subdirectories you can find diff files for various TeX
implementations which add support for on-the-fly pk-generation using ttf2pk
and hbf2gf (which is part of the CJK package for LaTeX 2e).
In case you don't have/want hbf2gf, simply comment out the relevant if-Block
in the script.
For web2c 7.3 resp. teTeX 1.0 or newer, no patches are needed.

View File

@@ -0,0 +1,63 @@
--- /root/scripts/teTeX-0.4/MakeTeXPK Sun Feb 23 22:12:05 1997
+++ /home/ft/freetype/contrib/ttf2pk/scripts/teTeX-0.4/MakeTeXPK Sat Sep 5 07:57:34 1998
@@ -80,6 +80,9 @@
: ${MAKETEXDIR=$TEXMF/maketex}
export TEXMF MAKETEXDIR
+unset cmd
+unset psline
+
# grep for the font in $PSMAPFILE, if some ps-to-pk is claimed to be supported.
# We have to figure out the name of the base font -- $NAME is probably
# something like pplr, but it's rpplr or pplr0 or pplr8r that's in psfonts.map.
@@ -91,7 +94,40 @@
# some installations have set up gs in such a way that creating files
# is only allowed if the parameter -DNOSAFER is used:
GS_OPTIONS=-DNOSAFER; export GS_OPTIONS
-else
+fi
+
+# test for TTF fonts
+if test -z "$cmd"; then
+ ttf2pk -q $NAME $DPI
+ errstatus=$?
+
+ if test $errstatus -ne 2; then
+ if test $errstatus -ne 0; then
+ echo "ttf2pk failed" >&2
+ exit 1
+ fi
+ MODE=ttf2pk # preferred mode for TDS would be `modeless'
+ cmd=true
+ psline=ttf2pk # suppress gftopk call
+ fi
+fi
+
+# test for HBF fonts
+if test -z "$cmd"; then
+ hbf2gf -q -p $NAME $DPI
+ errstatus=$?
+
+ if test $errstatus -ne 2; then
+ if test $errstatus -ne 0; then
+ echo "hbf2gf failed" >&2
+ exit 1
+ fi
+ MODE=hbf2gf # preferred mode for TDS would be `modeless'
+ cmd=true
+ fi
+fi
+
+if test -z "$cmd"; then
# If an explicit mode is not supplied, try to guess. You can get a
# list of extant modes from ftp.cs.umb.edu:pub/tex/modes.mf.
if test -z "$MODE" || test "$MODE" = default; then
@@ -141,7 +177,7 @@
{ echo "$progname: could not mkdir $PKDESTDIR."; exit 1; }'
eval "$mdir"
-echo "$progname: Running $cmd"
+test "$cmd" = true || echo "$progname: Running $cmd"
$cmd </dev/null || { echo "$progname: \`$cmd' failed." >&2; exit 1; }
if test -z "$psline"; then
test -r $GFNAME ||

View File

@@ -0,0 +1,75 @@
--- MakeTeXPK.orig Sun Aug 16 08:05:07 1998
+++ MakeTeXPK Tue Aug 18 07:53:57 1998
@@ -1,5 +1,5 @@
#!/bin/sh
-# original MakeTeXPK -- make a new PK font, because one wasn't found.
+# MakeTeXPK -- make a new PK font, because one wasn't found.
# Version of 12dec94.
#
# (If you change or delete the word `original' on the previous line,
@@ -142,11 +142,52 @@
test -d $TEMPDIR || mkdir $TEMPDIR
cd $TEMPDIR || exit 1
+unset cmd
+
+# test for TTF fonts
+if test -z "$cmd"; then
+ ttf2pk -q $NAME $DPI
+ errstatus=$?
+
+ if test $errstatus -ne 2; then
+ if test $errstatus -ne 0; then
+ echo "ttf2pk failed" >&2
+ exit 1
+ fi
+ test -z "$6" && DESTDIR="$DESTROOT/ttf2pk" # preferred mode for TDS
+ # would be `modeless'
+ echo "Successful call to ttf2pk" >&2
+ cmd=ttf2pk
+ fi
+fi
+
+# test for HBF fonts
+if test -z "$cmd"; then
+ hbf2gf -q -p $NAME $DPI
+ errstatus=$?
+
+ if test $errstatus -ne 2; then
+ if test $errstatus -ne 0; then
+ echo "hbf2gf failed" >&2
+ exit 1
+ fi
+ test -z "$6" && DESTDIR="$DESTROOT/hbf2gf" # preferred mode for TDS
+ # would be `modeless'
+ echo "Successful call to hbf2gf" >&2
+ cmd=hbf2gf
+
+ gftopk ./$GFNAME $PKNAME || exit 1
+ fi
+fi
+
# grep for the font in $PSMAPFILE, if some ps-to-pk is claimed to be supported.
# We have to figure out the name of the base font -- $NAME is probably
# something like pplr, but it's rpplr or pplr0 or pplr8r that's in psfonts.map.
-pattern="^r?$NAME"'(0|8r)?([ ]|$)'
-test -n "$ps_to_pk" && egrep "$pattern" $PSMAPFILE >psline
+if test -z "$cmd"; then
+ pattern="^r?$NAME"'(0|8r)?([ ]|$)'
+ test -n "$ps_to_pk" && egrep "$pattern" $PSMAPFILE > psline
+fi
+
if test -s psline; then
# This is a PostScript font.
MODE=$ps_to_pk
@@ -173,8 +214,9 @@
export DVIPSHEADERS
echo "$0: Running $cmd" >&2
$cmd >&2 || { echo "$0: $ps_to_pk failed." >&2; exit 1; }
+fi
-else
+if test -z "$cmd"; then
# Try Metafont.
MFINPUTS="$MFINPUTS:$SAVEPWD"
export MFINPUTS

View File

@@ -0,0 +1 @@
This is for web2c-6.1 with the patch for kpathsea 2.6

View File

@@ -0,0 +1,67 @@
--- MakeTeXPK.orig Sat Feb 8 15:52:00 1997
+++ MakeTeXPK Tue Aug 18 07:58:22 1998
@@ -1,5 +1,5 @@
#!/bin/sh
-# original MakeTeXPK -- make a new PK font, because one wasn't found.
+# MakeTeXPK -- make a new PK font, because one wasn't found.
#
# (If you change or delete the word `original' on the previous line,
# installation won't write this script over yours.)
@@ -44,15 +44,54 @@
MODE=$5
DEST=$6
+unset cmd
+
+# test for TTF fonts
+if test -z "$cmd"; then
+ ttf2pk -q $NAME $DPI
+ errstatus=$?
+
+ if test $errstatus -ne 2; then
+ if test $errstatus -ne 0; then
+ echo "ttf2pk failed" >&2
+ exit 1
+ fi
+ MODE=modeless
+ cmd=true
+ fi
+fi
+
+# test for HBF fonts
+if test -z "$cmd"; then
+ hbf2gf -q -p $NAME $DPI
+ errstatus=$?
+
+ if test $errstatus -ne 2; then
+ if test $errstatus -ne 0; then
+ echo "hbf2gf failed" >&2
+ exit 1
+ fi
+ MODE=modeless
+ cmd=true
+ fi
+fi
+
+unset psline
+
# grep for the font in $PSMAPFILE. These are base font names, such as
# rpplr (the original) or pplr0 (an interim step) or pplr8r (current).
-pattern="^r?$NAME"'(0|8r)?([ ]|$)'
-psline=`egrep "$pattern" $PSMAPFILE`
+if test -z "$cmd"; then
+ pattern="^r?$NAME"'(0|8r)?([ ]|$)'
+ psline=`egrep "$pattern" $PSMAPFILE`
+fi
+
if test -n "$psline"; then
MODE=modeless
# ps_to_pk set in MakeTeXcommon and/or MakeTeX.site.
cmd="$ps_to_pk $NAME $DPI"
-else
+fi
+
+if test -z "$cmd"; then
# Check that $BDPI and $MODE are consistent; if not, ignore the mode and
# hope we can correctly guess it from bdpi. (People like to specify the
# resolution on the command line, not the mode so much.)

View File

@@ -0,0 +1,72 @@
--- MakeTeXPK.orig Fri Oct 31 09:30:54 1997
+++ MakeTeXPK Tue Aug 18 08:01:33 1998
@@ -1,5 +1,5 @@
#!/bin/sh
-# original MakeTeXPK -- make a new PK font, because one wasn't found.
+# MakeTeXPK -- make a new PK font, because one wasn't found.
#
# (If you change or delete the word `original' on the previous line,
# installation won't write this script over yours.)
@@ -57,11 +57,48 @@
MODE=$5
DEST=$6
+unset cmd
+
+# test for TTF fonts
+if test -z "$cmd"; then
+ ttf2pk -q $NAME $DPI
+ errstatus=$?
+
+ if test $errstatus -ne 2; then
+ if test $errstatus -ne 0; then
+ echo "ttf2pk failed" >&2
+ exit 1
+ fi
+ MODE=modeless
+ cmd=true
+ fi
+fi
+
+# test for HBF fonts
+if test -z "$cmd"; then
+ hbf2gf -q -p $NAME $DPI
+ errstatus=$?
+
+ if test $errstatus -ne 2; then
+ if test $errstatus -ne 0; then
+ echo "hbf2gf failed" >&2
+ exit 1
+ fi
+ MODE=modeless
+ cmd=true
+ fi
+fi
+
+unset psline
+
# grep for the font in $PSMAPFILE. These are base font names, such as
# rpplr (the original) or pplr0 (an interim step) or pplr8r (current).
-: ${PSMAPFILE=`kpsewhich psfonts.map`}
-pattern="^$NAME"'([ ]|$)'
-psline=`egrep "$pattern" $PSMAPFILE`
+if test -z "$cmd"; then
+ : ${PSMAPFILE=`kpsewhich psfonts.map`}
+ pattern="^$NAME"'([ ]|$)'
+ psline=`egrep "$pattern" $PSMAPFILE`
+fi
+
if test -n "$psline"; then
MODE=modeless
# ps_to_pk is set in MakeTeX.cnf
@@ -100,7 +137,9 @@
cmd="$ps_to_pk $NAME $DPI"
;;
esac
-else
+fi
+
+if test -z "$cmd"; then
# Check that $BDPI and $MODE are consistent; if not, ignore the mode and
# hope we can correctly guess it from bdpi. (People like to specify the
# resolution on the command line, not the mode so much.)

View File

@@ -0,0 +1 @@
The patch works with web2c-7.0 too (expect a fuzz offset).

View File

@@ -0,0 +1,72 @@
--- mktexpk.orig Fri Feb 20 16:23:22 1998
+++ mktexpk Tue Aug 18 08:04:40 1998
@@ -1,5 +1,5 @@
#!/bin/sh
-# original mktexpk -- make a new PK font, because one wasn't found.
+# mktexpk -- make a new PK font, because one wasn't found.
#
# (If you change or delete the word `original' on the previous line,
# installation won't write this script over yours.)
@@ -73,11 +73,48 @@
NAME=$1
+unset cmd
+
+# test for TTF fonts
+if test -z "$cmd"; then
+ ttf2pk -q $NAME $DPI
+ errstatus=$?
+
+ if test $errstatus -ne 2; then
+ if test $errstatus -ne 0; then
+ echo "ttf2pk failed" >&2
+ exit 1
+ fi
+ MODE=modeless
+ cmd=true
+ fi
+fi
+
+# test for HBF fonts
+if test -z "$cmd"; then
+ hbf2gf -q -p $NAME $DPI
+ errstatus=$?
+
+ if test $errstatus -ne 2; then
+ if test $errstatus -ne 0; then
+ echo "hbf2gf failed" >&2
+ exit 1
+ fi
+ MODE=modeless
+ cmd=true
+ fi
+fi
+
+unset psline
+
# grep for the font in $PSMAPFILE. These are base font names, such as
# rpplr (the original) or pplr0 (an interim step) or pplr8r (current).
-: ${PSMAPFILE=`kpsewhich psfonts.map`}
-pattern="^$NAME"'([ ]|$)'
-psline=`egrep "$pattern" $PSMAPFILE`
+if test -z "$cmd"; then
+ : ${PSMAPFILE=`kpsewhich psfonts.map`}
+ pattern="^$NAME"'([ ]|$)'
+ psline=`egrep "$pattern" $PSMAPFILE`
+fi
+
if test -n "$psline"; then
MODE=modeless
# ps_to_pk is set in mktex.opt
@@ -116,7 +153,9 @@
cmd="$ps_to_pk $NAME $DPI"
;;
esac
-else
+fi
+
+if test -z "$cmd"; then
# Check that $BDPI and $MODE are consistent; if not, ignore the mode and
# hope we can correctly guess it from bdpi. (People like to specify the
# resolution on the command line, not the mode so much.)

264
contrib/ttf2pk/subfont.c Normal file
View File

@@ -0,0 +1,264 @@
/*
* subfont.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> /* for size_t */
#include <ctype.h>
#include <string.h>
#include "filesrch.h"
#include "subfont.h"
#include "newobj.h"
#include "errormsg.h"
static char *real_sfd_name;
static FILE *sfd;
/*
* Initialize subfont functionality. The argument is the subfont
* definition file name. If `fatal' is `True', the routine exits
* with an error. If `fatal' is `False', a warning message is emitted
* and `False' returned if an error occurs; in case of success `True'
* will be returned.
*/
Boolean
init_sfd(Font *fnt, Boolean fatal)
{
real_sfd_name = TeX_search_sfd_file(&(fnt->sfdname));
if (!real_sfd_name)
{
if (fatal)
oops("Cannot find subfont definition file `%s'.", fnt->sfdname);
else
{
warning("Cannot find subfont definition file `%s'.", fnt->sfdname);
return False;
}
}
sfd = fopen(real_sfd_name, "rt");
if (sfd == NULL)
{
if (fatal)
oops("Cannot open subfont definition file `%s'.", fnt->sfdname);
else
{
warning("Cannot open subfont definition file `%s'.", fnt->sfdname);
return False;
}
}
return True;
}
/*
* This function fills the font structure sequentially with subfont
* entries; it returns `False' if no more subfont entries are available,
* `True' otherwise.
*
* fnt->subfont_name must be set to NULL before the first call.
*
* The subset parser was inspired by ttf2bdf.c .
*/
Boolean
get_sfd(Font *fnt)
{
long i, offset;
long begin, end = -1;
char *buffer, *oldbuffer, *bufp, *bufp2, *bufp3;
for (i = 0; i < 256; i++)
fnt->sf_code[i] = -1;
again:
buffer = get_line(sfd);
if (!buffer)
oops("Error reading subfont definition file `%s'.", real_sfd_name);
if (!*buffer)
return False;
oldbuffer = newstring(buffer);
bufp = buffer;
offset = 0;
while (*bufp) /* remove comment */
{
if (*bufp == '#')
{
bufp++;
break;
}
bufp++;
}
*(--bufp) = '\0'; /* remove final newline character */
bufp = buffer;
while (isspace(*bufp))
bufp++;
if (*bufp == '\0') /* empty line? */
{
free(buffer);
free(oldbuffer);
goto again;
}
while (*bufp && !isspace(*bufp)) /* subfont name */
bufp++;
*(bufp++) = '\0';
while (isspace(*bufp))
bufp++;
if (*bufp == '\0')
oops("Invalid subfont entry in `%s'.", real_sfd_name);
if (fnt->subfont_name)
free(fnt->subfont_name);
fnt->subfont_name = newstring(buffer);
while (1)
{
bufp3 = bufp;
begin = strtol(bufp, &bufp2, 0);
if (bufp == bufp2 || begin < 0 || begin > 0xFFFF)
boops(oldbuffer, bufp - buffer,
"Invalid subfont range or offset entry.");
if (*bufp2 == ':') /* offset */
{
offset = begin;
if (offset > 0xFF)
boops(oldbuffer, bufp - buffer, "Invalid subfont offset.");
bufp = bufp2 + 1;
while (isspace(*bufp))
bufp++;
continue;
}
else if (*bufp2 == '_') /* range */
{
bufp = bufp2 + 1;
if (!isdigit(*bufp))
boops(oldbuffer, bufp - buffer, "Invalid subfont range entry.");
end = strtol(bufp, &bufp2, 0);
if (bufp == bufp2 || end < 0 || end > 0xFFFFL)
boops(oldbuffer, bufp - buffer, "Invalid subfont range entry.");
if (*bufp2 && !isspace(*bufp2))
boops(oldbuffer, bufp2 - buffer, "Invalid subfont range entry.");
if (end < begin)
boops(oldbuffer, bufp - buffer, "End of subfont range too small.");
if (offset + (end - begin) > 255)
boops(oldbuffer, bufp3 - buffer,
"Subfont range too large for current offset (%i).", offset);
}
else if (isspace(*bufp2) || !*bufp2) /* single value */
end = begin;
else
boops(oldbuffer, bufp2 - buffer, "Invalid subfont range entry.");
for (i = begin; i <= end; i++)
{
if (fnt->sf_code[offset] != -1)
boops(oldbuffer, bufp3 - buffer, "Overlapping subfont ranges.");
fnt->sf_code[offset++] = i;
}
bufp = bufp2;
while (isspace(*bufp))
bufp++;
if (!*bufp)
break;
}
free(buffer);
free(oldbuffer);
return True;
}
void
close_sfd(void)
{
if (sfd)
fclose(sfd);
}
/*
* We extract the subfont definition file name. The name must
* be embedded between two `@' characters. If there is no sfd file,
* `sfd_begin' is set to -1.
*
* The `@' characters will be replaced with null characters.
*/
void
handle_sfd(char *s, int *sfd_begin, int *postfix_begin)
{
size_t len;
int i;
Boolean have_atsign;
have_atsign = False;
len = strlen(s);
*sfd_begin = -1;
*postfix_begin = -1;
for (i = 0; s[i]; i++)
{
if (s[i] == '@')
{
if (have_atsign)
{
*postfix_begin = i + 1;
s[i] = '\0';
break;
}
have_atsign = True;
*sfd_begin = i + 1;
s[i] = '\0';
}
}
if (*sfd_begin != -1 &&
(*postfix_begin == -1 || *postfix_begin < *sfd_begin + 2))
oops("Invalid subfont definition file name.");
if (*postfix_begin > -1)
for (i = *postfix_begin; s[i]; i++)
if (s[i] == '/' || s[i] == ':' || s[i] == '\\' || s[i] == '@')
oops("`/', `:', `\\', and `@' not allowed after second `@'.");
}
/* end */

26
contrib/ttf2pk/subfont.h Normal file
View File

@@ -0,0 +1,26 @@
/*
* subfont.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef SUBFONT_H
#define SUBFONT_H
#include "ttf2tfm.h"
Boolean init_sfd(Font *fnt, Boolean fatal);
Boolean get_sfd(Font *fnt);
void close_sfd(void);
void handle_sfd(char *s, int *sfd_begin, int *postfix_begin);
#endif /* SUBFONT_H */
/* end */

203
contrib/ttf2pk/texenc.c Normal file
View File

@@ -0,0 +1,203 @@
/*
* texenc.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <stdlib.h> /* for definition of NULL */
#include "ttf2tfm.h"
#include "texenc.h"
encoding staticencoding =
{
"TeX text",
{"Gamma", "Delta", "Theta", "Lambda",
"Xi", "Pi", "Sigma", "Upsilon",
"Phi", "Psi", "Omega", "arrowup",
"arrowdown", "quotesingle", "exclamdown", "questiondown",
"dotlessi", "dotlessj", "grave", "acute",
"caron", "breve", "macron", "ring",
"cedilla", "germandbls", "ae", "oe",
"oslash", "AE", "OE", "Oslash",
"space", "exclam", "quotedbl", "numbersign",
"dollar", "percent", "ampersand", "quoteright",
"parenleft", "parenright", "asterisk", "plus",
"comma", "hyphen", "period", "slash",
"zero", "one", "two", "three",
"four", "five", "six", "seven",
"eight", "nine", "colon", "semicolon",
"less", "equal", "greater", "question",
"at", "A", "B", "C",
"D", "E", "F", "G",
"H", "I", "J", "K",
"L", "M", "N", "O",
"P", "Q", "R", "S",
"T", "U", "V", "W",
"X", "Y", "Z", "bracketleft",
"backslash", "bracketright", "circumflex", "underscore",
"quoteleft", "a", "b", "c",
"d", "e", "f", "g",
"h", "i", "j", "k",
"l", "m", "n", "o",
"p", "q", "r", "s",
"t", "u", "v", "w",
"x", "y", "z", "braceleft",
"bar", "braceright", "tilde", "dieresis",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
".notdef", ".notdef", ".notdef", ".notdef",
}
};
/*
* It's easier to put this in static storage and parse it as we go
* than to build the structures ourselves.
*
* The semicolons in the LIGKERN lines must be left isolated.
*/
char *staticligkern[] =
{
"% LIGKERN space l =: lslash ; space L =: Lslash ;",
"% LIGKERN question quoteleft =: questiondown ;",
"% LIGKERN exclam quoteleft =: exclamdown ;",
"% LIGKERN hyphen hyphen =: endash ; endash hyphen =: emdash ;",
"% LIGKERN quoteleft quoteleft =: quotedblleft ;",
"% LIGKERN quoteright quoteright =: quotedblright ;",
"% LIGKERN space {} * ; * {} space ; zero {} * ; * {} zero ;",
"% LIGKERN one {} * ; * {} one ; two {} * ; * {} two ;",
"% LIGKERN three {} * ; * {} three ; four {} * ; * {} four ;",
"% LIGKERN five {} * ; * {} five ; six {} * ; * {} six ;",
"% LIGKERN seven {} * ; * {} seven ; eight {} * ; * {} eight ;",
"% LIGKERN nine {} * ; * {} nine ;",
/*
* Kern accented characters the same way as their base.
*/
"% LIGKERN Aacute <> A ; aacute <> a ;",
"% LIGKERN Acircumflex <> A ; acircumflex <> a ;",
"% LIGKERN Adieresis <> A ; adieresis <> a ;",
"% LIGKERN Agrave <> A ; agrave <> a ;",
"% LIGKERN Aring <> A ; aring <> a ;",
"% LIGKERN Atilde <> A ; atilde <> a ;",
"% LIGKERN Ccedilla <> C ; ccedilla <> c ;",
"% LIGKERN Eacute <> E ; eacute <> e ;",
"% LIGKERN Ecircumflex <> E ; ecircumflex <> e ;",
"% LIGKERN Edieresis <> E ; edieresis <> e ;",
"% LIGKERN Egrave <> E ; egrave <> e ;",
"% LIGKERN Iacute <> I ; iacute <> i ;",
"% LIGKERN Icircumflex <> I ; icircumflex <> i ;",
"% LIGKERN Idieresis <> I ; idieresis <> i ;",
"% LIGKERN Igrave <> I ; igrave <> i ;",
"% LIGKERN Ntilde <> N ; ntilde <> n ;",
"% LIGKERN Oacute <> O ; oacute <> o ;",
"% LIGKERN Ocircumflex <> O ; ocircumflex <> o ;",
"% LIGKERN Odieresis <> O ; odieresis <> o ;",
"% LIGKERN Ograve <> O ; ograve <> o ;",
"% LIGKERN Oslash <> O ; oslash <> o ;",
"% LIGKERN Otilde <> O ; otilde <> o ;",
"% LIGKERN Scaron <> S ; scaron <> s ;",
"% LIGKERN Uacute <> U ; uacute <> u ;",
"% LIGKERN Ucircumflex <> U ; ucircumflex <> u ;",
"% LIGKERN Udieresis <> U ; udieresis <> u ;",
"% LIGKERN Ugrave <> U ; ugrave <> u ;",
"% LIGKERN Yacute <> Y ; yacute <> y ;",
"% LIGKERN Ydieresis <> Y ; ydieresis <> y ;",
"% LIGKERN Zcaron <> Z ; zcaron <> z ;",
/* lig commands for default ligatures */
"% LIGKERN f i =: fi ; f l =: fl ; f f =: ff ; ff i =: ffi ;",
"% LIGKERN ff l =: ffl ;",
NULL
};
/*
* The above layout corresponds to TeX Typewriter Type and is compatible
* with TeX Text because the position of ligatures is immaterial.
*/
/*
* These are the eight ligature ops, in VPL terms and in METAFONT terms.
*/
char *vplligops[] =
{
"LIG", "/LIG", "/LIG>", "LIG/", "LIG/>", "/LIG/", "/LIG/>", "/LIG/>>", 0
};
char *encligops[] =
{
"=:", "|=:", "|=:>", "=:|", "=:|>", "|=:|", "|=:|>", "|=:|>>", 0
};
/*
* For TeX we want to compute a character height that works properly
* with accents. The following list of accents doesn't need to be
* complete.
*/
/*
* We only do this if the xheight has a reasonable value (>50).
*/
char *accents[] = {"acute", "tilde", "caron", "dieresis", NULL};
char default_codingscheme[] = "Unspecified";
/* end */

28
contrib/ttf2pk/texenc.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* texenc.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef TEXENC_H
#define TEXENC_H
#include "ttf2tfm.h"
extern encoding staticencoding;
extern char *staticligkern[];
extern char *vplligops[];
extern char *encligops[];
extern char *accents[];
extern char default_codingscheme[];
#endif /* TEXENC_H */
/* end */

579
contrib/ttf2pk/tfmaux.c Normal file
View File

@@ -0,0 +1,579 @@
/*
* tfmaux.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "ttf2tfm.h"
#include "newobj.h"
#include "tfmaux.h"
#include "errormsg.h"
#undef PI
#define PI 3.14159265358979323846264338327
struct sf /* we need this for subfont ligatures */
{
long sf_code;
int position;
};
static long nextd; /* smallest value that will give a different mincover */
static int lf, lh, nw, nh, nd, ni, nl, nk, ne, np;
static int bc, ec;
static long *header, *charinfo,
*width, *height, *depth,
*ligkern, *kerns, *tparam,
*italic;
static int source[257]; /* utility variables for sorting tfm arrays */
static int unsort[257];
/*
* A simple function for sorting sf_array (in inverse order)
*/
static int
compare_sf(const void *a, const void *b)
{
return (int)(((struct sf *)b)->sf_code - ((struct sf *)a)->sf_code);
}
/*
* The next routine simply scales something.
* Input is in TFM units per em. Output is in FIXFACTORths of units
* per em. We use 1 em = 1000 TFM units.
*/
static long
scale(long what)
{
return ((what / 1000) * FIXFACTOR) +
(((what % 1000) * FIXFACTOR) + 500) / 1000;
}
/*
* Next we need a routine to reduce the number of distinct dimensions
* in a TFM file. Given an array what[0]..what[oldn-1], we want to
* group its elements into newn clusters, in such a way that the maximum
* difference between elements of a cluster is as small as possible.
* Furthermore, what[0]=0, and this value must remain in a cluster by
* itself. Data such as `0 4 6 7 9' with newn=3 shows that an iterative
* scheme in which 6 is first clustered with 7 will not work. So we
* borrow a neat algorithm from METAFONT to find the true optimum.
* Memory location what[oldn] is set to 0x7FFFFFFFL for convenience.
*/
/*
* Tells how many clusters result, given max difference d.
*/
static int
mincover(long *what,
register long d)
{
register int m;
register long l;
register long *p;
nextd = 0x7FFFFFFFL;
p = what+1;
m = 1;
while (*p < 0x7FFFFFFFL)
{
m++;
l = *p;
while (*++p <= l + d)
;
if (*p - l < nextd)
nextd = *p - l;
}
return m;
}
static void
remap(long *what,
int oldn,
int newn,
int *source,
int *unsort)
{
register int i, j;
register long d, l;
what[oldn] = 0x7FFFFFFFL;
for (i = oldn-1; i > 0; i--)
{
d = what[i];
for (j = i; what[j+1] < d; j++)
{
what[j] = what[j+1];
source[j] = source[j+1];
}
what[j] = d;
source[j] = i;
}
i = mincover(what, 0L);
d = nextd;
while (mincover(what, d + d) > newn)
d += d;
while (mincover(what, d) > newn)
d = nextd;
i = 1;
j = 0;
while (i < oldn)
{
j++;
l = what[i];
unsort[source[i]] = j;
while (what[++i] <= l + d)
{
unsort[source[i]] = j;
if (i - j == oldn - newn)
d = 0;
}
what[j] = (l + what[i-1])/2;
}
}
void
write16(register short what,
register FILE *out)
{
(void)fputc(what >> 8, out);
(void)fputc(what & 0xFF, out);
}
void
writearr(register long *p,
register int n,
register FILE *out)
{
while (n)
{
write16((short)(*p >> 16), out);
write16((short)(*p & 65535), out);
p++;
n--;
}
}
void
writesarr(long *what,
int len,
FILE *out)
{
register long *p;
int i;
p = what;
i = len;
while (i)
{
*p = scale(*p);
(void)scale(*p); /* need this kludge for some compilers */
p++;
i--;
}
writearr(what, len, out);
}
static long *
makebcpl(register long *p,
register char *s,
register int n)
{
register long t;
register long sc;
if (strlen(s) < n)
n = strlen(s);
t = ((long)n) << 24;
sc = 16;
while (n > 0)
{
t |= ((long)(*(unsigned char *)s++)) << sc;
sc -= 8;
if (sc < 0)
{
*p++ = t;
t = 0;
sc = 24;
}
n--;
}
if (t)
*p++ = t;
return p;
}
static long
checksum(ttfinfo **array)
{
int i;
unsigned long s1 = 0, s2 = 0;
char *p;
ttfinfo *ti;
for (i = 0; i < 256; i++)
if (NULL != (ti = array[i]))
{
s1 = ((s1 << 1) ^ (s1 >> 31)) ^ ti->width; /* cyclic left shift */
s1 &= 0xFFFFFFFF; /* in case we're on a 64-bit machine */
for (p = ti->adobename; *p; p++)
s2 = (s2 * 3) + *p;
}
s1 = (s1 << 1) ^ s2;
return s1;
}
int
transform(register int x, register int y,
float ef, float sl)
{
register double acc;
acc = ef * x + sl * y;
return (int)(acc >= 0 ? floor(acc + 0.5) : ceil(acc - 0.5));
}
int
buildtfm(Font *fnt)
{
register int i, j;
register ttfinfo *ti;
int byte1, old_byte1, byte2;
long cksum;
double Slant;
char buffer[256];
struct sf sf_array[256];
if (fnt->subfont_ligs)
{
for (i = 0; i < 256; i++)
{
ti = fnt->inencptrs[i];
if (ti)
{
sf_array[i].sf_code = ti->charcode;
sf_array[i].position = i;
}
else
{
sf_array[i].sf_code = -1;
sf_array[i].position = -1;
}
}
/* we sort the subfont character codes before we build a ligkern list */
qsort(sf_array, 256, sizeof (struct sf), compare_sf);
/* we need to create dummy characters for the ligatures in case the
character slots of the affected codes are unused */
i = 0;
while (i < 256 && sf_array[i].sf_code > -1)
{
byte1 = sf_array[i].sf_code >> 8;
byte2 = sf_array[i].sf_code & 0xFF;
if (!fnt->inencptrs[byte1])
{
ti = newchar(fnt);
ti->llx = ti->lly = 0;
ti->urx = ti->ury = 0;
ti->width = 0;
fnt->inencptrs[byte1] = ti;
ti->incode = byte1;
ti->adobename = ".dummy";
}
if (!fnt->inencptrs[byte2])
{
ti = newchar(fnt);
ti->llx = ti->lly = 0;
ti->urx = ti->ury = 0;
ti->width = 0;
fnt->inencptrs[byte2] = ti;
ti->incode = byte2;
ti->adobename = ".dummy";
}
i++;
}
}
for (i = 0; i <= 0xFF && fnt->inencptrs[i] == NULL; i++)
;
bc = i;
for (i = 0xFF; i >= 0 && fnt->inencptrs[i] == NULL; i--)
;
ec = i;
if (ec < bc)
{
if (fnt->sfdname)
return 0;
else
oops("No TTF characters.");
}
header = (long *)mymalloc(40000L);
cksum = checksum(fnt->inencptrs);
header[0] = cksum;
header[1] = 0xA00000; /* 10pt design size */
(void)makebcpl(header + 2, fnt->codingscheme, 39);
(void)makebcpl(header + 12, fnt->fullname, 19);
/* 4 bytes are left free for the unused FACE value */
buffer[0] = '\0';
strncat(buffer, "Created by `", 12);
strncat(buffer, fnt->titlebuf, 255 - 12 - 1);
strncat(buffer, "'", 1);
charinfo = makebcpl(header + 18, buffer, 255);
lh = charinfo - header;
width = charinfo + (ec - bc + 1);
width[0] = 0;
nw = 1;
for (i = bc; i <= ec; i++)
if (NULL != (ti = fnt->inencptrs[i]))
{
width[nw] = ti->width;
for (j = 1; width[j] != ti->width; j++)
;
ti->wptr = j;
if (j == nw)
nw++;
}
if (nw > 256)
oops("256 chars with different widths.");
depth = width + nw;
depth[0] = 0;
nd = 1;
for (i = bc; i <= ec; i++)
if (NULL != (ti = fnt->inencptrs[i]))
{
depth[nd] = -ti->lly;
for (j = 0; depth[j] != -ti->lly; j++)
;
ti->dptr = j;
if (j == nd)
nd++;
}
if (nd > 16)
{
remap(depth, nd, 16, source, unsort);
nd = 16;
for (i = bc; i <= ec; i++)
if (NULL != (ti = fnt->inencptrs[i]))
ti->dptr = unsort[ti->dptr];
}
height = depth + nd;
height[0] = 0;
nh = 1;
for (i = bc; i <= ec; i++)
if (NULL != (ti = fnt->inencptrs[i]))
{
height[nh] = ti->ury;
for (j = 0; height[j] != ti->ury; j++)
;
ti->hptr = j;
if (j == nh)
nh++;
}
if (nh > 16)
{
remap(height, nh, 16, source, unsort);
nh = 16;
for (i = bc; i <= ec; i++)
if (NULL != (ti = fnt->inencptrs[i]))
ti->hptr = unsort[ti->hptr];
}
italic = height + nh;
italic[0] = 0;
ni = 1;
for (i = bc; i <= ec; i++)
if (NULL != (ti = fnt->inencptrs[i]))
{
italic[ni] = ti->urx - ti->width;
if (italic[ni] < 0)
italic[ni] = 0;
for (j = 0; italic[j] != italic[ni]; j++)
;
ti->iptr = j;
if (j == ni)
ni++;
}
if (ni > 64)
{
remap(italic, ni, 64, source, unsort);
ni = 64;
for (i = bc; i <= ec; i++)
if (NULL != (ti = fnt->inencptrs[i]))
ti->iptr = unsort[ti->iptr];
}
for (i = bc; i <= ec; i++)
if (NULL != (ti = fnt->inencptrs[i]))
charinfo[i - bc] = ((long)(ti->wptr) << 24) +
((long)(ti->hptr) << 20) +
((long)(ti->dptr) << 16) +
((long)(ti->iptr) << 10);
else
charinfo[i - bc] = 0;
ligkern = italic + ni;
nl = 0;
if (fnt->subfont_ligs)
{
/* Now we build the ligature list. The ligature consisting of character
code byte1 + byte2 should yield the actual character. The fonts of
the HLaTeX package for Korean use this mechanism. */
old_byte1 = -1;
while (nl < 256 && sf_array[nl].sf_code > -1)
{
byte1 = sf_array[nl].sf_code >> 8;
byte2 = sf_array[nl].sf_code & 0xFF;
if (byte1 != old_byte1)
{
charinfo[byte1 - bc] += 0x100L + /* set the lig tag */
nl; /* set the position in array */
if (old_byte1 > -1)
ligkern[nl - 1] |= 0x80000000L; /* set the STOP byte in previous
ligkern command */
}
ligkern[nl] = ((long)byte2 << 16) +
(long)sf_array[nl].position;
old_byte1 = byte1;
nl++;
}
ligkern[nl - 1] |= 0x80000000L;
}
kerns = ligkern + nl;
nk = 0; /* kerns are omitted from raw TeX font */
Slant = fnt->slant - fnt->efactor * tan(fnt->italicangle * (PI / 180.0));
tparam = kerns + nk;
tparam[0] = (long)(FIXFACTOR * Slant + 0.5);
tparam[1] = scale((long)fnt->fontspace);
tparam[2] = (fnt->fixedpitch ? 0 : scale((long)(300 * fnt->efactor + 0.5)));
tparam[3] = (fnt->fixedpitch ? 0 : scale((long)(100 * fnt->efactor + 0.5)));
tparam[4] = scale((long)fnt->xheight);
tparam[5] = scale((long)(1000 * fnt->efactor + 0.5));
np = 6;
return 1;
}
void
writetfm(Font *fnt)
{
FILE *out;
char *tfm_name;
int len = 0;
if (fnt->tfm_path)
len += strlen(fnt->tfm_path);
len += strlen(fnt->fullname);
len += strlen(fnt->tfm_ext);
len++;
tfm_name = (char *)mymalloc(len);
tfm_name[0] = '\0';
if (fnt->tfm_path)
strcat(tfm_name, fnt->tfm_path);
strcat(tfm_name, fnt->fullname);
strcat(tfm_name, fnt->tfm_ext);
if ((out = fopen(tfm_name, "wb")) == NULL)
oops("Cannot open tfm file `%s'.", tfm_name);
free(tfm_name);
lf = 6 + lh + (ec - bc + 1) + nw + nh + nd + ni + nl + nk + ne + np;
write16(lf, out);
write16(lh, out);
write16(bc, out);
write16(ec, out);
write16(nw, out);
write16(nh, out);
write16(nd, out);
write16(ni, out);
write16(nl, out);
write16(nk, out);
write16(ne, out);
write16(np, out);
writearr(header, lh, out);
writearr(charinfo, ec - bc + 1, out);
writesarr(width, nw, out);
writesarr(height, nh, out);
writesarr(depth, nd, out);
writesarr(italic, ni, out);
writearr(ligkern, nl, out);
writesarr(kerns, nk, out);
writearr(tparam, np, out);
free(header);
fclose(out);
}
/* end */

28
contrib/ttf2pk/tfmaux.h Normal file
View File

@@ -0,0 +1,28 @@
/*
* tfmaux.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef TFMAUX_H
#define TFMAUX_H
#include "ttf2tfm.h"
#define FIXFACTOR (0x100000L) /* 2^{20}, the unit fixnum */
int transform(int x, int y, float ef, float sl);
int buildtfm(Font *fnt);
void writetfm(Font *fnt);
#endif /* TFMAUX_H */
/* end */

289
contrib/ttf2pk/ttf2pk.1 Normal file
View File

@@ -0,0 +1,289 @@
.\" man page for ttf2pk
.
.TH TTF2PK 1 15-Aug-1999 "FreeType version 1.3"
.SH NAME
ttf2pk \- convert a TrueType font into TeX's PK format
.SH SYNOPSIS
.na
.nh
.B ttf2pk
.RB [ -q ]
.RB [ -n ]
.I "\%font-name \%resolution"
.br
.B ttf2pk
.B -t
.RB [ -q ]
.I \%font-name
.br
.B "ttf2pk --version"
|
.B --help
.ad
.hy
.
.
.
.\" ====
.\" ==== macro definitions
.\" ====
.
.\" here we define \TeX for troff and nroff
.if t .ds TX \fRT\\h'-0.1667m'\\v'0.20v'E\\v'-0.20v'\\h'-0.125m'X\fP
.if n .ds TX TeX
.
.\" and here the same for \LaTeX
.if t \{\
.ie '\*(.T'dvi' \
.ds LX \fRL\h'-0.36m'\v'-0.15v'\s-3A\s0\h'-0.15m'\v'0.15v'\fP\*(TX
.el .ds LX \fRL\h'-0.36m'\v'-0.22v'\s-2A\s0\h'-0.15m'\v'0.22v'\fP\*(TX
.\}
.if n .ds LX LaTeX
.
.\" \LaTeXe
.\" note that we need \vareps for TeX instead of \eps which can only be
.\" accessed with the \N escape sequence (in the Math Italic font)
.if t \{\
.ie '\*(.T'dvi' .ds LE \*(LX\h'0.15m'2\v'0.20v'\f(MI\N'34'\fP\v'-0.20v'
.el .ds LE \*(LX\h'0.15m'2\v'0.20v'\(*e\v'-0.20v'
.\}
.if n .ds LE LaTeX\ 2e
.
.\" a typewriter font
.if t \{\
.de C
\fC\\$1\fP\\$2
..
.\}
.if n \{\
.de C
\\$1\\$2
..
.\}
.
.\" ====
.\" ==== end of macro definitions
.\" ====
.
.
.
.SH DESCRIPTION
This program converts a TrueType font into a
.C PK
file; the created font can then be used with \*(TX
or \*(LX.
.PP
All TrueType fonts to be used must be registered in a configuration
file called
.C \%ttfonts.map ;
it specifies how to handle each font.
CJKV (Chinese/Japanese/Korean/old Vietnamese) subfonts as created by
.B ttf2tfm
are also supported.
.PP
.B ttf2pk
always assumes 10pt as the design size for the written \*(TX
font.
.
.
.SH PARAMETERS
.TP
.B -q
This optional switch makes
.B ttf2pk
quiet.
It suppresses any informational output except warning and error
messages.
.TP
.B -n
Use only `\c
.C \&.pk '
as the extension instead of `\c
.C \&. \c
.RI < \%resolution >\c
.C pk '.
.TP
.B -t
Test for the existence of
.IR \%font-name .
Returns 0 on success and prints out the corresponding line in
.C \%ttfonts.map
(provided the
.B -q
switch isn't set).
.TP
.I font-name
The \*(TX
name of the font.
.B ttf2pk
looks this name up in a configuration file called
.C \%ttfonts.map
for further information how to process the font.
.TP
.I resolution
The resolution, given in dots per inch.
Currently the horizontal resolution is equal to the vertical
resolution.
The design size is always assumed to be 10pt.
.TP
.B --version
Shows the current version of
.B ttf2pk
and the used file search library (e.g.\ \c
.BR kpathsea ).
.TP
.B --help
Shows usage information.
.PP
Environment variables for file searching are described in the manual page
of
.BR ttf2tfm .
.
.
.SH "THE CONFIGURATION FILE"
.B ttf2pk
uses, similar to
.BR dvips ,
a font definition file called
.C \%ttfonts.map .
The parameters specified to
.B ttf2tfm
are here preserved\(em\c
.B ttf2tfm
writes out to standard output, as the last line, a proper
configuration entry for
.C \%ttfonts.map .
.PP
As an example, a call to
.PP
.in +2m
.C "ttf2tfm arial -p T1.enc -s 0.25 -P 1 -E 0 arials"
.PP
will produce the following line:
.PP
.in +2m
.C "arials arial Slant=0.25 Pid=1 Eid=0 Encoding=T1.enc"
.PP
See
.BR ttf2tfm (1)
and
.BR afm2tfm (1)
of the
.B dvips
package for a detailed description of encoding files.
.PP
Here a table listing the various
.B ttf2tfm
parameters and the corresponding
.C \%ttfonts.map
entries:
.PP
.in +4m
.ta 2i
-s Slant
.br
-e Extend
.br
-p Encoding
.br
-f Fontindex
.br
-P Pid
.br
-E Eid
.br
-n PS=Yes
.br
-N PS=Only
.br
-R Replacement
.br
-x Rotate=Yes
.br
-y Y-Offset
.PP
Single replacement glyph names given to
.B ttf2tfm
with `\c
.BI -r \ old-glyphname\ new-glyphname\c
\&'
are directly specified with `\c
.IR old-glyphname = new-glyphname '.
They will be ignored if in subfont mode or if no encoding file is given.
.PP
One additional parameter in
.C \%ttfonts.map
is unique to
.BR ttf2pk :
`Hinting', which can take the values `On' or `Off'.
Some fonts (e.g.\ the CJK part of
.C \%cyberbit.ttf )
are rendered incorrectly if hinting is activated.
Default is `On' (you can also use `Yes', `No', `1', and `0').
.PP
For a description of subfonts (i.e., entries of the form `\c
.I <namestem>\c
.C @\c
.I <sfd-filename>\c
.C @ ')
please refer to
.BR ttf2tfm (1).
.PP
The format of
.C \%ttfonts.map
is simple.
Each line defines a font; first comes the \*(TX
font name, then its TrueType font file name, followed by the
parameters in any order.
Case is significant (even for parameter names); the parameters are
separated from its values by an equal sign, with whitespace possibly
surrounding it.
.B ttf2pk
reads in
.C \%ttfonts.map
line by line, continuing until the \*(TX
font specified on the command line is found, otherwise the programs
exits with error code\ 2.
Thus you can use any character invalid in a \*(TX
font name to start a comment line.
.PP
You can use `\\' as the final character of a line to indicate that the
input is continued on the next line.
The backslash and the following newline character will be removed.
.PP
.B ttf2pk
will abort if it can't find or read the \*(TX
font metrics file of the given \*(TX
font name.
.
.
.SH "RETURN VALUE"
If the call was successful, 0\ will be returned.
In case of error, the return value is\ 1.
Finally, if the font can't be found in
.C \%ttfonts.map ,
2\ is returned.
This simplifies the inclusion of
.B ttf2pk
into scripts like
.B mktexpk
for automatic font generation.
.
.
.SH "SEE ALSO"
.BR ttf2tfm (1),
.BR afm2tfm (1)
.
.
.SH AVAILABILITY
.B ttf2pk
is part of the FreeType package, a high quality TrueType rendering
library.
.
.
.SH AUTHORS
Werner LEMBERG
.C <wl@gnu.org>
.br
Fr\('ed\('eric LOYER
.C <loyer@ensta.fr>

592
contrib/ttf2pk/ttf2pk.c Normal file
View File

@@ -0,0 +1,592 @@
/*
* ttf2pk.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> /* for size_t */
#include <string.h>
#include <math.h>
#include <ctype.h>
#include "ttf2tfm.h"
#include "newobj.h"
#include "pklib.h"
#include "ttfenc.h"
#include "ttflib.h"
#include "errormsg.h"
#include "filesrch.h"
#include "parse.h"
#include "subfont.h"
char ident[] = "ttf2pk version 1.3";
char progname[] = "ttf2pk"; /* for error/warning messages */
Boolean have_sfd = False;
Boolean have_pid = False;
Boolean have_eid = False;
/*
* Checks for an equal sign surrounded by whitespace.
*/
static char *
strip_equal(char *s, char *os, char *p)
{
while (isspace(*p))
p++;
if (*p != '=')
boops(os, p - s, "Missing `='.");
p++;
while (isspace(*p))
p++;
return p;
}
#define USAGE "\
Convert a TrueType font to TeX's PK format.\n\
\n\
-q suppress informational output\n\
-n only use `.pk' as extension\n\
-t test for <font> (returns 0 on success)\n\
--help print this message and exit\n\
--version print version number and exit\n\
"
static void
usage(void)
{
fputs("Usage: ttf2pk [-q] [-n] <font> <dpi>\n", stdout);
fputs(" ttf2pk -t [-q] <font>\n", stdout);
fputs(USAGE, stdout);
exit(0);
}
#define VERSION "\
Copyright (C) 1997-1999 Frederic Loyer and Werner Lemberg.\n\
There is NO warranty. You may redistribute this software\n\
under the terms of the GNU General Public License\n\
and the gsftopk copyright.\n\
\n\
For more information about these matters, see the files\n\
named COPYING and pklib.c.\n\
\n\
Primary authors of ttf2pk: F. Loyer and W. Lemberg.\n\
\n\
ttf2pk is partially based on gsftopk from P. Vojta\n\
and the FreeType project from\n\
David Turner, Robert Wilhelm, and Werner Lemberg\n\
"
static void
version(void)
{
fputs(ident, stdout);
fprintf(stdout, " (%s)\n", TeX_search_version());
fputs(VERSION, stdout);
exit(0);
}
static int
compare(Font *fnt, char *s, char *key)
{
char c;
char *p;
char *temp, *temp1;
int value;
int sfd_begin, postfix_begin;
/*
* We isolate the fontname.
*/
while (isspace(*s))
s++;
p = s;
while (*p && !isspace(*p))
p++;
c = *p;
*p = '\0';
temp = newstring(s);
*p = c;
/*
* We search for a subfont definition file name.
*/
handle_sfd(temp, &sfd_begin, &postfix_begin);
if (sfd_begin == -1)
value = strcmp(temp, key);
else
{
size_t len, len1, len2;
/*
* The sfd file will be only searched if prefix and postfix match.
*/
len = strlen(key);
len1 = strlen(temp);
len2 = strlen(temp + postfix_begin);
if (len1 + len2 >= len)
value = -1;
else if (!strncmp(temp, key, len1) &&
!strcmp(temp + postfix_begin, key + (len - len2)))
{
c = key[len - len2];
key[len - len2] = '\0';
temp1 = newstring(key + len1);
key[len - len2] = c;
if (fnt->sfdname)
free(fnt->sfdname);
fnt->sfdname = newstring(temp + sfd_begin);
/*
* If the sfd file can't be opened the search is continued.
*/
value = !init_sfd(fnt, False);
if (!value)
{
value = -1;
while (get_sfd(fnt))
{
if (!strcmp(fnt->subfont_name, temp1))
{
value = 0; /* success */
have_sfd = True;
break;
}
}
close_sfd();
}
free(temp1);
}
else
value = -1;
}
free(temp);
return value;
}
int
main(int argc, char** argv)
{
size_t l;
unsigned int i;
long index, code;
FILE *config_file;
char *configline, *oldconfigline, *p, *q;
Font font;
encoding *enc;
long inenc_array[256];
char *fontname;
size_t fontname_len;
char *pk_filename, *tfm_filename, *enc_filename, *cfg_filename;
char *real_ttfname, *real_cfg_filename;
int dpi = 0, ptsize;
Boolean hinting = True;
Boolean quiet = False;
Boolean no_dpi = False;
Boolean testing = False;
TeX_search_init(argv[0], "ttf2pk", "TTF2PK");
if (argc == 1)
oops("Need at least two arguments.\n"
"Try `ttf2pk --help' for more information.");
if (argc == 2)
{
if (strcmp(argv[1], "--help") == 0)
usage();
else if (strcmp(argv[1], "--version") == 0)
version();
}
while (argv[1][0] == '-')
{
if (argv[1][1] == 'q')
quiet = True;
else if (argv[1][1] == 'n')
no_dpi = True;
else if (argv[1][1] == 't')
testing = True;
else
oops("Unknown option `%s'.\n"
"Try `ttf2pk --help' for more information.", argv[1]);
argv++;
argc--;
}
if (testing)
{
if (argc != 2)
oops("Need exactly one parameter for `-t' option.\n"
"Try `ttf2pk --help' for more information.");
}
else if (argc != 3)
oops("Need at most two arguments.\n"
"Try `ttf2pk --help' for more information.");
if (!quiet)
printf("This is %s\n", ident);
if (!testing)
if ((dpi = atoi(argv[2])) <= 50)
oops("dpi value must be larger than 50.");
fontname = argv[1];
fontname_len = strlen(fontname);
enc_filename = NULL;
ptsize = 10;
init_font_structure(&font);
cfg_filename = newstring("ttfonts.map");
real_cfg_filename = TeX_search_config_file(&cfg_filename);
if (!real_cfg_filename)
oops("Cannot find file ttfonts.map.");
config_file = fopen(real_cfg_filename, "rt");
if (config_file == NULL)
oops("Cannot open file ttfonts.map.");
do
{
configline = get_line(config_file);
if (!configline)
oops("Error while reading ttfonts.map.");
if (!*configline)
{
/*
* This is the only error message we suppress if the -q flag
* is set, making it possible to call ttf2pk silently.
*/
if (!quiet)
fprintf(stdout,
"%s: ERROR: Cannot find font %s in ttfonts.map.\n",
progname, fontname);
exit(2);
}
} while (compare(&font, configline, fontname));
fclose(config_file);
if (testing)
{
if (!quiet)
fprintf(stdout, "%s\n", configline);
exit(0);
}
/*
* Parse the line from the config file. We split the config line buffer
* into substrings according to the given options.
*/
l = strlen(configline);
if (configline[l - 1] == '\n')
configline[l - 1] = '\0'; /* strip newline */
oldconfigline = newstring(configline);
p = configline;
while (isspace(*p))
p++;
while (*p && !isspace(*p))
p++;
q = p;
while (*p && isspace(*p))
p++;
if (!*p)
boops(oldconfigline, q - configline, "TTF file missing.");
font.ttfname = p;
while (*p && !isspace(*p))
p++;
if (*p)
*p++ = '\0';
for (; *p; p++)
{
if (isspace(*p))
continue;
if (!strncmp(p, "Slant", 5))
{
p = strip_equal(configline, oldconfigline, p + 5);
if (sscanf(p, "%f", &(font.slant)) == 0)
boops(oldconfigline, p - configline, "Bad `Slant' parameter.");
}
else if (!strncmp(p, "Encoding", 8))
{
if (have_sfd)
boops(oldconfigline, p - configline,
"No `Encoding' parameter allowed for subfonts.");
p = strip_equal(configline, oldconfigline, p + 8);
if (!*p)
boops(oldconfigline, p - configline, "Bad `Encoding' parameter.");
enc_filename = p;
}
else if (!strncmp(p, "Extend", 6))
{
p = strip_equal(configline, oldconfigline, p + 6);
if (sscanf(p, "%f", &(font.efactor)) == 0)
boops(oldconfigline, p - configline, "Bad `Extend' parameter.");
}
else if (!strncmp(p, "Fontindex", 9))
{
p = strip_equal(configline, oldconfigline, p + 9);
if (sscanf(p, "%lu", &(font.fontindex)) < 0)
boops(oldconfigline, p - configline, "Bad `Fontindex' parameter.");
}
else if (!strncmp(p, "Pid", 3))
{
p = strip_equal(configline, oldconfigline, p + 3);
if (sscanf(p, "%hu", &(font.pid)) < 0)
boops(oldconfigline, p - configline, "Bad `Pid' parameter.");
have_pid = True;
}
else if (!strncmp(p, "Eid", 3))
{
p = strip_equal(configline, oldconfigline, p + 3);
if (sscanf(p, "%hu", &(font.eid)) < 0)
boops(oldconfigline, p - configline, "Bad `Eid' parameter.");
have_eid = True;
}
else if (!strncmp(p, "Hinting", 7))
{
p = strip_equal(configline, oldconfigline, p + 7);
if (p[1] == 'N' || p[1] == 'n' ||
p[0] == 'Y' || p[1] == 'y' ||
p[0] == '1')
hinting = True;
else if (p[1] == 'F' || p[1] == 'f' ||
p[0] == 'N' || p[1] == 'n' ||
p[0] == '0')
hinting = False;
else
boops(oldconfigline, p - configline, "Bad `Hinting' parameter.");
}
else if (!strncmp(p, "PS", 2))
{
p = strip_equal(configline, oldconfigline, p + 2);
if (p[1] != '\0' &&
(p[2] == 'l' || p[2] == 'L'))
font.PSnames = Only;
else if (p[1] == 'N' || p[1] == 'n' ||
p[0] == 'Y' || p[0] == 'y' ||
p[0] == '1')
font.PSnames = Yes;
else if (p[1] == 'F' || p[1] == 'f' ||
p[0] == 'N' || p[0] == 'n' ||
p[0] == '0')
font.PSnames = No;
else
boops(oldconfigline, p - configline, "Bad `PS' parameter.");
if (have_sfd)
boops(oldconfigline, p - configline,
"No `PS' parameter allowed for subfonts.");
}
else if (!strncmp(p, "Rotate", 6))
{
p = strip_equal(configline, oldconfigline, p + 6);
if (p[1] == 'N' || p[1] == 'n' ||
p[0] == 'Y' || p[1] == 'y' ||
p[0] == '1')
font.rotate = True;
else if (p[1] == 'F' || p[1] == 'f' ||
p[0] == 'N' || p[1] == 'n' ||
p[0] == '0')
font.rotate = False;
else
boops(oldconfigline, p - configline, "Bad `Rotate' parameter.");
if (!have_sfd)
boops(oldconfigline, p - configline,
"No `Rotate' parameter allowed for non-subfonts.");
}
else if (!strncmp(p, "Y-Offset", 8))
{
p = strip_equal(configline, oldconfigline, p + 8);
if (sscanf(p, "%f", &(font.y_offset)) == 0)
boops(oldconfigline, p - configline, "Bad `Y-Offset' parameter.");
}
else if (!strncmp(p, "Replacement", 11))
{
p = strip_equal(configline, oldconfigline, p + 11);
if (!*p)
boops(oldconfigline, p - configline, "Bad `Replacement' parameter.");
font.replacementname = p;
}
else
{
char *new_name, *old_name;
stringlist *sl;
old_name = p;
while (*p && !isspace(*p) && *p != '=')
p++;
q = p;
p = strip_equal(configline, oldconfigline, p);
*q = '\0';
new_name = p;
while (*p && !isspace(*p))
p++;
if (*p)
*p++ = '\0';
sl = newstringlist();
sl->new_name = new_name;
sl->old_name = old_name;
sl->next = font.replacements;
font.replacements = sl;
p--; /* to make the next while loop work */
}
while (*p && !isspace(*p))
p++;
if (*p)
*p = '\0';
}
if (font.PSnames == Only)
if (have_pid || have_eid)
boops(oldconfigline, 0,
"No `Pid' or `Eid' parameters allowed if `PS=Only' is set.");
font.replacementname = newstring(font.replacementname);
get_replacements(&font);
tfm_filename = newstring(fontname);
TFMopen(&tfm_filename);
pk_filename = mymalloc(fontname_len + 10);
if (no_dpi)
sprintf(pk_filename, "%s.pk", fontname);
else
sprintf(pk_filename, "%s.%dpk", fontname, dpi);
PKopen(pk_filename, fontname, dpi);
font.ttfname = newstring(font.ttfname);
real_ttfname = TeX_search_ttf_file(&(font.ttfname));
if (!real_ttfname)
oops("Cannot find `%s'.", font.ttfname);
TTFopen(real_ttfname, &font, dpi, ptsize, quiet);
enc_filename = newstring(enc_filename);
enc = readencoding(&enc_filename, &font, True);
if (enc)
{
char *name;
restore_glyph(enc, &font);
for (i = 0; i <= 0xFF; i++)
{
name = enc->vec[i];
if (!font.PSnames)
{
code = adobename_to_code(name);
if (code < 0 && strcmp(name, ".notdef") != 0)
warning("Cannot map character `%s'.", name);
inenc_array[i] = code;
}
else
{
/* we search the glyph index */
index = TTFsearch_PS_name(name);
if (index < 0)
warning("Cannot map character `%s'.", name);
inenc_array[i] = index | 0x10000;
}
}
}
else
{
if (font.replacements)
warning("Replacement glyphs will be ignored.");
if (have_sfd)
TTFget_subfont(&font, inenc_array);
else
/* get the table of glyph names too */
enc = TTFget_first_glyphs(&font, inenc_array);
}
for (i = 0; i <= 0xFF; i++)
{
byte *bitmap;
int w, h, hoff, voff;
if ((code = inenc_array[i]) >= 0)
{
if (!quiet)
{
printf("Processing glyph %3ld %s index 0x%04x %s\n",
(long)i, (code >= 0x10000) ? "glyph" : "code",
(unsigned int)(code & 0xFFFF), enc ? enc->vec[i] : "");
fflush(stdout);
}
if (TTFprocess(&font, code,
&bitmap, &w, &h, &hoff, &voff, hinting, quiet))
PKputglyph(i,
-hoff, -voff, w - hoff, h - voff,
w, h, bitmap);
else
warning("Cannot render glyph with %s index 0x%x.",
(code >= 0x10000) ? "glyph" : "code",
(unsigned int)(code & 0xFFFF));
}
}
PKclose();
exit(0); /* for safety reasons */
return 0; /* never reached */
}
/* end */

733
contrib/ttf2pk/ttf2pk.doc Normal file
View File

@@ -0,0 +1,733 @@
ttf2tfm -- TrueType to TFM converter
ttf2pk -- TrueType to PK converter
====================================
These two auxiliary programs make TrueType fonts usable with TeX.
ttf2tfm extracts the metric and kerning information of a TrueType font
and converts it into metric files usable by TeX (quite similar to
afm2tfm which is part of the dvips package). ttf2pk rasterizes the
glyph outlines of a TrueType font into a bitmap font in PK format.
Since a TrueType font often contains more than 256 glyphs, some means
are necessary to map a subset of the TrueType glyphs into a TeX font.
To do this, two mapping tables are needed: the first maps from the
TrueType font to a raw TeX font (this mapping table is used both by
ttf2tfm and ttf2pk), and the second maps from the raw TeX font to
another (virtual) TeX font providing all kerning and ligature
information needed by TeX.
We sometimes refer to this first map as the `input' or `raw' map, and
to the second as the `output' or `virtual' map.
This two stage mapping has the advantage that one raw font can be
accessed with various TeX encodings (e.g. T1 and OT1) via the virtual
font mechanism, and just one PK file is necessary.
For CJK fonts, a different mechanism is provided (see section `Subfont
definition files' below). Additionally, rotated glyphs for
pseudo-vertical writing are supported -- if possible, vertical glyph
presentation forms are used from the font's GSUB table.
ttf2tfm
=======
Usage:
ttf2tfm FILE[.ttf|.ttc] [OPTION]... [FILE[.tfm]]
Options (default values are given in brackets):
-c REAL use REAL for height of small caps made with -V [0.8]
-e REAL widen (extend) characters by a factor of REAL [1.0]
-E INT select INT as the TTF encoding ID [1]
-f INT select INT as the font index in a TTC [0]
-l create 1st/2nd byte ligatures in subfonts
-n use PS names of TrueType font
-N use only PS names and no cmap
-O use octal for all character codes in the vpl file
-p ENCFILE[.enc] read ENCFILE for the TTF->raw TeX mapping
-P INT select INT as the TTF platform ID [3]
-q suppress informational output
-r OLDNAME NEWNAME replace glyph name OLDNAME with NEWNAME
-R RPLFILE[.rpl] read RPLFILE containing glyph replacement names
-s REAL oblique (slant) characters by REAL, usually <<1 [0.0]
-t ENCFILE[.enc] read ENCFILE for the encoding of the vpl file
-T ENCFILE[.enc] equivalent to -p ENCFILE -t ENCFILE
-u output only characters from encodings, nothing extra
-v FILE[.vpl] make a VPL file for conversion to VF
-V SCFILE[.vpl] like -v, but synthesize smallcaps as lowercase
-x rotate subfont glyphs by 90 degrees
-y REAL move rotated glyphs down by a factor of REAL [0.25]
--help print this message and exit
--version print version number and exit
The usage is very similar to afm2tfm. Please consult the dvips info
file for more details on the various parameters. Here we will
concentrate on the differences between afm2tfm and ttf2tfm.
cmaps
-----
Contrary to Type 1 PostScript fonts (but similar to the new CID-keyed
PostScript fonts), most TrueType fonts have more than one native
mapping table, also called `cmap', which maps the (internal) TTF glyph
indices to the (external) TTF character codes. Common examples are a
mapping table to Unicode encoded character positions and the standard
Macintosh mapping. To specify this TrueType mapping table, use the
options `-P' and `-E'. With `-P' you specify the platform ID; defined
values are:
platform platform ID (pid)
----------------------------------
Apple Unicode 0
Macintosh 1
ISO 2
Microsoft 3
The encoding ID depends on the platform. For pid=0, we ignore the
`-E' parameter (setting it to zero) since the mapping table is always
Unicode version 2.0. For pid=1, the following table lists the defined
values:
platform ID = 1
script encoding ID (eid)
---------------------------------
Roman 0
Japanese 1
Chinese 2
Korean 3
Arabic 4
Hebrew 5
Greek 6
Russian 7
Roman Symbol 8
Devanagari 9
Gurmukhi 10
Gujarati 11
Oriya 12
Bengali 13
Tamil 14
Telugu 15
Kannada 16
Malayalam 17
Sinhalese 18
Burmese 19
Khmer 20
Thai 21
Laotian 22
Georgian 23
Armenian 24
Maldivian 25
Tibetan 26
Mongolian 27
Geez 28
Slavic 29
Vietnamese 30
Sindhi 31
Uninterpreted 32
Here are the ISO encoding IDs:
platform ID = 2
encoding encoding ID
----------------------------
ASCII 0
ISO 10646 1
ISO 8859-1 2
And finally, the Microsoft encoding IDs:
platform ID = 3
encoding encoding ID
---------------------------
Symbol 0
Unicode 2.0 1
Shift JIS 2
GB 2312 (1980) 3
Big 5 4
KSC 5601 (Wansung) 5
KSC 5601 (Johab) 6
The program will abort if you specify an invalid platform/encoding ID
pair. Please note that most fonts have at most two or three cmaps,
usually corresponding to the pid/eid pairs (1,0), (3,0), or (3,1) in
case of Latin based fonts. Valid Microsoft fonts should have a (3,1)
mapping table, but some fonts exist (mostly Asian fonts) which have a
(3,1) cmap not encoded in Unicode. The reason for this strange
behavior is the fact that some MS Windows versions will reject fonts
having a non-Unicode cmap (since all non-Unicode Microsoft encoding
IDs are for Asian specific MS Windows versions).
The `-P' and `-E' options to ttf2tfm must be equally specified for
ttf2pk; the corresponding parameters in ttfonts.map are `Pid' and
`Eid', respectively.
The default pid/eid pair is (3,1).
If you use the `-N' switch, all cmaps are ignored, using only the
PostScript names in the TrueType font. The corresponding option in
ttfonts.map is `PS=Only'.
If you use the `-n' switch, the default glyph names built into ttf2tfm
are replaced with the PS glyph names found in the font. In many cases
this is not what you want because the glyph names in the font are
often incorrect or non-standard. The corresponding option in
ttfonts.map `PS=Yes'.
input and output encodings
--------------------------
You must specify the encoding vectors from the TrueType font to the
raw TeX font and from the raw TeX font to the virtual TeX font exactly
as with afm2tfm, but you have more possibilities to address the
character codes. [With `encoding vector' a mapping table with 256
entries in form of a PostScript vector is meant; see the file
`T1-WGL4.enc' of this package for an example.] With afm2tfm, you must
access each glyph with its Adobe glyph name, e.g. `/quotedsingle' or
`/Acircumflex'. This has been extended with ttf2tfm; now you can (and
sometimes must) access the code points and/or glyphs directly using
the following syntax for specifying the character position in decimal,
octal, or hexadecimal notation: `/.c<decimal-number>',
`/.c0<octal-number>', or `/.c0x<hexadecimal-number>'. Examples:
`/.c72', `/.c0646', `/.c0x48'. To access a glyph index directly, use
the character `g' instead of `c' in the just introduced notation.
Example: `/.g0x32'.
[Note: The `.cXXX' notation makes no sense if `-N' is used.]
Another possibility is to use the `-r old-glyphname new-glyphname'
switch to rename a glyph. Example:
ttf2tfm ... -r .g0xc7 dotlessi -r hungarumlaut dblacute ...
Nevertheless, it is not allowed to use the `.gXXX' or `.cXXX' glyph
name construct for `new-glyphname'.
Alternatively, you can collect such replacement pairs in a file which
should have `.rpl' as extension, using the `-R' option. The syntax is
simple: Each line contains a pair `old-glyphname new-glyphname'
separated by whitespace (without the quotation marks). The percent
sign starts a line comment; you can continue a line with a backslash
as the last character. An example for a replacement file is `VPS.rpl'
(to be used in conjunction with `ET5.enc' for Vietnamese) which is
part of this package.
The `-r' and `-R' switches are ignored for subfonts or if no encoding
tables are specified. For ttf2pk, the corresponding option to `-R' is
`Replacement'. Single replacements are directly given as
old_glyphname=newglyphname in ttfonts.map.
For pid/eid pairs (1,0) and (3,1), both ttf2tfm and ttf2pk recognize
built-in default Adobe glyph names; the former pair follows the names
given in Appendix E of the book `Inside Macintosh', volume 6, the
latter uses the names given in the TrueType Specification (WGL4, a
Unicode subset). Note that Adobe glyph names are not unique and do
sometimes differ: E.g., many PS fonts have the glyph `mu', whereas
this glyph is called `mu1' in the WGL4 character set to distinguish it
from the real Greek letter mu. You can find those mapping tables in
the source code file `ttfenc.c'.
On the other hand, the switches `-n' and `-N' make ttf2tfm read in and
use the PostScript names in the TrueType font itself (stored in the
font's `post' table) instead of the default Adobe glyph names.
If you don't select an input encoding, the first 256 glyphs of the
TrueType font with a valid entry in the selected cmap will be mapped
to the TeX raw font (without the `-q' option ttf2tfm prints this
mapping table to standard output), followed by all glyphs not yet
addressed in the selected cmap. However, some code points for the
(1,0) pid/eid pair are omitted since they do not represent glyphs
useful for TeX: 0x00 (null), 0x08 (backspace), 0x09 (horizontal
tabulation), 0x0d (carriage return), and 0x1d (group separator). The
`invalid character' with glyph index 0 will be omitted too.
If you select the `-N' switch, the first 256 glyphs of the TrueType
font with a valid PostScript name will be used in case no input
encoding is specified. Again, some glyphs are omitted: `.notdef',
`.null', and `nonmarkingreturn'.
If you don't select an output encoding, ttf2tfm uses the same mapping
table as afm2tfm would use (you can find it in the source code file
texenc.c); it corresponds to TeX typewriter text. Unused positions
(either caused by empty code points in the mapping table or missing
glyphs in the TrueType font) will be filled (rather arbitrarily) with
characters present in the input encoding but not specified in the
output encoding (without the `-q' option ttf2tfm prints the final
output encoding to standard output). Use the `-u' option if you want
only glyphs in the virtual font which are defined in the output
encoding file, and nothing more.
One feature missing in afm2tfm has been added which is needed by the
LaTeX T1 encoding: ttf2tfm will construct the glyph `Germandbls' (by
simply concatenating to `S' glyphs) even for normal fonts if possible.
It appears in the glyph list (written to stdout) as the last item,
marked with an asterisk. Since this isn't a real glyph it will be
available only in the virtual font.
For both input and output encoding, an empty code position is
represented by the glyph name `.notdef'.
In encoding files, you can use `\' as the final character of a line to
indicate that the input is continued on the next line. The backslash
and the following newline character will be removed.
ttf2tfm returns 0 on success and 1 on error; warning and error
messages are written to standard error.
other options
-------------
You can select the font in a TrueType font collection (which usually
has the extension `.ttc') with `-f'; the default value, zero,
specifies the first font. For fonts not being a collection, this
parameter is ignored.
The option `-l' makes ttf2tfm create ligatures in subfonts between
first and second bytes of all the original character codes. Example:
Character code 0xABCD maps to character position 123 in subfont 45.
Then a ligature in subfont 45 between position 0xAB and 0xCD pointing
to character 123 will be produced. The fonts of the Korean HLaTeX
package use this feature.
To produce glyphs rotated by 90 degrees counter-clockwise, use `-x'.
If the font contains a GSUB table (with feature `vert') to specify
vertical glyph presentation forms, both ttf2pk and ttf2tfm will use
it. This will work only in subfont mode. The y-offset of rotated
glyphs can be specified with the `-y' option; its parameter gives the
fractional amount of shifting downwards (the unit is one EM). If not
specified, a value of 0.25 (em) is used.
ttf2pk
======
Usage:
ttf2pk [-q] [-n] FONT DPI
ttf2pk -t [-q] FONT
Options:
-q suppresses informational output
-n only use `.pk' as extension
-t test for FONT (returns 0 on success)
--help print this message and exit
--version print version number and exit
The FONT parameter must correspond to an entry in the file ttfonts.map
(see below for details), otherwise error code 2 is returned -- this
can be used for scripts like mktexpk to test whether the given font
name is a (registered) TrueType font.
Another possibility is to use the `-t' switch which will print the
line of ttfonts.map corresponding to FONT and return 0 on success
(`-q' suppresses any output).
DPI specifies the intended resolution (we always assume a design size
of 10pt).
ttfonts.map
-----------
ttf2pk uses, similar to dvips, a font definition file called
ttfonts.map. The parameters specified to ttf2tfm are here preserved
-- ttf2tfm writes out to standard output, as the last line, a proper
configuration entry for ttfonts.map.
As an example, a call to
ttf2tfm arial -s 0.25 -P 1 -E 0 -r .g0xc7 caron \
-p 8r.enc -t T1-WGL4.enc -v arialsx arials
will produce the following line:
arials arial Slant=0.25 Encoding=8r.enc Pid=1 Eid=0 .g0xc7=caron
The output encoding given with `-t' for the virtual font `arialsx' is
immaterial to ttf2pk (nevertheless, input encoding files must have the
same format as with ttf2tfm, and all said above about encoding files
holds).
Here a table listing the various ttf2tfm parameters and its
corresponding ttfonts.map entries:
-s Slant
-e Extend
-p Encoding
-f Fontindex
-P Pid
-E Eid
-n PS=Yes
-N PS=Only
-R Replacement
-x Rotate=Yes
-y Y-Offset
Single replacement glyph names given to ttf2tfm with the `-r' switch
are directly specified with old-glyphname=new-glyphname. For subfonts
or if no encoding file is given, replacement glyphs are ignored.
One additional parameter in ttfonts.map is unique to ttf2pk:
`Hinting', which can take the values `On' or `Off'. Some fonts (e.g.
the CJK part of cyberbit.ttf) are rendered incorrectly if hinting is
activated. Default is `On' (you can also use `Yes', `No', `1', and
`0').
The format of ttfonts.map is simple. Each line defines a font; first
comes the TeX font name, then its TrueType font file name, followed by
the parameters in any order. Case is significant (even for parameter
names); the parameters are separated from its values by an equal sign,
with possible whitespace surrounding it. ttf2pk reads in ttfonts.map
line by line, continuing until the TeX font specified on the command
line is found, otherwise the programs exits with error code 2. Thus
you can use any character invalid in a TeX font name to start a
comment line.
In both ttfonts.map and encoding files, use `\' as the final character
of a line to indicate that the input is continued on the next line.
The backslash and the following newline character will be removed.
ttf2pk will abort if it can't find and read the TeX font metrics file
of the given TeX font name.
Subfont definition files
========================
CJK (Chinese/Japanese/Korean) fonts usually contain several thousand
glyphs; to use them with TeX it is necessary to split such large fonts
into subfonts. Subfont definition files (usually having the extension
`.sfd') are a simple means to do this smoothly. A subfont file name
usually consists of a prefix, a subfont infix, and a postfix (which is
empty in most cases), e.g.
ntukai23 -> prefix: ntukai, infix: 23, postfix: (empty)
Here the syntax of a line in an SFD file, describing one subfont:
<whitespace> <infix> <whitespace> <ranges> <whitespace> `\n'
<infix> := anything except whitespace. It's best to use only
alphanumerical characters.
<whitespace> := space, formfeed, carriage return, horizontal and
vertical tabs -- no newline characters.
<ranges> := <ranges> <whitespace> <codepoint> |
<ranges> <whitespace> <range> |
<ranges> <whitespace> <offset> <whitespace> <range>
<codepoint> := <number>
<range> := <number> `_' <number>
<offset> := <number> `:'
<number> := hexadecimal (prefix `0x'), decimal, or octal
(prefix `0')
A line can be continued on the next line with a backslash ending the
line. The ranges must not overlap; offsets have to be in the range
0-255.
Example:
The line
03 10: 0x2349 0x2345_0x2347
assigns to the code positions 10, 11, 12, and 13 of the subfont
having the infix `03' the character codes 0x2349, 0x2345, 0x2346,
and 0x2347, respectively.
The SFD files in the distribution are customized for the CJK package
for LaTeX.
You have to embed the SFD file into the TFM font name (at the place
where the infix will appear) surrounded by two `@' signs, on the
command line resp. the ttfonts.map file; both ttf2tfm and ttf2pk
switch then to subfont mode.
Subfont mode disables the options `-n', `-N', `-p', `-r', `-R', `-t',
`-T', `-u', `-v', and `-V' for ttf2tfm; similarly, no `Encoding' and
`Replacement' parameter resp. single replacement glyph names are
allowed in ttfonts.map.
ttf2tfm will create ALL subfont TFM files specified in the SFD files
(provided the subfont contains glyphs) in one run.
Example:
The call
ttf2tfm ntukai.ttf ntukai@/usr/local/lib/ttf2tfm/Big5@
will use `/usr/local/lib/ttf2tfm/Big5.sfd', producing the subfont
files ntukai01.tfm, ntukai02.tfm etc.
ttf2pk should be then called on the subfonts directly:
ttf2pk ntukai01 600
ttf2pk ntukai02 600
...
Some notes on file searching
============================
Both ttf2pk and ttf2tfm use either the kpathsea, emtexdir, or MiKTeX
library for searching files (emtexdir will work only on operating
systems which have an MS-DOSish background, i.e. MS-DOS, OS/2,
Windows; MiKTeX is specific to MS Windows).
During compilation, you have to define HAVE_KPATHSEA, HAVE_EMTEXDIR,
or MIKTEX to activate the specific file search code.
As a last resort, both programs can be compiled without a search
library; the searched files must be then in the current directory or
specified with a path. Default extensions will be appended also (with
the exception that only `.ttf' is appended and not `.ttc').
kpathsea
--------
Please note that older versions of kpathsea (<3.2) have no special
means to search for TrueType fonts and related files, thus we use the
paths for PostScript related stuff. The actual version of kpathsea is
displayed on screen if you call either ttf2pk or ttf2tfm with the
`--version' command line switch.
Here is a table of the file type and the corresponding kpathsea
variables. TTF2PKINPUTS and TTF2TFMINPUTS are program specific
environment variables introduced in kpathsea version 3.2:
.ttf and .ttc TTFONTS
ttfonts.map TTF2PKINPUTS
.enc TTF2PKINPUTS, TTF2TFMINPUTS
.rpl TTF2PKINPUTS, TTF2TFMINPUTS
.tfm TFMFONTS
.sfd TTF2PKINPUTS, TTF2TFMINPUTS
And here the same for pre-3.2-versions of kpathsea:
.ttf and .ttc T1FONTS
ttfonts.map TEXCONFIG
.enc TEXPSHEADERS
.rpl TEXPSHEADERS
.tfm TFMFONTS
.sfd TEXPSHEADERS
Finally, the same for pre-3.0-versions:
.ttf and .ttc DVIPSHEADERS
ttfonts.map TEXCONFIG
.enc DVIPSHEADERS
.rpl DVIPSHEADERS
.tfm TFMFONTS
.sfd DVIPSHEADERS
Please consult the info files for kpathsea for details on these
variables. The decision whether to use the old or the new scheme will
be done during compilation.
You should set the TEXMFCNF variable to the directory where your
texmf.cnf configuration file resides.
The default TDS location for the files in the data subdirectory is
$TEXMF/ttf2tfm
(or $TEXMF/ttf2pk; you should either make a symbolic link
% ln -s $TEXMF/ttf2tfm $TEXMF/ttf2pk
or set the variable TTF2PKINPUTS to $TEXMF/ttf2tfm for newer kpathsea
versions)
Here is the proper command to find out to which value a kpathsea
variable is set (we use `TTFONTS' as an example). This is especially
useful if a variable isn't set in texmf.cnf or in the environment,
thus pointing to the default value which is hard-coded into the
kpathsea library.
% kpsewhich --progname=ttf2tfm --expand-var='$TTFONTS'
We select the program name also since it is possible to specify
variables which are searched only for a certain program -- in our
example it would be `TTFONTS.ttf2tfm'.
A similar but not identical method is to say
% kpsewhich --progname=ttf2tfm --show-path='truetype fonts'
[A full list of format types can be obtained by saying `kpsewhich
--help' on the command line prompt.] This is exactly the how ttf2tfm
(and ttf2pk) search for files; the disadvantage is that all variables
are expanded which can cause very long string.
emtexdir
--------
Here the list of suffixes and its related environment variables to be
set in autoexec.bat (resp. in config.sys for OS/2):
.ttf and .ttc TTFONTS
ttfonts.map TTFCFG
.enc TTFCFG
.rpl TTFCFG
.tfm TEXTFM
.sfd TTFCFG
With other words, all files in the data subdirectory should be moved
to a place in your emtex tree with TTFCFG pointing to this directory.
If one of the variables isn't set, a warning message is emitted. The
current directory will always be searched. As usual, one exclamation
mark appended to a directory path causes subdirectories one level deep
to be searched, two exclamation marks causes all subdirectories to be
searched. Example:
TTFONTS=c:\fonts\truetype!!;d:\myfonts\truetype!
Constructions like `c:\fonts!!\truetype' aren't possible.
MiKTeX
------
Both ttf2tfm and ttf2pk have been fully integrated into MiKTeX.
Please refer to the documentation of MiKTeX for more details on file
searching.
A full example
==============
Here an example how to handle the font `verdana.ttf' and its variants.
1. Construct the font name
--------------------------
[This is the most complicated part -- in case you are too lazy to
construct font names compliant to TeX's `fontname' scheme, just use
your own names.]
Using the `ftdump' utility (which is part of FreeType) you can find
out the PostScript name of the specific TTF which is probably the
best choice to adapt TrueType fonts to the PostScript-oriented
`fontname' scheme.
In our example, the PostScript name is `Verdana'.
`fontname' uses the scheme
S TT W [V...] [N] [E] [DD]
as documented in `fontname.texi' resp. `fontname.dvi'. Now you have
to check the various mapping files:
S: supplier.map: `j' for `Microsoft'
TT: typeface.map: `vn' for `Verdana'
W: weight.map: `r' for `Regular Roman',
`b' for `bold'
V,
N: variant.map: `8r' for the raw base font
`8t' for the virtual font
(i.e., LaTeX's T1 encoding)
[additionally an inserted `c' for small caps,
`o' for slanted (`oblique'), or `i' for italic
fonts]
Here the standard combinations:
`jvnr8r' for the default base font.
`jvnr8t' for the virtual default font.
`jvnrc8t' for the virtual font with small caps. [As you can see,
no additional raw font is needed.]
`jvnro8r' for the slanted base font.
`jvnro8t' for the virtual slanted font.
The corresponding variants are:
bold: verdanab.ttf -> jvnb{8r,8t}
small caps: jvnbc8t
slanted: jvnbo{8r,8t}
italic: verdanai.ttf -> jvni{8r,8t}
bold and italic: verdanaz.ttf -> jvnbi{8r,8t}
2. Font definition files
------------------------
The FD file should be called `t1jvn.fd' (as you can see, this is T1
encoding). It is very similar to `t1ptm.fd', part of the PSNFSS
package (which can be found in almost all TeX distributions). A
`verdana.sty' file can also be modeled after `times.sty'.
3. Calling ttf2tfm
------------------
To make the example simpler, we use `T1-WGL4.enc' for both the raw
and the virtual encoding. This should be sufficient for most
TrueType fonts mapped to T1 encoding. Other packages may define
other encodings (e.g. the `t2' package available from CTAN defines
mapping files for Cyrillic encodings) -- it may also be necessary to
use the `-n' or `-N' switch together with replacement glyph names to
access all glyph names in the TrueType font.
To create `jvnr8r' and `jvnr8t', just call
ttf2tfm verdana -T T1-WGL4 -v jvnr8t jvnr8r
vptovf jvnr8t
For `jvnrc8t', do
ttf2tfm verdana -T T1-WGL4 -V jvnrc8t jvnr8r
vptovf jvnrc8t
Note that almost always some warnings will appear about missing
glyphs.
The last line written to stdout by ttf2tfm is a suitable entry for
ttfonts.map -- since ttf2pk doesn't care about virtual fonts, both
calls below produce the same.
Now just repeat this procedure. For slanted fonts you should
additionally use the switch `-s 0.176' (of course you can change the
slanting amount to make it fit your needs).
Problems
========
Most vptovf implementations allow only 100 bytes for the TFM header
(the limit is 1024 in the TFM file itself): 8 bytes for checksum and
design size, 40 bytes for the family name, 20 bytes for the encoding,
and 4 bytes for a face byte. There remain only 28 bytes for some
additional information which is used by ttf2tfm for an identification
string (which is essentially a copy of the command line), and this
limit is always exceeded.
The optimal solution is to increase the value of `max_header_bytes' in
the file vptovf.w (and probably pltotf.w) to, say, 400 and recompile
vptovf (and pltotf). Otherwise you'll get some (harmless) error
messages like
This HEADER index is too big for my present table size
which can be safely ignored.
--- end of ttf2pk.doc ---

1095
contrib/ttf2pk/ttf2tfm.1 Normal file

File diff suppressed because it is too large Load Diff

885
contrib/ttf2pk/ttf2tfm.c Normal file
View File

@@ -0,0 +1,885 @@
/*
* ttf2tfm.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>.
*/
/*
* This program converts TTF files to TeX TFM files, and optionally
* to TeX VPL files that retain all kerning and ligature information.
* Both files make the characters not normally encoded by TeX available
* by character codes greater than 0x7F.
*/
/*
* Adapted from afm2tfm by F. Loyer <loyer@ensta.fr>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h> /* for size_t */
#include <string.h>
#include "ttf2tfm.h"
#include "newobj.h"
#include "ttfenc.h"
#include "ligkern.h"
#include "texenc.h"
#include "ttfaux.h"
#include "tfmaux.h"
#include "vplaux.h"
#include "errormsg.h"
#include "filesrch.h"
#include "parse.h"
#include "subfont.h"
char ident[] = "ttf2tfm version 1.3";
char progname[] = "ttf2tfm"; /* for error/warning messages */
/* command line options */
static char makevpl; /* can be 1 or 2 */
static Boolean pedantic;
static Boolean quiet;
static Boolean forceoctal;
/*
* Re-encode the TTF font.
*/
static void
handlereencoding(Font *fnt)
{
int i;
ttfinfo *ti;
char *p;
if (fnt->inencname)
{
fnt->inencoding = readencoding(&(fnt->inencname), fnt, True);
/* reset all pointers in the mapping table */
for (i = 0; i <= 0xFF; i++)
if (NULL != (ti = fnt->inencptrs[i]))
{
ti->incode = -1;
fnt->inencptrs[i] = NULL;
}
/*
* Reencode TTF <--> raw TeX. Only these code points will be used
* for the output encoding.
*/
for (i = 0; i <= 0xFF; i++)
{
p = fnt->inencoding->vec[i];
if (p && *p)
{
if ((ti = findadobe(p, fnt->charlist)))
{
if (ti->incode >= 0)
{
warning("Character `%s' encoded twice in input encoding\n"
" (positions %x and %x; the latter is ignored).",
p, ti->incode, i);
fnt->inencoding->vec[i] = ".notdef";
continue;
}
if (ti->charcode >= 0)
{
ti->incode = i;
fnt->inencptrs[i] = ti;
}
}
else
{
warning("Cannot find character `%s'\n"
" specified in input encoding.", p);
}
}
}
fnt->codingscheme = fnt->inencoding->name;
}
if (!quiet)
{
if (fnt->inencname)
printf("\nUsing %s as input encoding.\n", fnt->inencname);
else
{
printf(
"\nUsing the first 256 glyphs in the following input encoding:\n\n");
for (i = 0; i <= 0xFF; i++)
{
if ((ti = fnt->inencptrs[i]))
printf(" 0x%02x %s\n", i, ti->adobename);
}
printf("\n");
}
}
if (fnt->outencname)
fnt->outencoding = readencoding(&(fnt->outencname), fnt, False);
else
fnt->outencoding = readencoding(NULL, fnt, False);
}
static void
assignchars(Font *fnt)
{
register char **p;
register int i, j, k;
register ttfinfo *ti;
int nextfree = 0x80;
/*
* First, we assign all those that match perfectly.
*/
for (i = 0, p = fnt->outencoding->vec; i <= 0xFF; i++, p++)
if ((ti = findmappedadobe(*p, fnt->inencptrs)))
{
if (ti->outcode >= 0)
fnt->nextout[i] = ti->outcode; /* linked list */
ti->outcode = i;
fnt->outencptrs[i] = ti;
}
else if (strcmp(*p, ".notdef") != 0)
warning("Cannot map character `%s'\n"
" specified in output encoding.", *p);
if (pedantic)
goto end;
/*
* Next, we assign all the others, retaining the TTF code positions,
* possibly multiplying assigned characters, unless the output encoding
* was precisely specified.
*/
for (i = 0; i <= 0xFF; i++)
if ((ti = fnt->inencptrs[i]) &&
ti->charcode >= 0 && ti->charcode <= 0xFF &&
ti->outcode < 0 && fnt->outencptrs[ti->charcode] == NULL)
{
ti->outcode = ti->charcode;
fnt->outencptrs[ti->charcode] = ti;
}
/*
* Finally, we map all remaining characters into free locations beginning
* with 0x80.
*/
for (i = 0; i <= 0xFF; i++)
if ((ti = fnt->inencptrs[i]) && ti->outcode < 0)
{
while (fnt->outencptrs[nextfree])
{
nextfree = (nextfree + 1) & 0xFF;
if (nextfree == 0x80)
goto finishup; /* all slots full */
}
ti->outcode = nextfree;
fnt->outencptrs[nextfree] = ti;
}
finishup:
/*
* Now, if any of the characters are encoded multiple times, we want
* ti->outcode to be the first one assigned, since that is most likely
* to be the most important one. So we reverse the above lists.
*/
for (i = 0; i <= 0xFF; i++)
if ((ti = fnt->inencptrs[i]) && ti->outcode >= 0)
{
k = -1;
while (fnt->nextout[ti->outcode] >= 0)
{
j = fnt->nextout[ti->outcode];
fnt->nextout[ti->outcode] = k;
k = ti->outcode;
ti->outcode = j;
}
fnt->nextout[ti->outcode] = k;
}
end:
if (!quiet)
{
printf("\nUsing the following output encoding:\n\n");
for (i = 0; i <= 0xFF; i++)
{
if ((ti = fnt->outencptrs[i]))
printf(" 0x%02x %s\n", i, ti->adobename);
}
printf("\n");
}
}
#define VERSION "\
Copyright (C) 1997-1999 Frederic Loyer and Werner Lemberg.\n\
There is NO warranty. You may redistribute this software\n\
under the terms of the GNU General Public License\n\
and the Dvips copyright.\n\
\n\
For more information about these matters, see the files\n\
named COPYING and ttf2tfm.c.\n\
\n\
Primary authors of ttf2tfm: F. Loyer and W. Lemberg.\n\
\n\
ttf2tfm is based on afm2tfm from T. Rokicki\n\
and the FreeType project from\n\
David Turner, Robert Wilhelm, and Werner Lemberg.\n\
"
static void
version(void)
{
fputs(ident, stdout);
fprintf(stdout, " (%s)\n", TeX_search_version());
fputs(VERSION, stdout);
exit(0);
}
#define USAGE "\
Convert a TrueType font table to TeX's font metric format.\n\
\n\
-c REAL use REAL for height of small caps made with -V [0.8]\n\
-e REAL widen (extend) characters by a factor of REAL [1.0]\n\
-E INT select INT as the TTF encoding ID [1]\n\
-f INT select INT as the font index in a TTC [0]\n\
-l create 1st/2nd byte ligatures in subfonts\n\
-n use PS names of TrueType font\n\
-N use only PS names and no cmap\n\
-O use octal for all character codes in the vpl file\n\
-p ENCFILE[.enc] read ENCFILE for the TTF->raw TeX mapping\n\
-P INT select INT as the TTF platform ID [3]\n\
-q suppress informational output\n\
-r OLDNAME NEWNAME replace glyph name OLDNAME with NEWNAME\n\
-R RPLFILE[.rpl] read RPLFILE containing glyph replacement names\n\
-s REAL oblique (slant) characters by REAL, usually <<1 [0.0]\n\
-t ENCFILE[.enc] read ENCFILE for the encoding of the vpl file\n\
-T ENCFILE[.enc] equivalent to -p ENCFILE -t ENCFILE\n\
-u output only characters from encodings, nothing extra\n\
-v FILE[.vpl] make a VPL file for conversion to VF\n\
-V SCFILE[.vpl] like -v, but synthesize smallcaps as lowercase\n\
-x rotate subfont glyphs by 90 degrees\n\
-y REAL move rotated glyphs down by a factor of REAL [0.25]\n\
--help print this message and exit\n\
--version print version number and exit\n\
"
static void
usage(void)
{
fputs("Usage: ttf2tfm FILE[.ttf|.ttc] [OPTION]... [FILE[.tfm]]\n", stdout);
fputs(USAGE, stdout);
exit(0);
}
static void
handle_options(int argc, char *argv[], Font *fnt)
{
register int lastext;
register int i;
size_t l;
int arginc;
char *temp;
char c;
char *vpl_name = NULL;
Boolean have_capheight = 0;
Boolean have_sfd = 0;
int sfd_begin, postfix_begin;
int base_name;
stringlist* sl;
/* scan first whether the -q switch is set */
for (i = 1; i < argc; i++)
if (argv[i][0] == '-' && argv[i][1] == 'q')
quiet = True;
if (!quiet)
printf("This is %s\n", ident);
#if defined(MSDOS) || defined(OS2) || defined(ATARIST)
/* Make VPL file identical to that created under Unix */
fnt->titlebuf = (char *)mymalloc(strlen(progname) + strlen(argv[1]) +
1 + 1);
sprintf(fnt->titlebuf, "%s %s", progname, argv[1]);
#else
fnt->titlebuf = (char *)mymalloc(strlen(argv[0]) + strlen(argv[1]) +
1 + 1);
sprintf(fnt->titlebuf, "%s %s", argv[0], argv[1]);
#endif
/*
* TrueType font name.
*/
fnt->ttfname = newstring(argv[1]);
/*
* The other arguments. We delay the final processing of some switches
* until the tfm font name has been scanned -- if it contains two `@'s,
* many switches are ignored.
*/
while (argc > 2 && *argv[2] == '-')
{
arginc = 2;
i = argv[2][1];
switch (i)
{
case 'v':
makevpl = 1;
if (argc <= 3)
oops("Missing parameter for -v option.");
if (vpl_name)
free(vpl_name);
vpl_name = newstring(argv[3]);
handle_extension(&vpl_name, ".vpl");
break;
case 'V':
makevpl = 2;
if (argc <= 3)
oops("Missing parameter for -V option.");
if (vpl_name)
free(vpl_name);
vpl_name = newstring(argv[3]);
handle_extension(&vpl_name, ".vpl");
break;
case 'f':
if (argc <= 3)
oops("Missing parameter for -f option.");
if (sscanf(argv[3], "%lu", &(fnt->fontindex)) == 0)
oops("Invalid font index.");
fnt->fontindexparam = argv[3];
break;
case 'E':
if (argc <= 3)
oops("Missing parameter for -E option.");
if (sscanf(argv[3], "%hu", &(fnt->eid)) == 0)
oops("Invalid encoding ID.");
fnt->eidparam = argv[3];
break;
case 'P':
if (argc <= 3)
oops("Missing parameter for -P option.");
if (sscanf(argv[3], "%hu", &(fnt->pid)) == 0)
oops("Invalid platform ID.");
fnt->pidparam = argv[3];
break;
case 'e':
if (argc <= 3)
oops("Missing parameter for -e option.");
if (sscanf(argv[3], "%f", &(fnt->efactor)) == 0 || fnt->efactor < 0.01)
oops("Bad extension factor.");
fnt->efactorparam = argv[3];
break;
case 'c':
if (argc <= 3)
oops("Missing parameter for -c option.");
have_capheight = True;
if (sscanf(argv[3], "%f", &(fnt->capheight)) == 0)
fnt->capheight = 0;
break;
case 's':
if (argc <= 3)
oops("Missing parameter for -s option.");
if (sscanf(argv[3], "%f", &(fnt->slant)) == 0)
oops("Bad slant parameter.");
fnt->slantparam = argv[3];
break;
case 'p':
if (argc <= 3)
oops("Missing parameter for -p option.");
if (fnt->inencname)
free(fnt->inencname);
fnt->inencname = newstring(argv[3]);
break;
case 'T':
if (argc <= 3)
oops("Missing parameter for -T option.");
if (fnt->inencname)
free(fnt->inencname);
if (fnt->outencname)
free(fnt->outencname);
fnt->inencname = newstring(argv[3]);
fnt->outencname = newstring(argv[3]);
break;
case 't':
if (argc <= 3)
oops("Missing parameter for -T option.");
if (fnt->outencname)
free(fnt->outencname);
fnt->outencname = newstring(argv[3]);
break;
case 'r':
if (argc <= 4)
oops("Not enough parameters for -r option.");
sl = newstringlist();
sl->old_name = newstring(argv[3]);
sl->new_name = newstring(argv[4]);
sl->single_replacement = True;
sl->next = fnt->replacements;
fnt->replacements = sl;
arginc = 3;
break;
case 'R':
if (argc <= 3)
oops("Missing parameter for -R option.");
if (fnt->replacementname)
free(fnt->replacementname);
fnt->replacementname = newstring(argv[3]);
break;
case 'y':
if (argc <= 3)
oops("Missing parameter for -y option.");
if (sscanf(argv[3], "%f", &(fnt->y_offset)) == 0)
oops("Invalid y-offset.");
fnt->y_offsetparam = argv[3];
break;
case 'O':
forceoctal = True;
arginc = 1;
break;
case 'n':
fnt->PSnames = Yes;
arginc = 1;
break;
case 'N':
fnt->PSnames = Only;
arginc = 1;
break;
case 'u':
pedantic = True;
arginc = 1;
break;
case 'q':
quiet = True;
arginc = 1;
break;
case 'l':
fnt->subfont_ligs = True;
arginc = 1;
break;
case 'x':
fnt->rotate = True;
arginc = 1;
break;
default:
if (argc <= 3 || argv[3][0] == '-')
{
warning("Unknown option `%s' will be ignored.\n", argv[2]);
arginc = 1;
}
else
warning("Unknown option `%s %s' will be ignored.\n",
argv[2], argv[3]);
}
for (i = 0; i < arginc; i++)
{
l = strlen(fnt->titlebuf);
fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf,
l + strlen(argv[2]) + 1 + 1);
sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]);
argv++;
argc--;
}
}
/* Read replacement glyph name file */
get_replacements(fnt);
if (argc > 3 || (argc == 3 && *argv[2] == '-'))
oops("Need at most two non-option arguments.");
/*
* The tfm file name.
*/
if (argc == 2)
temp = newstring(fnt->ttfname);
else
{
temp = newstring(argv[2]);
l = strlen(fnt->titlebuf);
fnt->titlebuf = (char *)myrealloc((void *)fnt->titlebuf,
l + strlen(argv[2]) + 1 + 1);
sprintf(fnt->titlebuf + strlen(fnt->titlebuf), " %s", argv[2]);
}
handle_sfd(temp, &sfd_begin, &postfix_begin);
if (sfd_begin > -1)
{
have_sfd = True;
i = sfd_begin - 2;
}
else
i = strlen(temp) - 1;
/*
* Now we search the beginning of the name without directory.
*/
for (; i >= 0; i--)
if (temp[i] == '/' || temp[i] == ':' || temp[i] == '\\')
break;
base_name = i + 1;
/*
* We store the path (with the final directory separator).
*/
if (base_name > 0)
{
c = temp[base_name];
temp[base_name] = '\0';
fnt->tfm_path = newstring(temp);
temp[base_name] = c;
}
if (have_sfd)
{
/* the prefix and the sfd file name */
if (temp[base_name])
fnt->outname = newstring(temp + base_name);
fnt->sfdname = newstring(temp + sfd_begin);
}
else
postfix_begin = base_name;
/*
* Get the extension.
*/
lastext = -1;
for (i = postfix_begin; temp[i]; i++)
if (temp[i] == '.')
lastext = i;
if (argc == 2 && lastext >= 0)
{
temp[lastext] = '\0'; /* remove TTF file extension */
lastext = -1;
}
if (lastext == -1)
fnt->tfm_ext = newstring(".tfm");
else
{
fnt->tfm_ext = newstring(temp + lastext);
temp[lastext] = '\0';
}
if (have_sfd)
{
if (temp[postfix_begin])
fnt->outname_postfix = newstring(temp + postfix_begin);
}
else
{
if (temp[base_name])
fnt->outname = newstring(temp + base_name);
else
oops("Invalid tfm file name.");
}
/*
* Now we can process the remaining parameters.
*/
if (have_sfd)
{
if (makevpl)
{
warning("Ignoring `-v' and `-V' switches for subfonts.");
makevpl = 0;
}
if (have_capheight)
warning("Ignoring `-c' switch for subfonts.");
if (fnt->inencname || fnt->outencname)
{
warning("Ignoring `-p', `-t', and `-T' switches for subfonts.");
fnt->inencname = NULL;
fnt->outencname = NULL;
}
if (fnt->y_offsetparam && !fnt->rotate)
warning("Ignoring `-y' switch for non-rotated subfonts.");
if (fnt->PSnames)
{
warning("Ignoring `-n' or '-N' switch for subfonts.");
fnt->PSnames = No;
}
init_sfd(fnt, True);
}
else
{
if (have_capheight && fnt->capheight < 0.01)
oops("Bad small caps height.");
if (vpl_name)
if ((fnt->vplout = fopen(vpl_name, "wt")) == NULL)
oops("Cannot open vpl output file.");
if (fnt->subfont_ligs)
{
warning("Ignoring `-l' switch for non-subfont.");
fnt->subfont_ligs = False;
}
if (fnt->rotate)
{
warning("Ignoring `-x' switch for non-subfont.");
fnt->rotate = False;
}
if (fnt->y_offsetparam)
warning("Ignoring `-y' switch for non-subfont.");
}
if (fnt->PSnames == Only)
{
if (fnt->pidparam || fnt->eidparam)
{
warning("Ignoring `-P' and `-E' options if `-N' switch is selected.");
fnt->pidparam = NULL;
fnt->eidparam = NULL;
}
}
if (vpl_name)
free(vpl_name);
free(temp);
}
/*
* This routine prints out the line that needs to be added to ttfonts.map.
*/
static void
consttfonts(Font *fnt)
{
if (!quiet)
printf("\n");
if (fnt->outname)
printf("%s", fnt->outname);
if (fnt->sfdname)
printf("@%s@", fnt->sfdname);
if (fnt->outname_postfix)
printf("%s", fnt->outname_postfix);
printf(" %s", fnt->ttfname);
if (fnt->slantparam || fnt->efactorparam ||
fnt->inencname ||
fnt->pidparam || fnt->eidparam ||
fnt->fontindexparam ||
fnt->replacements ||
fnt->replacementname ||
fnt->PSnames ||
fnt->rotate || fnt->y_offsetparam)
{
if (fnt->slantparam)
printf(" Slant=%s", fnt->slantparam);
if (fnt->efactorparam)
printf(" Extend=%s", fnt->efactorparam);
if (fnt->inencname)
printf(" Encoding=%s", fnt->inencname);
if (fnt->pidparam)
printf(" Pid=%s", fnt->pidparam);
if (fnt->eidparam)
printf(" Eid=%s", fnt->eidparam);
if (fnt->fontindexparam)
printf(" Fontindex=%s", fnt->fontindexparam);
if (fnt->PSnames)
printf(" PS=%s", fnt->PSnames == Yes ? "Yes" : "Only");
if (fnt->rotate)
printf(" Rotate=Yes");
if (fnt->y_offsetparam)
printf(" Y-Offset=%s", fnt->y_offsetparam);
if (fnt->replacementname && fnt->inencoding)
printf(" Replacement=%s", fnt->replacementname);
if (fnt->replacements && fnt->inencoding)
{
stringlist *sl;
for (sl = fnt->replacements; sl; sl = sl->next)
if (sl->single_replacement)
printf(" %s=%s", sl->old_name, sl->new_name);
}
}
printf("\n");
}
int
main(int argc, char *argv[])
{
Font font;
ttfinfo *ti;
init_font_structure(&font);
TeX_search_init(argv[0], "ttf2tfm", "TTF2TFM");
if (argc == 1)
{
fputs("ttf2tfm: Need at least one file argument.\n", stderr);
fputs("Try `ttf2tfm --help' for more information.\n", stderr);
exit(1);
}
if (argc == 2)
{
if (strcmp(argv[1], "--help") == 0)
usage();
else if (strcmp(argv[1], "--version") == 0)
version();
}
handle_options(argc, argv, &font);
if (font.sfdname)
{
while (get_sfd(&font))
{
char *temp;
int i, start, end, len;
get_tfm_fullname(&font);
/*
* Extract base name of sfd file.
*/
temp = newstring(font.sfdname);
len = strlen(temp);
start = 0;
for (i = len - 1; i >= 0; i--)
if (temp[i] == '/' || temp[i] == ':' || temp[i] == '\\')
{
start = i + 1;
break;
}
end = len;
for (i = len - 1; i >= 0; i--)
if (temp[i] == '.')
{
end = i;
break;
}
temp[end] = '\0';
font.codingscheme = (char *)mymalloc(strlen(temp + start) + 4 + 1);
sprintf(font.codingscheme, "CJK-%s", temp + start);
free(temp);
readttf(&font, quiet, True);
if (font.replacements)
warning("Replacement glyphs will be ignored.");
if (NULL != (ti = findadobe("space", font.charlist)))
font.fontspace = ti->width;
else if (NULL != (ti = findadobe(".c0x20", font.charlist)))
font.fontspace = ti->width;
else
font.fontspace = transform(500, 0, font.efactor, font.slant);
if (buildtfm(&font))
writetfm(&font);
}
close_sfd();
}
else
{
get_tfm_fullname(&font);
readttf(&font, quiet, False);
replace_glyphs(&font);
if (NULL != (ti = findadobe("space", font.charlist)))
font.fontspace = ti->width;
else if (NULL != (ti = findadobe(".c0x20", font.charlist)))
font.fontspace = ti->width;
else
font.fontspace = transform(500, 0, font.efactor, font.slant);
handlereencoding(&font);
buildtfm(&font);
writetfm(&font);
}
if (makevpl)
{
assignchars(&font);
if (makevpl > 1)
upmap(&font);
writevpl(&font, makevpl, forceoctal);
fclose(font.vplout);
}
consttfonts(&font);
exit(0); /* for safety reasons */
return 0; /* never reached */
}
/* end */

234
contrib/ttf2pk/ttf2tfm.h Normal file
View File

@@ -0,0 +1,234 @@
/*
* ttf2tfm.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef TTF2TFM_H
#define TTF2TFM_H
#include <stdio.h>
enum Boolean_
{
False = 0,
True = 1
};
typedef enum Boolean_ Boolean;
enum PSstate_
{
No = 0,
Yes = 1,
Only = 2
};
typedef enum PSstate_ PSstate;
struct _encoding
{
char *name;
char *vec[256];
};
typedef struct _encoding encoding;
/*
* This is what we store character data in.
*/
struct _ttfinfo;
typedef struct _ttfinfo ttfinfo;
struct _lig;
typedef struct _lig lig;
struct _kern;
typedef struct _kern kern;
struct _ttfptr;
typedef struct _ttfptr ttfptr;
struct _pcc;
typedef struct _pcc pcc;
struct _stringlist;
typedef struct _stringlist stringlist;
struct _ttfinfo
{
ttfinfo *next;
long charcode; /* the TTF character code (or glyph index */
/* if bit 17 is set) */
unsigned short glyphindex; /* the TTF glyph number */
short incode; /* the code position in the raw TeX font */
short outcode; /* the code position in the virtual font */
char *adobename;
short width;
short llx, lly, urx, ury;
lig *ligs;
kern *kerns;
ttfptr *kern_equivs;
Boolean constructed;
pcc *pccs; /* we use the composite feature for */
/* `germandbls' <--> `SS' only */
unsigned char wptr, hptr, dptr, iptr;
};
struct _lig
{
lig *next;
char *succ, *sub;
short op, boundleft;
};
struct _kern
{
kern *next;
char *succ;
short delta;
};
struct _ttfptr
{
ttfptr *next;
ttfinfo *ch;
};
struct _pcc
{
pcc *next;
char *partname;
short xoffset, yoffset;
};
struct _stringlist
{
stringlist* next;
char *old_name;
char *new_name;
Boolean single_replacement;
};
struct _Font
{
char *ttfname;
/*
* Full path and extension of the tfm file
*/
char *tfm_path;
char *tfm_ext;
/*
* The final tfm name is composed of the following three parts.
*/
char *outname; /* only namestem without extension */
char *subfont_name; /* NULL if not used */
char *outname_postfix; /* NULL if not used */
char *fullname; /* outname + subfont_name + outname_postfix */
FILE *vplout;
FILE *tfmout;
/*
* The input encoding maps from the TrueType font to the raw TeX font.
*/
char *inencname; /* name of input encoding file */
encoding *inencoding; /* the input encoding vector */
ttfinfo *inencptrs[256]; /* the input mapping table. Will be
filled initially with the first
256 characters in the selected
cmap of the TrueType font */
stringlist *replacements; /* replacements for glyph names given
with the -r option on the command
line */
char *replacementname; /* name of replacement file */
/*
* The output encoding maps from the raw TeX font to the virtual font.
*/
char *outencname; /* name of output encoding file */
encoding *outencoding; /* the output encoding vector */
ttfinfo *outencptrs[256]; /* the output mapping table */
short nextout[256]; /* for characters encoded multiple times
in output */
Boolean sawligkern; /* there were LIGKERN lines in the
output encoding file */
Boolean subfont_ligs; /* ligatures 1st byte/2nd byte in
subfonts wanted */
ttfinfo *charlist; /* a linked list of all valid chars */
ttfinfo *uppercase[256]; /* needed for small caps fonts */
ttfinfo *lowercase[256]; /* ditto */
short boundarychar; /* the boundary character */
char *codingscheme; /* coding scheme for TeX */
char *titlebuf;
/*
* The name of the subfont definition file.
*/
char *sfdname;
long sf_code[256];
/*
* We get the following three values from the TTF's postscript table.
*/
short units_per_em;
float italicangle;
char fixedpitch;
short xheight; /* xheight for TeX */
short fontspace; /* font space for TeX */
/*
* These values can be specified on the command line.
*/
unsigned short pid; /* the TTF platform ID */
unsigned short eid; /* the TTF encoding ID */
float efactor; /* to extend the glyphs horizontally */
float slant; /* to slant the font */
unsigned long fontindex; /* font number in TTC */
float capheight; /* the height of small caps glyphs */
PSstate PSnames; /* we use the PS names in the TTF */
Boolean rotate; /* we rotate the glyphs by 90 degrees */
float y_offset; /* y offset for rotated glyphs */
/*
* The command line parameter strings needed for ttf2pk.
*/
char *pidparam;
char *eidparam;
char *efactorparam;
char *slantparam;
char *fontindexparam;
char *y_offsetparam;
};
typedef struct _Font Font;
#endif /* TEX2TFM_H */
/* end */

714
contrib/ttf2pk/ttfaux.c Normal file
View File

@@ -0,0 +1,714 @@
/*
* ttfaux.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "freetype.h"
#include "extend/ftxkern.h" /* we are in the FreeType package tree */
#include "extend/ftxpost.h"
#include "extend/ftxopen.h"
#include "ttf2tfm.h"
#include "newobj.h"
#include "ligkern.h"
#include "ttfenc.h"
#include "tfmaux.h"
#include "errormsg.h"
#include "ttfaux.h"
#include "filesrch.h"
#define Macintosh_platform 1
#define Macintosh_encoding 0
#define Microsoft_platform 3
#define Microsoft_Unicode_encoding 1
#define SCRIPT_kana MAKE_TT_TAG('k', 'a', 'n', 'a')
#define SCRIPT_hani MAKE_TT_TAG('h', 'a', 'n', 'i')
#define SCRIPT_hang MAKE_TT_TAG('h', 'a', 'n', 'g')
#define LANGUAGE_JAN MAKE_TT_TAG('J', 'A', 'N', ' ')
#define LANGUAGE_CHN MAKE_TT_TAG('C', 'H', 'N', ' ')
#define LANGUAGE_KOR MAKE_TT_TAG('K', 'O', 'R', ' ')
#define FEATURE_vert MAKE_TT_TAG('v', 'e', 'r', 't')
extern char progname[];
char *real_ttfname;
TT_Engine engine;
TT_Face face;
TT_Instance instance;
TT_Glyph glyph;
TT_Outline outline;
TT_CharMap char_map;
TT_Matrix matrix1, matrix2;
TT_Big_Glyph_Metrics metrics;
TT_Face_Properties properties;
TT_BBox bbox;
TT_Kerning directory;
TT_Post post;
TTO_GSUBHeader gsub_;
TTO_GSUBHeader *gsub;
Boolean has_gsub;
static void
readttf_kern(Font *fnt)
{
register kern *nk;
register ttfinfo *ti;
TT_Kern_0_Pair* pairs0;
TT_Error error;
unsigned int i, j;
if ((error = TT_Get_Kerning_Directory(face, &directory)))
oops("Cannot get kerning directory (error code = 0x%x).", error);
if (directory.nTables == 0)
return;
for (i = 0; i < directory.nTables; i++)
{
if ((error = TT_Load_Kerning_Table(face, i)))
oops("Cannot load kerning table (error code = 0x%x).", error);
switch (directory.tables[i].format)
{
case 0:
pairs0 = directory.tables[i].t.kern0.pairs;
for (j = 0; j < directory.tables[i].t.kern0.nPairs; j++, pairs0++)
{
ti = findglyph(pairs0->left, fnt->charlist);
if (ti == NULL)
warning("kern char not found");
else
{
nk = newkern();
nk->succ = findglyph(pairs0->right, fnt->charlist)->adobename;
nk->delta = transform(pairs0->value * 1000 / fnt->units_per_em, 0,
fnt->efactor, fnt->slant);
nk->next = ti->kerns;
ti->kerns = nk;
}
}
return; /* we stop after the first format 0 kerning table */
default:
break;
}
}
return;
}
void
readttf(Font *fnt, Boolean quiet, Boolean only_range)
{
TT_Error error;
ttfinfo *ti, *Ti;
long Num, index;
unsigned int i, j;
long k, max_k;
unsigned short num_cmap;
unsigned short cmap_plat, cmap_enc;
int index_array[257];
static Boolean initialized = False;
TT_UShort in_string[2];
TTO_GSUB_String in, out;
TT_UShort script_index, language_index, feature_index;
TT_UShort req_feature_index = 0xFFFF;
/*
* We allocate a placeholder boundary and the `.notdef' character.
*/
if (!only_range)
{
ti = newchar(fnt);
ti->charcode = -1;
ti->adobename = ".notdef";
ti = newchar(fnt);
ti->charcode = -1;
ti->adobename = "||"; /* boundary character name */
}
/*
* Initialize FreeType engine.
*/
if (!initialized)
{
if ((error = TT_Init_FreeType(&engine)))
oops("Cannot initialize engine (error code = 0x%x).", error);
if ((error = TT_Init_Kerning_Extension(engine)))
oops("Cannot initialize kerning (error code = 0x%x).", error);
if (fnt->PSnames)
if ((error = TT_Init_Post_Extension(engine)))
oops("Cannot initialize PS name support (error code = 0x%x).", error);
if (fnt->rotate)
if ((error = TT_Init_GSUB_Extension(engine)))
oops("Cannot initialize GSUB support (error code = 0x%x).", error);
/*
* Load face.
*/
real_ttfname = TeX_search_ttf_file(&(fnt->ttfname));
if (!real_ttfname)
oops("Cannot find `%s'.", fnt->ttfname);
if ((error = TT_Open_Face(engine, real_ttfname, &face)))
oops("Cannot open `%s'.", real_ttfname);
/*
* Get face properties and allocate preload arrays.
*/
TT_Get_Face_Properties(face, &properties);
/*
* Now we try to open the proper font in a collection.
*/
if (fnt->fontindex != 0)
{
if (properties.num_Faces == 1)
{
warning("This isn't a TrueType collection.\n"
"Parameter `-f' is ignored.");
fnt->fontindex = 0;
fnt->fontindexparam = NULL;
}
else
{
TT_Close_Face(face);
if ((error = TT_Open_Collection(engine, real_ttfname,
fnt->fontindex, &face)))
oops("Cannot open font %lu in TrueType Collection `%s'.",
fnt->fontindex, real_ttfname);
}
}
/*
* Create instance.
*/
if ((error = TT_New_Instance(face, &instance)))
oops("Cannot create instance for `%s' (error code = 0x%x).",
real_ttfname, error);
/*
* We use a dummy glyph size of 10pt.
*/
if ((error = TT_Set_Instance_CharSize(instance, 10 * 64)))
oops("Cannot set character size (error code = 0x%x).", error);
matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1L<<16)/1024);
matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1L<<16)/1024);
matrix1.yx = (TT_Fixed)0;
matrix1.yy = (TT_Fixed)(1L<<16);
if (fnt->rotate)
{
matrix2.xx = 0;
matrix2.yx = 1L << 16;
matrix2.xy = -matrix2.yx;
matrix2.yy = matrix2.xx;
}
if ((error = TT_Set_Instance_Transform_Flags(
instance,
fnt->rotate ? 1 : 0,
fnt->efactor != 1.0 ? 1 : 0)))
oops("Cannot set transform flags (error code = 0x%x).", error);
/*
* Create glyph container.
*/
if ((error = TT_New_Glyph(face, &glyph)))
oops("Cannot create glyph container (error code = 0x%x).", error);
fnt->units_per_em = properties.header->Units_Per_EM;
fnt->fixedpitch = properties.postscript->isFixedPitch;
fnt->italicangle = properties.postscript->italicAngle / 65536.0;
if (fnt->PSnames != Only)
{
num_cmap = properties.num_CharMaps;
for (i = 0; i < num_cmap; i++)
{
if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc)))
oops("Cannot query cmap (error code = 0x%x).", error);
if (cmap_plat == fnt->pid && cmap_enc == fnt->eid)
break;
}
if (i == num_cmap)
{
fprintf(stderr, "%s: ERROR: Invalid platform and/or encoding ID.\n",
progname);
if (num_cmap == 1)
fprintf(stderr, " The only valid PID/EID pair is");
else
fprintf(stderr, " Valid PID/EID pairs are:\n");
for (i = 0; i < num_cmap; i++)
{
TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc);
fprintf(stderr, " (%i,%i)\n", cmap_plat, cmap_enc);
}
fprintf(stderr, "\n");
exit(1);
}
if ((error = TT_Get_CharMap(face, i, &char_map)))
oops("Cannot load cmap (error code = 0x%x).", error);
}
if (fnt->PSnames)
{
if ((error = TT_Load_PS_Names(face, &post)))
oops("Cannot load TrueType PS names (error code = 0x%x).", error);
}
else if (cmap_plat == Microsoft_platform &&
cmap_enc == Microsoft_Unicode_encoding)
set_encoding_scheme(encUnicode, fnt);
else if (cmap_plat == Macintosh_platform &&
cmap_enc == Macintosh_encoding)
set_encoding_scheme(encMac, fnt);
else
set_encoding_scheme(encFontSpecific, fnt);
if (fnt->rotate)
{
gsub = &gsub_;
error = TT_Load_GSUB_Table(face, gsub, NULL);
if (!error)
has_gsub = True;
else if (error != TT_Err_Table_Missing)
warning("Cannot load GSUB table (error code = 0x%x).", error);
else
warning("No GSUB data available "
"for vertical glyph presentation forms.");
/* we check for the `vert' feature in Chinese, Japanese, and Korean */
error = TT_GSUB_Select_Script(gsub,
SCRIPT_kana,
&script_index);
if (error)
goto check_hani;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
0xFFFF,
&feature_index);
if (error)
{
error = TT_GSUB_Select_Language(gsub,
LANGUAGE_JAN,
script_index,
&language_index,
&req_feature_index);
if (error)
goto check_hani;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
language_index,
&feature_index);
if (error)
goto check_hani;
else
goto Done;
}
else
goto Done;
check_hani:
error = TT_GSUB_Select_Script(gsub,
SCRIPT_hani,
&script_index);
if (error)
goto check_hang;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
0xFFFF,
&feature_index);
if (error)
{
error = TT_GSUB_Select_Language(gsub,
LANGUAGE_CHN,
script_index,
&language_index,
&req_feature_index);
if (error)
goto check_hang;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
language_index,
&feature_index);
if (error)
goto check_hang;
else
goto Done;
}
else
goto Done;
check_hang:
error = TT_GSUB_Select_Script(gsub,
SCRIPT_hang,
&script_index);
if (error)
goto Done;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
0xFFFF,
&feature_index);
if (error)
{
error = TT_GSUB_Select_Language(gsub,
LANGUAGE_KOR,
script_index,
&language_index,
&req_feature_index);
if (error)
goto Done;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
language_index,
&feature_index);
}
Done:
if (error)
{
warning("There is no data for vertical typesetting in GSUB table.");
has_gsub = False;
}
if (req_feature_index != 0xFFFF)
TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS);
TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS);
in.length = 1;
in.pos = 0;
in.string = in_string;
in.properties = NULL;
out.pos = 0;
out.allocated = 0;
out.string = NULL;
out.properties = NULL;
}
initialized = True;
}
if (!quiet)
{
if (only_range)
printf("\n\n%s:\n", fnt->fullname);
printf("\n");
printf("Glyph Code Glyph Name ");
printf("Width llx lly urx ury\n");
printf("---------------------------------------");
printf("---------------------------------\n");
}
/*
* We load only glyphs with a valid cmap entry. Nevertheless, for
* the default mapping, we use the first 256 glyphs addressed by
* ascending code points, followed by glyphs not in the cmap.
*
* If we compute a range, we take the character codes given in
* the fnt->sf_code array.
*
* If the -N flag is set, no cmap is used at all. Instead, the
* first 256 glyphs (with a valid PS name) are used for the default
* mapping.
*/
if (!only_range)
for (i = 0; i < 257; i++)
index_array[i] = 0;
else
for (i = 0; i < 256; i++)
fnt->inencptrs[i] = 0;
j = 0;
if (fnt->PSnames == Only)
max_k = properties.num_Glyphs - 1;
else
max_k = only_range ? 0xFF : 0xFFFF;
for (k = 0; k <= max_k; k++)
{
char *an;
if (fnt->PSnames != Only)
{
if (only_range)
{
index = fnt->sf_code[k];
if (index < 0)
continue;
j = k;
}
else
index = k;
Num = TT_Char_Index(char_map, index);
/* now we try to get a vertical glyph form */
if (has_gsub)
{
in_string[0] = Num;
error = TT_GSUB_Apply_String(gsub, &in, &out);
if (error && error != TTO_Err_Not_Covered)
warning("Cannot get the vertical glyph form for glyph index %d.",
Num);
else
Num = out.string[0];
}
if (Num < 0)
oops("Failure on cmap mapping from %s.", fnt->ttfname);
if (Num == 0)
continue;
if (!only_range)
if (Num <= 256)
index_array[Num] = 1;
}
else
{
Num = k;
index = 0;
}
error = TT_Load_Glyph(instance, glyph, Num, 0);
if (!error)
error = TT_Get_Glyph_Big_Metrics(glyph, &metrics);
if (!error)
error = TT_Get_Glyph_Outline(glyph, &outline);
if (!error)
{
if (fnt->efactor != 1.0 || fnt->slant != 0.0 )
TT_Transform_Outline(&outline, &matrix1);
if (fnt->rotate)
TT_Transform_Outline(&outline, &matrix2);
}
if (!error)
error = TT_Get_Outline_BBox(&outline, &bbox); /* we need the non-
grid-fitted bbox */
if (!error)
{
if (fnt->PSnames)
(void)TT_Get_PS_Name(face, Num, &an);
else
an = code_to_adobename(index);
/* ignore characters not usable for typesetting with TeX */
if (strcmp(an, ".notdef") == 0)
continue;
if (strcmp(an, ".null") == 0)
continue;
if (strcmp(an, "nonmarkingreturn") == 0)
continue;
ti = newchar(fnt);
ti->charcode = index;
ti->glyphindex = Num;
ti->adobename = an;
ti->llx = bbox.xMin * 1000 / fnt->units_per_em;
ti->lly = bbox.yMin * 1000 / fnt->units_per_em;
ti->urx = bbox.xMax * 1000 / fnt->units_per_em;
ti->ury = bbox.yMax * 1000 / fnt->units_per_em;
/*
* We must now shift the rotated character both horizontally
* and vertically. The vertical amount is 25% by default.
*/
if (fnt->rotate)
{
ti->llx += (metrics.vertBearingY - bbox.xMin) *
1000 / fnt->units_per_em;
ti->lly -= 1000 * fnt->y_offset;
ti->urx += (metrics.vertBearingY - bbox.xMin) *
1000 / fnt->units_per_em;
ti->ury -= 1000 * fnt->y_offset;
}
/*
* We need to avoid negative heights or depths. They break accents
* in math mode, among other things.
*/
if (ti->lly > 0)
ti->lly = 0;
if (ti->ury < 0)
ti->ury = 0;
if (fnt->rotate)
ti->width = metrics.vertAdvance * 1000 / fnt->units_per_em;
else
ti->width = transform(metrics.horiAdvance * 1000 / fnt->units_per_em,
0, fnt->efactor, fnt->slant);
if (!quiet)
printf("%5ld %04lx %-25s %5d % 5d,% 5d -- % 5d,% 5d\n",
Num, index, ti->adobename,
ti->width,
ti->llx, ti->lly, ti->urx, ti->ury);
if (j < 256)
{
fnt->inencptrs[j] = ti;
ti->incode = j;
}
j++;
}
}
/*
* Now we load glyphs without a cmap entry, provided some slots are
* still free -- we skip this if we have to compute a range or use
* PS names.
*/
if (!only_range && !fnt->PSnames)
{
for (i = 1; i <= properties.num_Glyphs; i++)
{
char *an;
if (index_array[i] == 0)
{
error = TT_Load_Glyph(instance, glyph, i, 0);
if (!error)
error = TT_Get_Glyph_Big_Metrics(glyph, &metrics);
if (!error)
error = TT_Get_Glyph_Outline(glyph, &outline);
if (!error)
error = TT_Get_Outline_BBox(&outline, &bbox);
if (!error)
{
an = code_to_adobename(i | 0x10000);
ti = newchar(fnt);
ti->charcode = i | 0x10000;
ti->glyphindex = i;
ti->adobename = an;
ti->llx = bbox.xMin * 1000 / fnt->units_per_em;
ti->lly = bbox.yMin * 1000 / fnt->units_per_em;
ti->urx = bbox.xMax * 1000 / fnt->units_per_em;
ti->ury = bbox.yMax * 1000 / fnt->units_per_em;
if (ti->lly > 0)
ti->lly = 0;
if (ti->ury < 0)
ti->ury = 0;
ti->width = transform(metrics.horiAdvance*1000 / fnt->units_per_em,
0, fnt->efactor, fnt->slant);
if (!quiet)
printf("%5d %-25s %5d % 5d,% 5d -- % 5d,% 5d\n",
i, ti->adobename,
ti->width,
ti->llx, ti->lly, ti->urx, ti->ury);
if (j < 256)
{
fnt->inencptrs[j] = ti;
ti->incode = j;
}
else
break;
j++;
}
}
}
}
/* Finally, we construct a `Germandbls' glyph if necessary */
if (!only_range)
{
if (NULL == findadobe("Germandbls", fnt->charlist) &&
NULL != (Ti = findadobe("S", fnt->charlist)))
{
pcc *np, *nq;
ti = newchar(fnt);
ti->charcode = properties.num_Glyphs | 0x10000;
ti->glyphindex = properties.num_Glyphs;
ti->adobename = "Germandbls";
ti->width = Ti->width << 1;
ti->llx = Ti->llx;
ti->lly = Ti->lly;
ti->urx = Ti->width + Ti->urx;
ti->ury = Ti->ury;
ti->kerns = Ti->kerns;
np = newpcc();
np->partname = "S";
nq = newpcc();
nq->partname = "S";
nq->xoffset = Ti->width;
np->next = nq;
ti->pccs = np;
ti->constructed = True;
if (!quiet)
printf("* %-25s %5d % 5d,% 5d -- % 5d,% 5d\n",
ti->adobename,
ti->width,
ti->llx, ti->lly, ti->urx, ti->ury);
}
}
/* kerning between subfonts isn't available */
if (!only_range)
readttf_kern(fnt);
}
/* end */

21
contrib/ttf2pk/ttfaux.h Normal file
View File

@@ -0,0 +1,21 @@
/*
* ttfaux.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef TTFAUX_H
#define TTFAUX_H
#include "ttf2tfm.h"
void readttf(Font *fnt, Boolean quiet, Boolean only_range);
#endif /* TTFAUX_H */
/* end */

1281
contrib/ttf2pk/ttfenc.c Normal file

File diff suppressed because it is too large Load Diff

41
contrib/ttf2pk/ttfenc.h Normal file
View File

@@ -0,0 +1,41 @@
/*
* ttfenc.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef TTFENC_H
#define TTFENC_H
#include "ttf2tfm.h"
enum _EncodingScheme
{
encUnicode,
encMac,
encFontSpecific
};
typedef enum _EncodingScheme EncodingScheme;
void set_encoding_scheme(EncodingScheme e, Font *fnt);
char *code_to_adobename(long code);
long adobename_to_code(char *s);
ttfinfo *findglyph(unsigned short g, ttfinfo *p);
ttfinfo *findadobe(char *p, ttfinfo *ap);
ttfinfo *findmappedadobe(char *p, ttfinfo **array);
void replace_glyphs(Font *fnt);
void restore_glyph(encoding *enc, Font *fnt);
#endif /* TTFENC_H */
/* end */

703
contrib/ttf2pk/ttflib.c Normal file
View File

@@ -0,0 +1,703 @@
/*
* ttflib.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Loyer Frederic <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h> /* libc ANSI */
#include <ctype.h>
#include "pklib.h" /* for the `byte' type */
#include "freetype.h"
#include "ttfenc.h"
#include "ttflib.h"
#include "errormsg.h"
#include "newobj.h"
#include "ttf2tfm.h"
#include "extend/ftxpost.h"
#include "extend/ftxopen.h"
#define Macintosh_platform 1
#define Macintosh_encoding 0
#define Microsoft_platform 3
#define Microsoft_Symbol_encoding 0
#define Microsoft_Unicode_encoding 1
#define SCRIPT_kana MAKE_TT_TAG('k', 'a', 'n', 'a')
#define SCRIPT_hani MAKE_TT_TAG('h', 'a', 'n', 'i')
#define SCRIPT_hang MAKE_TT_TAG('h', 'a', 'n', 'g')
#define LANGUAGE_JAN MAKE_TT_TAG('J', 'A', 'N', ' ')
#define LANGUAGE_CHN MAKE_TT_TAG('C', 'H', 'N', ' ')
#define LANGUAGE_KOR MAKE_TT_TAG('K', 'O', 'R', ' ')
#define FEATURE_vert MAKE_TT_TAG('v', 'e', 'r', 't')
TT_Engine engine;
TT_Face face;
TT_Instance instance;
TT_Glyph glyph;
TT_CharMap char_map;
TT_Outline outline;
TT_Face_Properties properties;
TT_BBox bbox;
TT_Post post;
TT_Raster_Map Bit, Bit2;
void *Bitp, *Bit2p;
int dpi;
int ptsize;
int x_offset, y_offset;
int ppem;
TT_Big_Glyph_Metrics metrics;
TT_Matrix matrix1, matrix2;
TTO_GSUBHeader gsub_;
TTO_GSUBHeader *gsub;
TT_UShort in_string[2];
TTO_GSUB_String in, out;
Boolean has_gsub;
static void
SetRasterArea(int quiet)
{
int temp1_x, temp1_y, temp2_x, temp2_y;
temp1_x = bbox.xMin / 64; /* scaling F16.6 -> int */
temp1_y = bbox.yMin / 64;
temp2_x = (bbox.xMax + 63) / 64;
temp2_y = (bbox.yMax + 63) / 64;
x_offset = 5 - temp1_x;
y_offset = 5 - temp1_y;
if (!quiet)
printf(" off = (%d, %d)", x_offset, y_offset);
#if 0
x_offset = y_offset = 0;
#endif
if (!quiet)
printf(" bbox = (%d, %d) <-> (%d, %d)\n",
temp1_x, temp1_y, temp2_x, temp2_y);
Bit.rows = temp2_y - temp1_y + 10;
Bit.width = temp2_x - temp1_x + 10;
Bit.cols = (Bit.width + 7) / 8; /* convert to # of bytes */
Bit.flow = TT_Flow_Up;
Bit.size = Bit.rows * Bit.cols; /* number of bytes in buffer */
/*
* We allocate one more row to have valid pointers for comparison
* purposes in pklib.c, making `gcc -fbounds-checking' happy.
*/
if (Bitp)
free(Bitp);
Bitp = mymalloc(Bit.size + Bit.cols);
Bit.bitmap = Bitp;
Bit2 = Bit;
if (Bit2p)
free(Bit2p);
Bit2p = mymalloc(Bit.size + Bit.cols);
Bit2.bitmap = Bit2p;
}
static void
FlipBit(void)
{
int y;
char *p1, *p2;
p1 = (char *)Bit.bitmap;
p2 = (char *)Bit2.bitmap + Bit2.cols * (Bit2.rows - 1);
for (y = 0; y < Bit.rows; y++)
{
memcpy(p2, p1, Bit.cols);
p1 += Bit.cols;
p2 -= Bit.cols;
}
}
#if 0
static void
Output(TT_Raster_Map Bit)
{
int x;
int y;
int i;
char *p, b;
p = Bit.bitmap;
printf("====\n");
for (y = 0; y < Bit.rows; y++)
{
printf("%3d:", y);
for (x = 0; x < Bit.cols; x++)
{
b = *p++;
for(i = 0x80; i; i >>= 1)
printf((b & i) ? "x" : ".");
}
printf("\n");
}
}
#endif /* 0 */
void
TTFopen(char *filename, Font *fnt, int new_dpi, int new_ptsize, Boolean quiet)
{
unsigned short i, num_cmap;
unsigned short cmap_plat;
unsigned short cmap_enc;
TT_Error error;
TT_UShort script_index, language_index, feature_index;
TT_UShort req_feature_index = 0xFFFF;
dpi = new_dpi;
ptsize = new_ptsize;
if ((error = TT_Init_FreeType(&engine)))
oops("Cannot initialize FreeType engine (error code = 0x%x).", error);
if (fnt->PSnames)
if ((error = TT_Init_Post_Extension(engine)))
oops("Cannot initialize PS name support (error code = 0x%x).", error);
if (fnt->rotate)
if ((error = TT_Init_GSUB_Extension(engine)))
oops("Cannot initialize GSUB support (error code = 0x%x).", error);
/*
* Load face.
*/
error = TT_Open_Face(engine, filename, &face);
if (error)
oops("Cannot open `%s'.", filename);
/*
* Get face properties and allocate preloaded arrays.
*/
TT_Get_Face_Properties(face, &properties);
/*
* Now we try to open the proper font in a collection.
*/
if (fnt->fontindex != 0)
{
if (properties.num_Faces == 1)
warning("This isn't a TrueType collection.\n"
"Parameter `Fontindex' is ignored.");
else
{
TT_Close_Face(face);
if ((error = TT_Open_Collection(engine, filename,
fnt->fontindex, &face)))
oops("Cannot open font %lu in TrueType Collection `%s'.",
fnt->fontindex, filename);
}
}
/*
* Create instance.
*/
if ((error = TT_New_Instance(face, &instance)))
oops("Cannot create instance for `%s' (error code = 0x%x).",
filename, error);
if ((error = TT_Set_Instance_Resolutions(instance, dpi, dpi)))
oops("Cannot set device resolutions (error code = 0x%x).");
if ((error = TT_Set_Instance_CharSize(instance, ptsize * 64)))
oops("Cannot set character size (error code = 0x%x).", error);
ppem = (dpi * ptsize + 36) / 72;
if (!quiet)
printf("dpi = %d, ptsize = %d, ppem = %d\n\n", dpi, ptsize, ppem);
matrix1.xx = (TT_Fixed)(floor(fnt->efactor * 1024) * (1<<16)/1024);
matrix1.xy = (TT_Fixed)(floor(fnt->slant * 1024) * (1<<16)/1024);
matrix1.yx = (TT_Fixed)0;
matrix1.yy = (TT_Fixed)(1<<16);
if (fnt->rotate)
{
matrix2.xx = 0;
matrix2.yx = 1L << 16;
matrix2.xy = -matrix2.yx;
matrix2.yy = matrix2.xx;
}
if ((error = TT_Set_Instance_Transform_Flags(
instance,
fnt->rotate ? 1 : 0,
fnt->efactor != 1.0 ? 1 : 0)))
oops("Cannot set transform flags (error code = 0x%x).", error);
/*
* Create glyph container.
*/
if ((error = TT_New_Glyph(face, &glyph)))
oops("Cannot create glyph container (error code = 0x%x).");
if (fnt->PSnames != Only)
{
num_cmap = properties.num_CharMaps;
for (i = 0; i < num_cmap; i++)
{
if ((error = TT_Get_CharMap_ID(face, i, &cmap_plat, &cmap_enc)))
oops("Cannot query cmap (error code = 0x%x).", error);
if (cmap_plat == fnt->pid && cmap_enc == fnt->eid)
break;
}
if (i == num_cmap)
oops("Invalid platform and/or encoding ID.");
if ((error = TT_Get_CharMap(face, i, &char_map)))
oops("Cannot load cmap (error code = 0x%x).", error);
}
if (fnt->PSnames)
{
if ((error = TT_Load_PS_Names(face, &post)))
oops("Cannot load TrueType PS names (error code = 0x%x).", error);
}
else if (cmap_plat == Microsoft_platform &&
cmap_enc == Microsoft_Unicode_encoding)
set_encoding_scheme(encUnicode, fnt);
else if (cmap_plat == Macintosh_platform &&
cmap_enc == Macintosh_encoding)
set_encoding_scheme(encMac, fnt);
else
set_encoding_scheme(encFontSpecific, fnt);
if (fnt->rotate)
{
gsub = &gsub_;
error = TT_Load_GSUB_Table(face, gsub, NULL);
if (!error)
has_gsub = True;
else if (error != TT_Err_Table_Missing)
warning("Cannot load GSUB table (error code = 0x%x).", error);
else
warning("No GSUB data available "
"for vertical glyph presentation forms.");
/* we check for the `vert' feature in Chinese, Japanese, and Korean */
error = TT_GSUB_Select_Script(gsub,
SCRIPT_kana,
&script_index);
if (error)
goto check_hani;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
0xFFFF,
&feature_index);
if (error)
{
error = TT_GSUB_Select_Language(gsub,
LANGUAGE_JAN,
script_index,
&language_index,
&req_feature_index);
if (error)
goto check_hani;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
language_index,
&feature_index);
if (error)
goto check_hani;
else
goto Done;
}
else
goto Done;
check_hani:
error = TT_GSUB_Select_Script(gsub,
SCRIPT_hani,
&script_index);
if (error)
goto check_hang;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
0xFFFF,
&feature_index);
if (error)
{
error = TT_GSUB_Select_Language(gsub,
LANGUAGE_CHN,
script_index,
&language_index,
&req_feature_index);
if (error)
goto check_hang;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
language_index,
&feature_index);
if (error)
goto check_hang;
else
goto Done;
}
else
goto Done;
check_hang:
error = TT_GSUB_Select_Script(gsub,
SCRIPT_hang,
&script_index);
if (error)
goto Done;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
0xFFFF,
&feature_index);
if (error)
{
error = TT_GSUB_Select_Language(gsub,
LANGUAGE_KOR,
script_index,
&language_index,
&req_feature_index);
if (error)
goto Done;
error = TT_GSUB_Select_Feature(gsub,
FEATURE_vert,
script_index,
language_index,
&feature_index);
}
Done:
if (error)
{
warning("There is no data for vertical typesetting in GSUB table.");
has_gsub = False;
}
if (req_feature_index != 0xFFFF)
TT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS);
TT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS);
in.length = 1;
in.pos = 0;
in.string = in_string;
in.properties = NULL;
out.pos = 0;
out.allocated = 0;
out.string = NULL;
out.properties = NULL;
}
}
static TT_Error
LoadTrueTypeChar(Font *fnt,
int idx,
Boolean hint,
Boolean quiet)
{
TT_Error error;
int flags;
flags = TTLOAD_SCALE_GLYPH;
if (hint)
flags |= TTLOAD_HINT_GLYPH;
error = TT_Load_Glyph(instance, glyph, idx, flags);
if (!error)
error = TT_Get_Glyph_Big_Metrics(glyph, &metrics);
if (!error)
error = TT_Get_Glyph_Outline(glyph, &outline);
if (!error)
{
if (fnt->efactor != 1.0 || fnt->slant != 0.0 )
TT_Transform_Outline(&outline, &matrix1);
if (fnt->rotate)
TT_Transform_Outline(&outline, &matrix2);
}
if (!error)
error = TT_Get_Outline_BBox(&outline, &bbox); /* we need the non-
grid-fitted bbox */
if (fnt->rotate)
TT_Translate_Outline(&outline,
metrics.vertBearingY - bbox.xMin,
-fnt->y_offset * ppem * 64);
if (!error)
error = TT_Get_Outline_BBox(&outline, &bbox);
if (!error)
SetRasterArea(quiet);
return error;
}
Boolean
TTFprocess(Font *fnt,
long Code,
byte **bitmap,
int *width, int *height,
int *hoff, int *voff,
Boolean hinting,
Boolean quiet)
{
int Num;
TT_Error error;
if (!bitmap || !width || !height || !hoff || !voff)
oops("Invalid parameter in call to TTFprocess()");
if (Code >= 0x10000)
Num = Code & 0xFFFF;
else
{
Num = TT_Char_Index(char_map, Code);
if (has_gsub)
{
in_string[0] = Num;
error = TT_GSUB_Apply_String(gsub, &in, &out);
if (error && error != TTO_Err_Not_Covered)
warning("Cannot get the vertical glyph form for glyph index %d.",
Num);
else
Num = out.string[0];
}
}
if ((error = LoadTrueTypeChar(fnt, Num, hinting, quiet)) == TT_Err_Ok)
{
memset(Bit.bitmap, 0, Bit.size);
TT_Get_Glyph_Bitmap(glyph, &Bit, x_offset * 64, y_offset * 64);
FlipBit();
*bitmap = Bit2.bitmap;
*width = Bit2.width;
*height = Bit2.rows;
*hoff = x_offset;
*voff = y_offset;
/* *voff = Bit2.rows - y_offset; */
/* printf("%D %d\n", *hoff, *voff); */
/* Output(Bit2); */
return True;
}
else
return False;
}
/*
* We collect first all glyphs addressed via the cmap. Then we fill the
* array up with glyphs not in the cmap.
*
* If PSnames is set to `Only', we get the first 256 glyphs which have
* names different from `.notdef', `.null', and `nonmarkingreturn'.
*
* For nicer output, we return the glyph names in an encoding array.
*/
encoding *
TTFget_first_glyphs(Font *fnt, long *array)
{
unsigned int i, j, Num;
unsigned int index_array[257]; /* we ignore glyph index 0 */
char *n;
encoding *e = (encoding *)mymalloc(sizeof (encoding));
if (!array)
oops("Invalid parameter in call to TTFget_first_glyphs()");
for (i = 0; i < 257; i++)
index_array[i] = 0;
j = 0;
if (fnt->PSnames != Only)
{
for (i = 0; i <= 0xFFFF; i++)
{
Num = TT_Char_Index(char_map, i);
if (Num < 0)
oops("cmap mapping failure.");
if (Num == 0)
continue;
if (Num <= 256)
index_array[Num] = 1;
if (fnt->PSnames)
(void)TT_Get_PS_Name(face, Num, &n);
else
n = code_to_adobename(i);
if (strcmp(n, ".notdef") == 0)
continue;
if (strcmp(n, ".null") == 0)
continue;
if (strcmp(n, "nonmarkingreturn") == 0)
continue;
if (j < 256)
{
array[j] = i;
e->vec[j] = n;
}
else
return e;
j++;
}
if (!fnt->PSnames)
{
for (i = 1; i < properties.num_Glyphs; i++)
{
if (index_array[i] == 0)
{
if (j < 256)
{
array[j] = i | 0x10000;
e->vec[j] = code_to_adobename(i | 0x10000);
}
else
return e;
j++;
}
}
}
}
else
{
for (i = 0; i < properties.num_Glyphs; i++)
{
char *n;
(void)TT_Get_PS_Name(face, i, &n);
if (strcmp(n, ".notdef") == 0)
continue;
if (strcmp(n, ".null") == 0)
continue;
if (strcmp(n, "nonmarkingreturn") == 0)
continue;
if (j < 256)
{
array[j] = i | 0x10000;
e->vec[j] = n;
}
else
return e;
j++;
}
}
return NULL; /* never reached */
}
/*
* This routine fills `array' with the subfont character codes;
* additionally, it tests for valid glyph indices.
*/
void
TTFget_subfont(Font *fnt, long *array)
{
int i, j, Num;
if (!fnt || !array)
oops("Invalid parameter in call to TTFget_subfont()");
for (i = 0; i <= 0xFF; i++)
{
j = fnt->sf_code[i];
if (j < 0)
array[i] = j;
else
{
Num = TT_Char_Index(char_map, j);
if (Num < 0)
oops("cmap mapping failure.");
else
array[i] = j;
}
}
}
long
TTFsearch_PS_name(char *name)
{
unsigned int i;
char *n;
for (i = 0; i < properties.num_Glyphs; i++)
{
TT_Get_PS_Name(face, i, &n);
if (strcmp(name, n) == 0)
break;
}
if (i == properties.num_Glyphs)
return -1L;
else
return (long)i;
}
/* end */

31
contrib/ttf2pk/ttflib.h Normal file
View File

@@ -0,0 +1,31 @@
/*
* ttflib.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef TTFLIB_H
#define TTFLIB_H
#include "pklib.h" /* for the `byte' type */
void TTFopen(char *filename, Font *fnt, int new_dpi, int new_ptsize,
Boolean quiet);
Boolean TTFprocess(Font *fnt, long Code, byte **bitmap,
int *width, int *height, int *hoff, int *voff,
Boolean hinting, Boolean quiet);
encoding *TTFget_first_glyphs(Font *fnt, long *array);
void TTFget_subfont(Font *fnt, long *array);
long TTFsearch_PS_name(char *name);
#endif /* TTFLIB_H */
/* end */

588
contrib/ttf2pk/vplaux.c Normal file
View File

@@ -0,0 +1,588 @@
/*
* vplaux.c
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "ttf2tfm.h"
#include "newobj.h"
#include "ttfenc.h"
#include "texenc.h"
#include "tfmaux.h"
#include "vplaux.h"
#include "errormsg.h"
#include "case.h"
#undef PI
#define PI 3.14159265358979323846264338327
#define vout(s) fprintf(out, s)
#define voutln(str) {fprintf(out, "%s\n", str); vlevout(level);}
#define voutln2(f, s) {fprintf(out, f, s); vlevnlout(level);}
#define voutln3(f, a, b) {fprintf(out, f, a, b); vlevnlout(level);}
#define voutln4(f, a, b, c) {fprintf(out, f, a, b, c); vlevnlout(level);}
static char vcharbuf[6];
static char vnamebuf[100];
/* the depth of parenthesis nesting in VPL file being written */
static int level;
static FILE *out;
static void
vlevout(register int l)
{
while (l--)
vout(" ");
}
static void
vlevnlout(int level)
{
vout("\n");
vlevout(level);
}
static void
vleft(int *levelp)
{
(*levelp)++;
vout("(");
}
static void
vright(int *levelp)
{
(*levelp)--;
voutln(")");
}
static char *
vchar(int c,
char *buf,
Boolean forceoctal)
{
if (forceoctal == 0 && isalnum(c))
(void)sprintf(buf, "C %c", c);
else
(void)sprintf(buf, "O %o", (unsigned)c);
return buf;
}
static char *
vname(int c,
char *buf,
ttfinfo **array,
Boolean forceoctal)
{
if (!forceoctal && isalnum(c))
buf[0] = '\0';
else
sprintf(buf, " (comment %s)", array[c]->adobename);
return buf;
}
static int
texheight(register ttfinfo *ti,
ttfinfo *ac,
int xh)
{
register char **p;
register ttfinfo *aci, *acci;
char buffer[200];
if (xh <= 50 || *(ti->adobename + 1))
return ti->ury; /* that was the simple case */
for (p = accents; *p; p++) /* otherwise we look for accented letters. */
/* We even check glyphs not in any encoding */
if (NULL != (aci = findadobe(*p, ac)))
{
strcpy(buffer, ti->adobename);
strcat(buffer, *p);
if (NULL != (acci = findadobe(buffer, ac)))
return acci->ury - aci->ury + xh;
}
return ti->ury;
}
/*
* Compute uppercase mapping, when making a small caps font.
*/
void
upmap(Font *fnt)
{
register ttfinfo *ti, *Ti;
register char *p, *q;
register pcc *np, *nq;
int i, j;
char lwr[50];
for (Ti = fnt->charlist; Ti; Ti = Ti->next)
{
p = Ti->adobename;
if (isupper(*p))
{
q = lwr;
for (; *p; p++)
*q++ = tolower(*p);
*q = '\0';
if (NULL != (ti = findmappedadobe(lwr, fnt->inencptrs)))
{
for (i = ti->outcode; i >= 0; i = fnt->nextout[i])
fnt->uppercase[i] = Ti;
for (i = Ti->outcode; i >= 0; i = fnt->nextout[i])
fnt->lowercase[i] = ti;
}
}
}
/*
* Note that, contrary to the normal true/false conventions,
* uppercase[i] is NULL and lowercase[i] is non-NULL when `i' is the
* ASCII code of an uppercase letter; and vice versa for lowercase
* letters.
*/
if (NULL != (ti = findmappedadobe("germandbls", fnt->inencptrs)))
if (NULL != (Ti = findmappedadobe("S", fnt->inencptrs)))
/* we also construct SS */
{
for (i = ti->outcode; i >= 0; i = fnt->nextout[i])
fnt->uppercase[i] = ti;
ti->incode = -1;
ti->width = Ti->width << 1;
ti->llx = Ti->llx;
ti->lly = Ti->lly;
ti->urx = Ti->width + Ti->urx;
ti->ury = Ti->ury;
ti->kerns = Ti->kerns;
np = newpcc();
np->partname = "S";
nq = newpcc();
nq->partname = "S";
nq->xoffset = Ti->width;
np->next = nq;
ti->pccs = np;
ti->constructed = True;
}
for (i = 0; casetable[i].upper; i++)
{
if ((ti = findmappedadobe(casetable[i].lower, fnt->inencptrs)))
for (j = ti->outcode; j >= 0; j = fnt->nextout[j])
fnt->uppercase[j] = findmappedadobe(casetable[i].upper,
fnt->inencptrs);
}
}
/*
* The logic above seems to work well enough, but it leaves useless
* characters like `fi' and `fl' in the font if they were present
* initially, and it omits characters like `dotlessj' if they are
* absent initially.
*/
void
writevpl(Font *fnt, char makevpl, Boolean forceoctal)
{
register int i, j, k;
register ttfinfo *ti;
register lig *nlig;
register kern *nkern;
register pcc *npcc;
ttfinfo *asucc, *asub, *api;
ttfptr *kern_eq;
int xoff, yoff, ht;
int bc, ec;
char buf[200];
char header[256];
Boolean unlabeled;
float Slant;
out = fnt->vplout;
header[0] = '\0';
strncat(header, "Created by `", 12);
strncat(header, fnt->titlebuf, 255 - 12 - 1);
strncat(header, "'", 1);
voutln2("(VTITLE %s)", header);
voutln("(COMMENT Please change VTITLE if you edit this file)");
(void)sprintf(buf, "TeX-%s%s%s%s",
fnt->fullname,
(fnt->efactor == 1.0 ? "" : "-E"),
(fnt->slant == 0.0 ? "" : "-S"),
(makevpl == 1 ? "" : "-CSC"));
if (strlen(buf) > 19) /* too long, will retain first 9 and last 10 chars */
{
register char *p, *q;
for (p = &buf[9], q = &buf[strlen(buf)-10]; p < &buf[19];
p++, q++)
*p = *q;
buf[19] = '\0';
}
voutln2("(FAMILY %s)", buf);
{
char tbuf[300];
char *base_encoding = fnt->codingscheme;
if (strcmp(fnt->outencoding->name, base_encoding) == 0)
sprintf(tbuf, "%s", fnt->outencoding->name);
else
sprintf(tbuf, "%s + %s", base_encoding, fnt->outencoding->name);
if (strlen(tbuf) > 39)
{
warning("Coding scheme too long; shortening to 39 characters");
tbuf[39] = '\0';
}
voutln2("(CODINGSCHEME %s)", tbuf);
}
{
long t, sc;
char *s;
int n, pos;
s = header;
n = strlen(s);
t = ((long)n) << 24;
sc = 16;
pos = 18;
voutln(
"(COMMENT The following `HEADER' lines are equivalent to the string)");
voutln2("(COMMENT \"%s\")", header);
while (n > 0)
{
t |= ((long)(*(unsigned char *)s++)) << sc;
sc -= 8;
if (sc < 0)
{
voutln3("(HEADER D %d O %lo)", pos, t);
t = 0;
sc = 24;
pos++;
}
n--;
}
if (t)
voutln3("(HEADER D %d O %lo)", pos, t);
}
voutln("(DESIGNSIZE R 10.0)");
voutln("(DESIGNUNITS R 1000)");
voutln("(COMMENT DESIGNSIZE (1 em) IS IN POINTS)");
voutln("(COMMENT OTHER DIMENSIONS ARE MULTIPLES OF DESIGNSIZE/1000)");
#if 0
/* Let vptovf compute the checksum. */
voutln2("(CHECKSUM O %lo)", cksum ^ 0xFFFFFFFF);
#endif
if (fnt->boundarychar >= 0)
voutln2("(BOUNDARYCHAR O %lo)", (unsigned long)fnt->boundarychar);
vleft(&level);
voutln("FONTDIMEN");
Slant = fnt->slant - fnt->efactor * tan(fnt->italicangle * (PI / 180.0));
if (Slant)
voutln2("(SLANT R %f)", Slant);
voutln2("(SPACE D %d)", fnt->fontspace);
if (!fnt->fixedpitch)
{
voutln2("(STRETCH D %d)", transform(200, 0, fnt->efactor, fnt->slant));
voutln2("(SHRINK D %d)", transform(100, 0, fnt->efactor, fnt->slant));
}
voutln2("(XHEIGHT D %d)", fnt->xheight);
voutln2("(QUAD D %d)", transform(1000, 0, fnt->efactor, fnt->slant));
voutln2("(EXTRASPACE D %d)",
fnt->fixedpitch ? fnt->fontspace :
transform(111, 0, fnt->efactor, fnt->slant));
vright(&level);
vleft(&level);
voutln("MAPFONT D 0");
voutln2("(FONTNAME %s)", fnt->fullname);
#if 0
voutln2("(FONTCHECKSUM O %lo)", (unsigned long)cksum);
#endif
vright(&level);
if (makevpl > 1)
{
vleft(&level);
voutln("MAPFONT D 1");
voutln2("(FONTNAME %s)", fnt->fullname);
voutln2("(FONTAT D %d)", (int)(1000.0 * fnt->capheight + 0.5));
#if 0
voutln2("(FONTCHECKSUM O %lo)", (unsigned long)cksum);
#endif
vright(&level);
}
for (i = 0; i <= 0xFF && fnt->outencptrs[i] == NULL; i++)
;
bc = i;
for (i = 0xFF; i >= 0 && fnt->outencptrs[i] == NULL; i--)
;
ec = i;
vleft(&level);
voutln("LIGTABLE");
ti = findadobe("||", fnt->charlist);
unlabeled = True;
for (nlig = ti->ligs; nlig; nlig = nlig->next)
if (NULL != (asucc = findmappedadobe(nlig->succ, fnt->inencptrs)))
{
if (NULL != (asub = findmappedadobe(nlig->sub, fnt->inencptrs)))
if (asucc->outcode >= 0)
if (asub->outcode >= 0)
{
if (unlabeled)
{
voutln("(LABEL BOUNDARYCHAR)");
unlabeled = False;
}
for (j = asucc->outcode; j >= 0; j = fnt->nextout[j])
voutln4("(%s %s O %o)", vplligops[nlig->op],
vchar(j, vcharbuf, forceoctal),
(unsigned)asub->outcode);
}
}
if (!unlabeled)
voutln("(STOP)");
for (i = bc; i <= ec; i++)
if ((ti = fnt->outencptrs[i]) && ti->outcode == i)
{
unlabeled = True;
if (fnt->uppercase[i] == NULL)
/* omit ligatures from smallcap lowercase */
for (nlig = ti->ligs; nlig; nlig = nlig->next)
if (NULL != (asucc = findmappedadobe(nlig->succ, fnt->inencptrs)))
if (NULL != (asub = findmappedadobe(nlig->sub, fnt->inencptrs)))
if (asucc->outcode >= 0)
if (asub->outcode >= 0)
{
if (unlabeled)
{
for (j = ti->outcode; j >= 0; j = fnt->nextout[j])
voutln3("(LABEL %s)%s",
vchar(j, vcharbuf, forceoctal),
vname(j, vnamebuf,
fnt->outencptrs, forceoctal));
unlabeled = False;
}
for (j = asucc->outcode; j >= 0; j = fnt->nextout[j])
{
voutln4("(%s %s O %o)", vplligops[nlig->op],
vchar(j, vcharbuf, forceoctal),
(unsigned)asub->outcode);
if (nlig->boundleft)
break;
}
}
for (nkern = (fnt->uppercase[i] ? fnt->uppercase[i]->kerns : ti->kerns);
nkern; nkern=nkern->next)
if (NULL != (asucc = findmappedadobe(nkern->succ, fnt->inencptrs)))
for (j = asucc->outcode; j >= 0; j = fnt->nextout[j])
{
if (fnt->uppercase[j] == NULL)
{
if (unlabeled)
{
for (k = ti->outcode; k >= 0; k = fnt->nextout[k])
voutln3("(LABEL %s)%s",
vchar(k, vcharbuf, forceoctal),
vname(k, vnamebuf, fnt->outencptrs, forceoctal));
unlabeled = False;
}
/*
* If other characters have the same kerns as this
* one, output the label here. This makes the TFM
* file much smaller than if we output all the
* kerns again under a different label.
*/
for (kern_eq = ti->kern_equivs; kern_eq;
kern_eq = kern_eq->next)
{
k = kern_eq->ch->outcode;
if (k >= 0 && k <= 0xFF)
voutln3("(LABEL %s)%s",
vchar(k, vcharbuf, forceoctal),
vname(k, vnamebuf, fnt->outencptrs, forceoctal));
}
ti->kern_equivs = NULL; /* Only output those labels once. */
if (fnt->uppercase[i])
{
if (fnt->lowercase[j])
{
for (k = fnt->lowercase[j]->outcode; k >= 0;
k = fnt->nextout[k])
voutln4("(KRN %s R %.1f)%s",
vchar(k, vcharbuf, forceoctal),
fnt->capheight * nkern->delta,
vname(k, vnamebuf, fnt->outencptrs, forceoctal));
}
else
voutln4("(KRN %s R %.1f)%s",
vchar(j, vcharbuf, forceoctal),
fnt->capheight * nkern->delta,
vname(j, vnamebuf, fnt->outencptrs, forceoctal));
}
else
{
voutln4("(KRN %s R %d)%s",
vchar(j, vcharbuf, forceoctal),
nkern->delta,
vname(j, vnamebuf, fnt->outencptrs, forceoctal));
if (fnt->lowercase[j])
for (k = fnt->lowercase[j]->outcode; k >= 0;
k = fnt->nextout[k])
voutln4("(KRN %s R %.1f)%s",
vchar(k, vcharbuf, forceoctal),
fnt->capheight * nkern->delta,
vname(k, vnamebuf, fnt->outencptrs, forceoctal));
}
}
}
if (!unlabeled)
voutln("(STOP)");
}
vright(&level);
for (i = bc; i <= ec; i++)
if (NULL != (ti = fnt->outencptrs[i]))
{
vleft(&level);
fprintf(out, "CHARACTER %s%s\n ",
vchar(i, vcharbuf, forceoctal),
vname(i, vnamebuf, fnt->outencptrs, forceoctal));
if (fnt->uppercase[i])
{
ti = fnt->uppercase[i];
voutln2("(CHARWD R %.1f)", fnt->capheight * (ti->width));
if (0 != (ht = texheight(ti, fnt->charlist, fnt->xheight)))
voutln2("(CHARHT R %.1f)", fnt->capheight * ht);
if (ti->lly)
voutln2("(CHARDP R %.1f)", -fnt->capheight * ti->lly);
if (ti->urx > ti->width)
voutln2("(CHARIC R %.1f)", fnt->capheight * (ti->urx - ti->width));
}
else
{
voutln2("(CHARWD R %d)", ti->width);
if (0 != (ht = texheight(ti, fnt->charlist, fnt->xheight)))
voutln2("(CHARHT R %d)", ht);
if (ti->lly)
voutln2("(CHARDP R %d)", -ti->lly);
if (ti->urx > ti->width)
voutln2("(CHARIC R %d)", ti->urx - ti->width);
}
if (ti->incode != i || fnt->uppercase[i] || ti->constructed)
{
vleft(&level);
voutln("MAP");
if (fnt->uppercase[i])
voutln("(SELECTFONT D 1)");
if (ti->pccs && (ti->incode < 0 || ti->constructed))
{
xoff = 0;
yoff = 0;
for (npcc = ti->pccs; npcc; npcc = npcc->next)
if (NULL != (api = findmappedadobe(npcc->partname,
fnt->inencptrs)))
if (api->outcode >= 0)
{
if (npcc->xoffset != xoff)
{
if (fnt->uppercase[i])
{
voutln2("(MOVERIGHT R %.1f)",
fnt->capheight * (npcc->xoffset - xoff));
}
else
voutln2("(MOVERIGHT R %d)", npcc->xoffset - xoff);
xoff = npcc->xoffset;
}
if (npcc->yoffset != yoff)
{
if (fnt->uppercase[i])
{
voutln2("(MOVEUP R %.1f)",
fnt->capheight * (npcc->yoffset - yoff));
}
else
voutln2("(MOVEUP R %d)", npcc->yoffset - yoff);
yoff = npcc->yoffset;
}
voutln2("(SETCHAR O %o)", (unsigned)api->incode);
xoff += fnt->outencptrs[api->outcode]->width;
}
}
else
voutln2("(SETCHAR O %o)", (unsigned)ti->incode);
vright(&level);
}
vright(&level);
}
if (level)
oops("I forgot to match the parentheses.");
}
/* end */

23
contrib/ttf2pk/vplaux.h Normal file
View File

@@ -0,0 +1,23 @@
/*
* vplaux.h
*
* This file is part of the ttf2pk package.
*
* Copyright 1997-1999 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*/
#ifndef VPLAUX_H
#define VPLAUX_H
#include "ttf2tfm.h"
void writevpl(Font *fnt, char makevpl, Boolean forceoctal);
void upmap(Font *fnt);
#endif /* VPLAUX_H */
/* end */