summaryrefslogtreecommitdiff
path: root/Build/source/texk/ttfdump
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2011-12-01 13:24:38 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2011-12-01 13:24:38 +0000
commit3131715fb5bce44da6c7584315237731aa752eba (patch)
treeb4e748ed3b19d603c4ac1b29f33340c196003e0e /Build/source/texk/ttfdump
parent9417d53067c450b541cecd8c3ae224e5d17b8e54 (diff)
ttfdump: Added functionality
- do not segfault for fonts without loca table - allow cmap subtables with format 8, 10, 12, and 13 - handle GPOS and GSUB tables - additional tests git-svn-id: svn://tug.org/texlive/trunk@24713 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/ttfdump')
-rw-r--r--Build/source/texk/ttfdump/ChangeLog38
-rw-r--r--Build/source/texk/ttfdump/Makefile.am17
-rw-r--r--Build/source/texk/ttfdump/Makefile.in64
-rw-r--r--Build/source/texk/ttfdump/docs/ttfdump.116
-rw-r--r--Build/source/texk/ttfdump/include/gpos.h229
-rw-r--r--Build/source/texk/ttfdump/include/gsub.h134
-rw-r--r--Build/source/texk/ttfdump/include/loadtable.h36
-rw-r--r--Build/source/texk/ttfdump/include/otftables.h368
-rw-r--r--Build/source/texk/ttfdump/include/tables.h148
-rw-r--r--Build/source/texk/ttfdump/include/ttf.h6
-rw-r--r--Build/source/texk/ttfdump/include/ttfutil.h1
-rw-r--r--Build/source/texk/ttfdump/libttf/cmap.c1091
-rw-r--r--Build/source/texk/ttfdump/libttf/font.c18
-rw-r--r--Build/source/texk/ttfdump/libttf/glyf.c6
-rw-r--r--Build/source/texk/ttfdump/libttf/gpos.c971
-rw-r--r--Build/source/texk/ttfdump/libttf/gsub.c553
-rw-r--r--Build/source/texk/ttfdump/libttf/head.c14
-rw-r--r--Build/source/texk/ttfdump/libttf/hhea.c2
-rw-r--r--Build/source/texk/ttfdump/libttf/loca.c26
-rw-r--r--Build/source/texk/ttfdump/libttf/maxp.c2
-rw-r--r--Build/source/texk/ttfdump/libttf/otfcommon.c1074
-rw-r--r--Build/source/texk/ttfdump/libttf/ttfutil.c16
-rw-r--r--Build/source/texk/ttfdump/src/ttfdump.c41
-rw-r--r--Build/source/texk/ttfdump/tests/ttfdump.glyf54
-rw-r--r--Build/source/texk/ttfdump/tests/ttfdump.gpos47
-rw-r--r--Build/source/texk/ttfdump/tests/ttfdump.gsub35
-rw-r--r--Build/source/texk/ttfdump/tests/ttfdump.head44
-rwxr-xr-xBuild/source/texk/ttfdump/tests/ttfdump.test30
28 files changed, 4566 insertions, 515 deletions
diff --git a/Build/source/texk/ttfdump/ChangeLog b/Build/source/texk/ttfdump/ChangeLog
index a9cc2d5786c..9713680022a 100644
--- a/Build/source/texk/ttfdump/ChangeLog
+++ b/Build/source/texk/ttfdump/ChangeLog
@@ -1,3 +1,41 @@
+2011-12-01 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * include/gpos.h (new): GPOS table format.
+ * include/gsub.h (new): GSUB table format.
+ * include/otftables.h (new): OpenType common table formats.
+ * libttf/gpos.c (new): Load, print, and free GPOS table.
+ * libttf/gsub.c (new): Load, print, and free GSUB table.
+ * libttf/otfcommon.c (new): Handle common table formats.
+ * include/loadtable.h, include/tables.h, include/ttf.h,
+ libttf/font.c, src/ttfdump.c: Add GPOS and GSUB tables.
+ * Makefile.am (libttf_a_SOURCES): Add the new files.
+ * docs/ttfdump.1: Mention GPOS and GSUB tables.
+
+ * tests/ttfdump.test: Add tests for GPOS and GSUB tables.
+ * tests/ttfdump.{gpos,gsub} (new): Expected output.
+ * Makefile.am: Adapted.
+
+2011-11-21 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ Additional 'cmap' SubTable Formats.
+ * include/tables.h: Declare data structures for 'cmap' SubTable
+ Formats 8, 10, 12, 13, and 14.
+ * libttf/cmap.c: Separate Encoding Records from SubTables;
+ several Encodings may refer to the same SubTable.
+ Add support for SubTable Formats 8, 10, 12, 13, and 14.
+ FIXME: Format 14 is not yet implemented.
+ * include/loadtable.h, include/ttf.h, libttf/glyf.c: Adapted.
+
+2011-11-10 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * include/tables.h, libttf/head.c: Print created and modified.
+ * libttf/font.c: Index to location ('loca') table is optional.
+ * libttf/loca.c: Avoid segfault for missing 'loca' table.
+ * src/ttfdump.c: Avoid segfault for missing 'loca' table (do not
+ try to print glyphs). Print sfnt version.
+
+ * tests/ttfdump.test: Perform all sub-tests and report failed ones.
+
2011-11-08 Peter Breitenlohner <peb@mppmu.mpg.de>
Major update.
diff --git a/Build/source/texk/ttfdump/Makefile.am b/Build/source/texk/ttfdump/Makefile.am
index e5d7547ca8a..018623bc1d8 100644
--- a/Build/source/texk/ttfdump/Makefile.am
+++ b/Build/source/texk/ttfdump/Makefile.am
@@ -12,9 +12,12 @@ noinst_LIBRARIES = libttf.a
libttf_a_SOURCES = \
include/gcache.h \
+ include/gpos.h \
include/gstate.h \
+ include/gsub.h \
include/loadtable.h \
include/os2_P.h \
+ include/otftables.h \
include/protos.h \
include/tables.h \
include/ttc.h \
@@ -28,7 +31,9 @@ libttf_a_SOURCES = \
libttf/gasp.c \
libttf/gcache.c \
libttf/glyf.c \
+ libttf/gpos.c \
libttf/gstate.c \
+ libttf/gsub.c \
libttf/hdmx.c \
libttf/head.c \
libttf/hhea.c \
@@ -39,6 +44,7 @@ libttf_a_SOURCES = \
libttf/maxp.c \
libttf/name.c \
libttf/os2.c \
+ libttf/otfcommon.c \
libttf/pclt.c \
libttf/post.c \
libttf/prep.c \
@@ -78,8 +84,15 @@ TESTS = tests/ttfdump.test
EXTRA_DIST += $(TESTS)
DISTCLEANFILES =
## tests/ttfdump.test
-EXTRA_DIST += tests/FonetikaDaniaIwonaeRegular.ttf tests/ttfdump.glyf tests/ttfdump.head
-DISTCLEANFILES += FonetikaDaniaIwonaeRegular.ttf ttfdump.glyf ttfdump.head
+EXTRA_DIST += \
+ tests/FonetikaDaniaIwonaeRegular.ttf \
+ tests/ttfdump.glyf \
+ tests/ttfdump.gpos \
+ tests/ttfdump.gsub \
+ tests/ttfdump.head
+DISTCLEANFILES += \
+ FonetikaDaniaIwonaeRegular.ttf \
+ ttftest.*
## Not used
##
diff --git a/Build/source/texk/ttfdump/Makefile.in b/Build/source/texk/ttfdump/Makefile.in
index 28090ee782f..1ae5c003152 100644
--- a/Build/source/texk/ttfdump/Makefile.in
+++ b/Build/source/texk/ttfdump/Makefile.in
@@ -73,9 +73,10 @@ libttf_a_AR = $(AR) $(ARFLAGS)
libttf_a_LIBADD =
am_libttf_a_OBJECTS = cmap.$(OBJEXT) cvt.$(OBJEXT) disasm.$(OBJEXT) \
font.$(OBJEXT) fpgm.$(OBJEXT) gasp.$(OBJEXT) gcache.$(OBJEXT) \
- glyf.$(OBJEXT) gstate.$(OBJEXT) hdmx.$(OBJEXT) head.$(OBJEXT) \
- hhea.$(OBJEXT) hmtx.$(OBJEXT) kern.$(OBJEXT) loca.$(OBJEXT) \
- ltsh.$(OBJEXT) maxp.$(OBJEXT) name.$(OBJEXT) os2.$(OBJEXT) \
+ glyf.$(OBJEXT) gpos.$(OBJEXT) gstate.$(OBJEXT) gsub.$(OBJEXT) \
+ hdmx.$(OBJEXT) head.$(OBJEXT) hhea.$(OBJEXT) hmtx.$(OBJEXT) \
+ kern.$(OBJEXT) loca.$(OBJEXT) ltsh.$(OBJEXT) maxp.$(OBJEXT) \
+ name.$(OBJEXT) os2.$(OBJEXT) otfcommon.$(OBJEXT) \
pclt.$(OBJEXT) post.$(OBJEXT) prep.$(OBJEXT) \
tabledir.$(OBJEXT) ttc.$(OBJEXT) ttfread.$(OBJEXT) \
ttfutil.$(OBJEXT) vdmx.$(OBJEXT) vhea.$(OBJEXT) vmtx.$(OBJEXT)
@@ -262,9 +263,12 @@ AM_CFLAGS = $(WARNING_CFLAGS)
noinst_LIBRARIES = libttf.a
libttf_a_SOURCES = \
include/gcache.h \
+ include/gpos.h \
include/gstate.h \
+ include/gsub.h \
include/loadtable.h \
include/os2_P.h \
+ include/otftables.h \
include/protos.h \
include/tables.h \
include/ttc.h \
@@ -278,7 +282,9 @@ libttf_a_SOURCES = \
libttf/gasp.c \
libttf/gcache.c \
libttf/glyf.c \
+ libttf/gpos.c \
libttf/gstate.c \
+ libttf/gsub.c \
libttf/hdmx.c \
libttf/head.c \
libttf/hhea.c \
@@ -289,6 +295,7 @@ libttf_a_SOURCES = \
libttf/maxp.c \
libttf/name.c \
libttf/os2.c \
+ libttf/otfcommon.c \
libttf/pclt.c \
libttf/post.c \
libttf/prep.c \
@@ -303,13 +310,13 @@ libttf_a_SOURCES = \
EXTRA_DIST = libttf/fixed.c libttf/interp.c libttf/stack.c \
docs/ttfdump.dvi docs/ttfdump.html docs/ttfdump.ps $(TESTS) \
tests/FonetikaDaniaIwonaeRegular.ttf tests/ttfdump.glyf \
- tests/ttfdump.head ILX NOTE README.bg5
+ tests/ttfdump.gpos tests/ttfdump.gsub tests/ttfdump.head ILX \
+ NOTE README.bg5
ttfdump_SOURCES = src/ttfdump.c
LDADD = libttf.a
dist_man1_MANS = docs/ttfdump.1
TESTS = tests/ttfdump.test
-DISTCLEANFILES = FonetikaDaniaIwonaeRegular.ttf ttfdump.glyf \
- ttfdump.head
+DISTCLEANFILES = FonetikaDaniaIwonaeRegular.ttf ttftest.*
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -434,7 +441,9 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gasp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gcache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/glyf.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gpos.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gstate.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gsub.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdmx.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/head.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hhea.Po@am__quote@
@@ -445,6 +454,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maxp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/name.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/os2.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/otfcommon.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pclt.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/post.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prep.Po@am__quote@
@@ -590,6 +600,20 @@ glyf.obj: libttf/glyf.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o glyf.obj `if test -f 'libttf/glyf.c'; then $(CYGPATH_W) 'libttf/glyf.c'; else $(CYGPATH_W) '$(srcdir)/libttf/glyf.c'; fi`
+gpos.o: libttf/gpos.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpos.o -MD -MP -MF $(DEPDIR)/gpos.Tpo -c -o gpos.o `test -f 'libttf/gpos.c' || echo '$(srcdir)/'`libttf/gpos.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpos.Tpo $(DEPDIR)/gpos.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libttf/gpos.c' object='gpos.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpos.o `test -f 'libttf/gpos.c' || echo '$(srcdir)/'`libttf/gpos.c
+
+gpos.obj: libttf/gpos.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gpos.obj -MD -MP -MF $(DEPDIR)/gpos.Tpo -c -o gpos.obj `if test -f 'libttf/gpos.c'; then $(CYGPATH_W) 'libttf/gpos.c'; else $(CYGPATH_W) '$(srcdir)/libttf/gpos.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gpos.Tpo $(DEPDIR)/gpos.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libttf/gpos.c' object='gpos.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gpos.obj `if test -f 'libttf/gpos.c'; then $(CYGPATH_W) 'libttf/gpos.c'; else $(CYGPATH_W) '$(srcdir)/libttf/gpos.c'; fi`
+
gstate.o: libttf/gstate.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gstate.o -MD -MP -MF $(DEPDIR)/gstate.Tpo -c -o gstate.o `test -f 'libttf/gstate.c' || echo '$(srcdir)/'`libttf/gstate.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gstate.Tpo $(DEPDIR)/gstate.Po
@@ -604,6 +628,20 @@ gstate.obj: libttf/gstate.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gstate.obj `if test -f 'libttf/gstate.c'; then $(CYGPATH_W) 'libttf/gstate.c'; else $(CYGPATH_W) '$(srcdir)/libttf/gstate.c'; fi`
+gsub.o: libttf/gsub.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gsub.o -MD -MP -MF $(DEPDIR)/gsub.Tpo -c -o gsub.o `test -f 'libttf/gsub.c' || echo '$(srcdir)/'`libttf/gsub.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gsub.Tpo $(DEPDIR)/gsub.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libttf/gsub.c' object='gsub.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gsub.o `test -f 'libttf/gsub.c' || echo '$(srcdir)/'`libttf/gsub.c
+
+gsub.obj: libttf/gsub.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gsub.obj -MD -MP -MF $(DEPDIR)/gsub.Tpo -c -o gsub.obj `if test -f 'libttf/gsub.c'; then $(CYGPATH_W) 'libttf/gsub.c'; else $(CYGPATH_W) '$(srcdir)/libttf/gsub.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/gsub.Tpo $(DEPDIR)/gsub.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libttf/gsub.c' object='gsub.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gsub.obj `if test -f 'libttf/gsub.c'; then $(CYGPATH_W) 'libttf/gsub.c'; else $(CYGPATH_W) '$(srcdir)/libttf/gsub.c'; fi`
+
hdmx.o: libttf/hdmx.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT hdmx.o -MD -MP -MF $(DEPDIR)/hdmx.Tpo -c -o hdmx.o `test -f 'libttf/hdmx.c' || echo '$(srcdir)/'`libttf/hdmx.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/hdmx.Tpo $(DEPDIR)/hdmx.Po
@@ -744,6 +782,20 @@ os2.obj: libttf/os2.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o os2.obj `if test -f 'libttf/os2.c'; then $(CYGPATH_W) 'libttf/os2.c'; else $(CYGPATH_W) '$(srcdir)/libttf/os2.c'; fi`
+otfcommon.o: libttf/otfcommon.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT otfcommon.o -MD -MP -MF $(DEPDIR)/otfcommon.Tpo -c -o otfcommon.o `test -f 'libttf/otfcommon.c' || echo '$(srcdir)/'`libttf/otfcommon.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/otfcommon.Tpo $(DEPDIR)/otfcommon.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libttf/otfcommon.c' object='otfcommon.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o otfcommon.o `test -f 'libttf/otfcommon.c' || echo '$(srcdir)/'`libttf/otfcommon.c
+
+otfcommon.obj: libttf/otfcommon.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT otfcommon.obj -MD -MP -MF $(DEPDIR)/otfcommon.Tpo -c -o otfcommon.obj `if test -f 'libttf/otfcommon.c'; then $(CYGPATH_W) 'libttf/otfcommon.c'; else $(CYGPATH_W) '$(srcdir)/libttf/otfcommon.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/otfcommon.Tpo $(DEPDIR)/otfcommon.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libttf/otfcommon.c' object='otfcommon.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o otfcommon.obj `if test -f 'libttf/otfcommon.c'; then $(CYGPATH_W) 'libttf/otfcommon.c'; else $(CYGPATH_W) '$(srcdir)/libttf/otfcommon.c'; fi`
+
pclt.o: libttf/pclt.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT pclt.o -MD -MP -MF $(DEPDIR)/pclt.Tpo -c -o pclt.o `test -f 'libttf/pclt.c' || echo '$(srcdir)/'`libttf/pclt.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pclt.Tpo $(DEPDIR)/pclt.Po
diff --git a/Build/source/texk/ttfdump/docs/ttfdump.1 b/Build/source/texk/ttfdump/docs/ttfdump.1
index 45ce77ce811..f0d5e4cd4d8 100644
--- a/Build/source/texk/ttfdump/docs/ttfdump.1
+++ b/Build/source/texk/ttfdump/docs/ttfdump.1
@@ -1,4 +1,4 @@
-.TH TTFDUMP 1 "4 May 2011" "ILX Project"
+.TH TTFDUMP 1 "14 November 2011" "ILX Project"
.SH NAME
ttfdump \- Dumping the contents of a TrueType Font file
.SH SYNOPSIS
@@ -8,9 +8,9 @@ ttfdump \- Dumping the contents of a TrueType Font file
.IR tablename ]
.RB [ \-g
.IR glyphnumber ]
-.RB [\ -c
+.RB [ \-c
.IR collection ]
-.RB [\ -o
+.RB [ \-o
.IR dumpfile ]
.RB [ \-i ]
.I ttfile
@@ -18,7 +18,7 @@ ttfdump \- Dumping the contents of a TrueType Font file
\fBttfdump\fP dumps the contents of a TrueType font file in ASCII form.
A TrueType font file is consist of various tables. Those table are divided into
two categories - \fIRequired Tables\fP and \fIOptional Tables\fP. Mulitiple
-TrueType fonts and be merged to a TrueType Collection.
+TrueType fonts can be merged to a TrueType Collection.
.SS Options
.TP
\fB-h\fP
@@ -96,6 +96,14 @@ vertical metrics header
.TP
\fIvmtx\fP
vertical metrics
+.TP
+\fBAdditional OpenType Tables\fR
+.TP
+\fIGPOS\fP
+glyph positioning table
+.TP
+\fIGSUB\fP
+glyph substitution table
.RE
.TP
\fB-g\fI glyphnumber\fR
diff --git a/Build/source/texk/ttfdump/include/gpos.h b/Build/source/texk/ttfdump/include/gpos.h
new file mode 100644
index 00000000000..23e5bda0846
--- /dev/null
+++ b/Build/source/texk/ttfdump/include/gpos.h
@@ -0,0 +1,229 @@
+/* gpos.h -- define data structures for Glyph Positioning Table
+ */
+
+#ifndef __TTF_GPOS_H
+#define __TTF_GPOS_H
+
+/* ValueFormat Bits */
+#define ValueFormat_XPlacement 0x0001 << 0
+#define ValueFormat_YPlacement 0x0001 << 1
+#define ValueFormat_XAdvance 0x0001 << 2
+#define ValueFormat_YAdvance 0x0001 << 3
+#define ValueFormat_AllDesign 0x000f
+#define ValueFormat_XPlaDevice 0x0010 << 0
+#define ValueFormat_YPlaDevice 0x0010 << 1
+#define ValueFormat_XAdvDevice 0x0010 << 2
+#define ValueFormat_YAdvDevice 0x0010 << 3
+#define ValueFormat_AllDevice 0x00f0
+#define ValueFormat_Reserved 0xff00
+
+/* Positioning LookupType Values */
+#define PosLookup_SingleAdjustment 1
+#define PosLookup_PairAdjustment 2
+#define PosLookup_CursiveAttachment 3
+#define PosLookup_MarkToBaseAttachment 4
+#define PosLookup_MarkToLigatureAttachment 5
+#define PosLookup_MarkToMarkAttachment 6
+#define PosLookup_ContextPositioning 7
+#define PosLookup_ChainedContextPositioning 8
+#define PosLookup_ExtensionPositioning 9
+#define PosLookup_Max 9
+
+typedef struct
+{
+ SHORT valDesign[4];
+ DevicePtr valDevice[4];
+}
+ValueRecord, *ValueRecordPtr;
+
+typedef struct
+{
+ USHORT anchorFormat; /* = 1 */
+ SHORT xCoordinate;
+ SHORT yCoordinate;
+}
+Anchor1, *Anchor1Ptr;
+
+typedef struct
+{
+ USHORT anchorFormat; /* = 2 */
+ SHORT xCoordinate;
+ SHORT yCoordinate;
+ USHORT anchorPoint;
+}
+Anchor2, *Anchor2Ptr;
+
+typedef struct
+{
+ USHORT anchorFormat; /* = 3 */
+ SHORT xCoordinate;
+ SHORT yCoordinate;
+ DevicePtr xDevice;
+ DevicePtr yDevice;
+}
+Anchor3, *Anchor3Ptr;
+
+typedef union
+{
+ Anchor1Ptr anchor1;
+ Anchor2Ptr anchor2;
+ Anchor3Ptr anchor3;
+}
+AnchorPtr;
+
+typedef struct
+{
+ USHORT class;
+ AnchorPtr markAnchor;
+}
+MarkRecord, *MarkRecordPtr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 1 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr coverage;
+ USHORT valueFormat;
+ ValueRecordPtr value;
+}
+Pos11, *Pos11Ptr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 1 */
+ USHORT lookupFormat; /* = 2 */
+ CoveragePtr coverage;
+ USHORT valueFormat;
+ USHORT valueCount;
+ ValueRecordPtr *value; /* length = valueCount */
+}
+Pos12, *Pos12Ptr;
+
+typedef struct
+{
+ USHORT secondGlyph;
+ ValueRecordPtr value1;
+ ValueRecordPtr value2;
+}
+PairValueRecord, *PairValueRecordPtr;
+
+typedef struct
+{
+ USHORT pairValueCount;
+ PairValueRecordPtr pairValue; /* length = pairValueCount */
+}
+PairSet, *PairSetPtr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 2 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr coverage;
+ USHORT valueFormat1;
+ USHORT valueFormat2;
+ USHORT pairSetCount;
+ PairSetPtr pairSet; /* length = pairSetCount */
+}
+Pos21, *Pos21Ptr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 2 */
+ USHORT lookupFormat; /* = 2 */
+ CoveragePtr coverage;
+ USHORT valueFormat1;
+ USHORT valueFormat2;
+ ClassDefPtr classDef1;
+ ClassDefPtr classDef2;
+ USHORT class1Count;
+ USHORT class2Count;
+ ValueRecordPtr *values; /* length = 2 * class1Count * class2Count */
+}
+Pos22, *Pos22Ptr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 3 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr coverage;
+ USHORT entryExitCount;
+ AnchorPtr *entryExit; /* length = 2 * entryExitCount */
+}
+Pos31, *Pos31Ptr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 4 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr markCoverage;
+ CoveragePtr baseCoverage;
+ USHORT markCount;
+ USHORT baseCount;
+ USHORT classCount;
+ MarkRecordPtr markArray; /* length = markCount */
+ AnchorPtr *baseArray; /* length = baseCount * classCount */
+}
+Pos41, *Pos41Ptr;
+
+typedef struct
+{
+ USHORT componentCount;
+ AnchorPtr *componentRecord; /* length = componentCount * classCount */
+}
+LigatureAttach, *LigatureAttachPtr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 5 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr markCoverage;
+ CoveragePtr ligatureCoverage;
+ USHORT markCount;
+ USHORT ligatureCount;
+ USHORT classCount;
+ MarkRecordPtr markArray; /* length = markCount */
+ LigatureAttachPtr ligatureArray; /* length = ligatureCount */
+}
+Pos51, *Pos51Ptr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 6 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr mark1Coverage;
+ CoveragePtr mark2Coverage;
+ USHORT mark1Count;
+ USHORT mark2Count;
+ USHORT classCount;
+ MarkRecordPtr mark1Array; /* length = mark1Count */
+ AnchorPtr *mark2Array; /* length = mark2Count * classCount */
+}
+Pos61, *Pos61Ptr;
+
+#define Pos71Ptr OtfCtx1Ptr
+#define Pos72Ptr OtfCtx2Ptr
+#define Pos73Ptr OtfCtx3Ptr
+#define Pos81Ptr OtfChn1Ptr
+#define Pos82Ptr OtfChn2Ptr
+#define Pos83Ptr OtfChn3Ptr
+
+typedef union
+{
+ Pos11Ptr pos11;
+ Pos12Ptr pos12;
+ Pos21Ptr pos21;
+ Pos22Ptr pos22;
+ Pos31Ptr pos31;
+ Pos41Ptr pos41;
+ Pos51Ptr pos51;
+ Pos61Ptr pos61;
+ Pos71Ptr pos71;
+ Pos72Ptr pos72;
+ Pos73Ptr pos73;
+ Pos81Ptr pos81;
+ Pos82Ptr pos82;
+ Pos83Ptr pos83;
+}
+PosLookupPtr;
+
+#endif /* __TTF_GPOS_H */
diff --git a/Build/source/texk/ttfdump/include/gsub.h b/Build/source/texk/ttfdump/include/gsub.h
new file mode 100644
index 00000000000..725d60e8cde
--- /dev/null
+++ b/Build/source/texk/ttfdump/include/gsub.h
@@ -0,0 +1,134 @@
+/* gsub.h -- define data structures for Glyph Substitution Table
+ */
+
+#ifndef __TTF_GSUB_H
+#define __TTF_GSUB_H
+
+/* Substitution LookupType Values */
+#define SubLookup_Single 1
+#define SubLookup_Multiple 2
+#define SubLookup_Alternate 3
+#define SubLookup_Ligature 4
+#define SubLookup_Context 5
+#define SubLookup_ChainingContext 6
+#define SubLookup_ExtensionSubstitution 7
+#define SubLookup_ReverseChainingContextSingle 8
+#define SubLookup_Max 8
+
+typedef struct
+{
+ USHORT lookupType; /* = 1 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr coverage;
+ SHORT deltaGlyphID;
+}
+Sub11, *Sub11Ptr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 1 */
+ USHORT lookupFormat; /* = 2 */
+ CoveragePtr coverage;
+ USHORT glyphCount;
+ USHORT *substitute; /* length = glyphCount */
+}
+Sub12, *Sub12Ptr;
+
+typedef struct
+{
+ USHORT glyphCount;
+ USHORT *substitute; /* length = glyphCount */
+}
+Sequence, *SequencePtr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 2 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr coverage;
+ USHORT sequenceCount;
+ SequencePtr sequence; /* length = sequenceCount */
+}
+Sub21, *Sub21Ptr;
+
+typedef struct
+{
+ USHORT glyphCount;
+ USHORT *alternate; /* length = glyphCount */
+}
+AlternateSet, *AlternateSetPtr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 3 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr coverage;
+ USHORT alternateSetCount;
+ AlternateSetPtr alternateSet; /* length = alternateSetCount */
+}
+Sub31, *Sub31Ptr;
+
+typedef struct
+{
+ USHORT ligGlyph;
+ USHORT compCount;
+ USHORT *component; /* length = compCount - 1 */
+}
+Ligature, *LigaturePtr;
+
+typedef struct
+{
+ USHORT ligatureCount;
+ LigaturePtr ligature; /* length = ligatureCount */
+}
+LigatureSet, *LigatureSetPtr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 4 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr coverage;
+ USHORT ligSetCount;
+ LigatureSetPtr ligatureSet; /* length = ligSetCount */
+}
+Sub41, *Sub41Ptr;
+
+#define Sub51Ptr OtfCtx1Ptr
+#define Sub52Ptr OtfCtx2Ptr
+#define Sub53Ptr OtfCtx3Ptr
+#define Sub61Ptr OtfChn1Ptr
+#define Sub62Ptr OtfChn2Ptr
+#define Sub63Ptr OtfChn3Ptr
+
+typedef struct
+{
+ USHORT lookupType; /* = 8 */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr coverage;
+ USHORT backtrackGlyphCount;
+ CoveragePtr *backtrack; /* length = backtrackGlyphCount */
+ USHORT lookaheadGlyphCount;
+ CoveragePtr *lookahead; /* length = lookaheadGlyphCount */
+ USHORT glyphCount;
+ USHORT *substitute; /* length = glyphCount */
+}
+Sub81, *Sub81Ptr;
+
+typedef union
+{
+ Sub11Ptr sub11;
+ Sub12Ptr sub12;
+ Sub21Ptr sub21;
+ Sub31Ptr sub31;
+ Sub41Ptr sub41;
+ Sub51Ptr sub51;
+ Sub52Ptr sub52;
+ Sub53Ptr sub53;
+ Sub61Ptr sub61;
+ Sub62Ptr sub62;
+ Sub63Ptr sub63;
+ Sub81Ptr sub81;
+}
+SubLookupPtr;
+
+#endif /* __TTF_SUB_H */
diff --git a/Build/source/texk/ttfdump/include/loadtable.h b/Build/source/texk/ttfdump/include/loadtable.h
index 9bf74f0b5ab..f44c12dc69c 100644
--- a/Build/source/texk/ttfdump/include/loadtable.h
+++ b/Build/source/texk/ttfdump/include/loadtable.h
@@ -9,6 +9,8 @@ void ttfLoadRequiredTables(TTFontPtr font);
void ttfFreeRequiredTables(TTFontPtr font);
void ttfLoadOptionalTables(TTFontPtr font);
void ttfFreeOptionalTables(TTFontPtr font);
+void ttfLoadOpenTypeTables(TTFontPtr font);
+void ttfFreeOpenTypeTables(TTFontPtr font);
void ttfInitTableDir(TTFontPtr font, ULONG offset);
void ttfPrintTableDir(FILE *fp, TableDirPtr p);
@@ -17,8 +19,7 @@ TableDirPtr ttfLookUpTableDir(ULONG tag, TTFontPtr font);
void ttfInitCMAP(TTFontPtr font);
void ttfPrintCMAP(FILE *fp, CMAPPtr cmap);
-USHORT ttfLookUpCMAP(SubTablePtr subTable, USHORT cc);
-SubTablePtr ttfSelectCMAP(CMAPPtr cmap, USHORT PlatformID, USHORT EncodingID);
+USHORT ttfLookUpCMAP(MapPtr map, USHORT cc);
void ttfFreeCMAP(CMAPPtr cmap);
void ttfInitGLYF(TTFontPtr font);
@@ -93,6 +94,37 @@ void ttfInitVDMX(TTFontPtr font);
void ttfPrintVDMX(FILE *fp, VDMXPtr vdmx);
void ttfFreeVDMX(VDMXPtr vdmx);
+ScriptListPtr otfMakeScriptList(FILE *fp, ULONG offset);
+void otfPrintScriptList(FILE *fp, ScriptListPtr scriptList);
+void otfFreeScriptList(ScriptListPtr scriptList);
+
+FeatureListPtr otfMakeFeatureList(FILE *fp, ULONG offset);
+void otfPrintFeatureList(FILE *fp, FeatureListPtr featureList);
+void otfFreeFeatureList(FeatureListPtr featureList);
+
+LookupListPtr otfMakeLookupList(FILE *fp, ULONG offset, MakeLookupFunc makeLookup);
+void otfPrintLookupList(FILE *fp, LookupListPtr lookupList, PrintLookupFunc printLookup);
+void otfFreeLookupList(LookupListPtr lookupList, FreeLookupFunc freeLookup);
+
+CoveragePtr otfMakeCoverage(FILE *fp, ULONG offset);
+void otfPrintCoverage(FILE *fp, CoveragePtr coverage);
+void otfFreeCoverage(CoveragePtr coverage);
+
+ClassDefPtr otfMakeClassDef(FILE *fp, ULONG offset);
+void otfPrintClassDef(FILE *fp, ClassDefPtr classDef);
+void otfFreeClassDef(ClassDefPtr classDef);
+
+DevicePtr otfMakeDevice(FILE *fp, ULONG offset);
+void otfPrintDevice(FILE *fp, DevicePtr device);
+
+void ttfInitGPOS(TTFontPtr font);
+void ttfPrintGPOS(FILE *fp, GPOSPtr gpos);
+void ttfFreeGPOS(GPOSPtr gpos);
+
+void ttfInitGSUB(TTFontPtr font);
+void ttfPrintGSUB(FILE *fp, GSUBPtr gsub);
+void ttfFreeGSUB(GSUBPtr gsub);
+
void ttfInitGraphicsState(TTFontPtr font);
void ttfInitStack(TTFontPtr font);
void ttfInitStorageArea(TTFontPtr font);
diff --git a/Build/source/texk/ttfdump/include/otftables.h b/Build/source/texk/ttfdump/include/otftables.h
new file mode 100644
index 00000000000..5a6cc54c57e
--- /dev/null
+++ b/Build/source/texk/ttfdump/include/otftables.h
@@ -0,0 +1,368 @@
+/* otftables.h -- define data structures for various OpenType Tables
+ * See Also: OpenType Specification
+ */
+
+#ifndef __TTF_OTFTABLES_H
+#define __TTF_OTFTABLES_H
+
+typedef struct
+{
+ USHORT reqFeatureIndex;
+ USHORT featureCount;
+ USHORT *featureIndex; /* length = featureCount */
+}
+LangSys, *LangSysPtr;
+
+typedef struct
+{
+ ULONG tag;
+ LangSysPtr langSys;
+}
+LangSysRecord, *LangSysRecordPtr;
+
+typedef struct
+{
+ ULONG tag;
+ LangSysPtr defaultLangSys;
+ USHORT langSysCount;
+ LangSysRecord *langSysRecord; /* length = langSysCount */
+}
+ScriptRecord, *ScriptRecordPtr;
+
+typedef struct
+{
+ USHORT scriptCount;
+ ScriptRecord *scriptRecord; /* length = scriptCount */
+}
+ScriptList, *ScriptListPtr;
+
+typedef struct
+{
+ ULONG tag;
+ USHORT featureParams;
+ USHORT lookupCount;
+ USHORT *lookupListIndex; /* length = lookupCount */
+}
+FeatureRecord, *FeatureRecordPtr;
+
+typedef struct
+{
+ USHORT featureCount;
+ FeatureRecord *featureRecord; /* length = featureCount */
+}
+FeatureList, *FeatureListPtr;
+
+typedef struct
+{
+ USHORT start;
+ USHORT end;
+ USHORT startCoverageIndex;
+}
+RangeRecord, *RangeRecordPtr;
+
+typedef struct
+{
+ USHORT coverageFormat; /* = 1 */
+ USHORT glyphCount;
+ USHORT *glyphArray; /* length = glyphCount */
+}
+Coverage1, *Coverage1Ptr;
+
+typedef struct
+{
+ USHORT coverageFormat; /* = 2 */
+ USHORT rangeCount;
+ RangeRecordPtr rangeRecord; /* length = rangeCount */
+}
+Coverage2, *Coverage2Ptr;
+
+typedef union
+{
+ USHORT *format;
+ Coverage1Ptr coverage1;
+ Coverage2Ptr coverage2;
+}
+CoveragePtr;
+
+typedef struct
+{
+ USHORT start;
+ USHORT end;
+ USHORT classValue;
+}
+ClassRangeRecord, *ClassRangeRecordPtr;
+
+typedef struct
+{
+ USHORT classFormat; /* = 1 */
+ USHORT startGlyph;
+ USHORT glyphCount;
+ USHORT *classValueArray; /* length = glyphCount */
+}
+ClassDef1, *ClassDef1Ptr;
+
+typedef struct
+{
+ USHORT classFormat; /* = 2 */
+ USHORT classRangeCount;
+ ClassRangeRecordPtr classRangeRecord; /* length = classRangeCount */
+}
+ClassDef2, *ClassDef2Ptr;
+
+typedef union
+{
+ USHORT *format;
+ ClassDef1Ptr classDef1;
+ ClassDef2Ptr classDef2;
+}
+ClassDefPtr;
+
+typedef struct
+{
+ USHORT startSize;
+ USHORT endSize;
+ USHORT deltaFormat; /* = 1, 2, or 3 */
+ USHORT deltaValue[1]; /* variable size
+ * (endSize-startSize+1) entries
+ * 8, 4, or 2 entries per array element */
+}
+Device, *DevicePtr;
+
+typedef struct
+{
+ USHORT sequenceIndex;
+ USHORT lookupListIndex;
+}
+OtfLookupRecord, *OtfLookupRecordPtr;
+
+typedef struct
+{
+ USHORT glyphCount;
+ USHORT otfCount;
+ USHORT *input; /* length = glyphCount - 1 */
+ OtfLookupRecordPtr otf; /* length = otfCount */
+}
+OtfRule, *OtfRulePtr;
+
+typedef struct
+{
+ USHORT otfRuleCount;
+ OtfRulePtr otfRule; /* length = otfRuleCount */
+}
+OtfRuleSet, *OtfRuleSetPtr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 7 (GPOS) or 5 (GSUB) */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr coverage;
+ USHORT otfRuleSetCount;
+ OtfRuleSetPtr otfRuleSet; /* length = otfRuleSetCount */
+}
+OtfCtx1, *OtfCtx1Ptr;
+
+OtfCtx1Ptr makeOTFCtx1 (FILE *fp, ULONG offset);
+void printOTFCtx1 (FILE *fp, OtfCtx1Ptr otf);
+void freeOTFCtx1 (OtfCtx1Ptr otf);
+
+typedef struct
+{
+ USHORT glyphCount;
+ USHORT otfCount;
+ USHORT *class; /* length = glyphCount - 1 */
+ OtfLookupRecordPtr otf; /* length = otfCount */
+}
+OtfClassRule, *OtfClassRulePtr;
+
+typedef struct
+{
+ USHORT otfClassRuleCnt;
+ OtfClassRulePtr otfClassRule; /* length = otfClassRuleCnt */
+}
+OtfClassSet, *OtfClassSetPtr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 7 (GPOS) or 5 (GSUB) */
+ USHORT lookupFormat; /* = 2 */
+ CoveragePtr coverage;
+ ClassDefPtr classDef;
+ USHORT otfClassSetCnt;
+ OtfClassSetPtr otfClassSet; /* length = otfClassSetCnt */
+}
+OtfCtx2, *OtfCtx2Ptr;
+
+OtfCtx2Ptr makeOTFCtx2 (FILE *fp, ULONG offset);
+void printOTFCtx2 (FILE *fp, OtfCtx2Ptr otf);
+void freeOTFCtx2 (OtfCtx2Ptr otf);
+
+typedef struct
+{
+ USHORT lookupType; /* = 7 (GPOS) or 5 (GSUB) */
+ USHORT lookupFormat; /* = 3 */
+ USHORT glyphCount;
+ USHORT otfCount;
+ CoveragePtr *glyphs; /* length = glyphCount */
+ OtfLookupRecordPtr otf; /* length = otfCount */
+}
+OtfCtx3, *OtfCtx3Ptr;
+
+OtfCtx3Ptr makeOTFCtx3 (FILE *fp, ULONG offset);
+void printOTFCtx3 (FILE *fp, OtfCtx3Ptr otf);
+void freeOTFCtx3 (OtfCtx3Ptr otf);
+
+typedef struct
+{
+ USHORT backtrackGlyphCount;
+ USHORT *backtrack; /* length = backtrackGlyphCount */
+ USHORT inputGlyphCount;
+ USHORT *input; /* length = inputGlyphCount - 1 */
+ USHORT lookaheadGlyphCount;
+ USHORT *lookahead; /* length = lookaheadGlyphCount */
+ USHORT otfCount;
+ OtfLookupRecordPtr otf; /* length = otfCount */
+}
+ChainOtfRule, *ChainOtfRulePtr;
+
+typedef struct
+{
+ USHORT chainOtfRuleCount;
+ ChainOtfRulePtr chainOtfRule; /* length = chainOtfRuleCount */
+}
+ChainOtfRuleSet, *ChainOtfRuleSetPtr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 8 (GPOS) or 6 (GSUB) */
+ USHORT lookupFormat; /* = 1 */
+ CoveragePtr coverage;
+ USHORT chainOtfRuleSetCount;
+ ChainOtfRuleSetPtr chainOtfRuleSet; /* length = chainOtfRuleSetCount */
+}
+OtfChn1, *OtfChn1Ptr;
+
+OtfChn1Ptr makeOTFChn1 (FILE *fp, ULONG offset);
+void printOTFChn1 (FILE *fp, OtfChn1Ptr otf);
+void freeOTFChn1 (OtfChn1Ptr otf);
+
+typedef struct
+{
+ USHORT backtrackGlyphCount;
+ USHORT *backtrack; /* length = backtrackGlyphCount */
+ USHORT inputGlyphCount;
+ USHORT *input; /* length = inputGlyphCount - 1 */
+ USHORT lookaheadGlyphCount;
+ USHORT *lookahead; /* length = lookaheadGlyphCount */
+ USHORT otfCount;
+ OtfLookupRecordPtr otf; /* length = otfCount */
+}
+ChainOtfClassRule, *ChainOtfClassRulePtr;
+
+typedef struct
+{
+ USHORT chainOtfClassRuleCnt;
+ ChainOtfClassRulePtr chainOtfClassRule; /* length = chainOtfClassRuleCnt */
+}
+ChainOtfClassSet, *ChainOtfClassSetPtr;
+
+typedef struct
+{
+ USHORT lookupType; /* = 8 (GPOS) or 6 (GSUB) */
+ USHORT lookupFormat; /* = 2 */
+ CoveragePtr coverage;
+ ClassDefPtr backtrackClassDef;
+ ClassDefPtr inputClassDef;
+ ClassDefPtr lookaheadClassDef;
+ USHORT chainOtfClassSetCnt;
+ ChainOtfClassSetPtr chainOtfClassSet; /* length = chainOtfClassSetCnt */
+}
+OtfChn2, *OtfChn2Ptr;
+
+OtfChn2Ptr makeOTFChn2 (FILE *fp, ULONG offset);
+void printOTFChn2 (FILE *fp, OtfChn2Ptr otf);
+void freeOTFChn2 (OtfChn2Ptr otf);
+
+typedef struct
+{
+ USHORT lookupType; /* = 8 (GPOS) or 6 (GSUB) */
+ USHORT lookupFormat; /* = 3 */
+ USHORT backtrackGlyphCount;
+ CoveragePtr *backtrack; /* length = backtrackGlyphCount */
+ USHORT inputGlyphCount;
+ CoveragePtr *input; /* length = inputGlyphCount */
+ USHORT lookaheadGlyphCount;
+ CoveragePtr *lookahead; /* length = lookaheadGlyphCount */
+ USHORT otfCount;
+ OtfLookupRecordPtr otf; /* length = otfCount */
+}
+OtfChn3, *OtfChn3Ptr;
+
+OtfChn3Ptr makeOTFChn3 (FILE *fp, ULONG offset);
+void printOTFChn3 (FILE *fp, OtfChn3Ptr otf);
+void freeOTFChn3 (OtfChn3Ptr otf);
+
+#include "gpos.h"
+#include "gsub.h"
+
+typedef struct
+{
+ USHORT lookupType;
+ USHORT lookupFormat;
+}
+OtfLookup, *OtfLookupPtr;
+
+typedef union
+{
+ OtfLookupPtr otf;
+ PosLookupPtr pos;
+ SubLookupPtr sub;
+}
+LookupPtr;
+
+typedef struct
+{
+ USHORT lookupFlag;
+ USHORT subTableCount;
+ USHORT markFilteringSet;
+ LookupPtr *lookup; /* length = subTableCount */
+} LookupRecord, *LookupRecordPtr;
+
+/* LookupFlag Bits */
+#define LookupFlag_RightToLeft 0x0001
+#define lookupFlag_IgnoreBaseGlyphs 0x0002
+#define lookupFlag_IgnoreLigatures 0x0004
+#define lookupFlag_IgnoreMarks 0x0008
+#define lookupFlag_UseMarkFilteringSet 0x0010
+#define lookupFlag_Reserved 0x00e0
+#define lookupFlag_MarkAttachmentType 0xff00
+
+typedef struct
+{
+ USHORT lookupCount;
+ LookupRecord *lookupRecord;
+}
+LookupList, *LookupListPtr;
+
+typedef LookupPtr (MakeLookupFunc) (FILE *fp, USHORT lookupType, ULONG offset);
+typedef void (PrintLookupFunc) (FILE *fp, LookupPtr lookup);
+typedef void (FreeLookupFunc) (LookupPtr lookup);
+
+typedef struct
+{
+ Fixed version;
+ ScriptListPtr scriptList;
+ FeatureListPtr featureList;
+ LookupListPtr lookupList;
+}
+GPOS, *GPOSPtr;
+
+typedef struct
+{
+ Fixed version;
+ ScriptListPtr scriptList;
+ FeatureListPtr featureList;
+ LookupListPtr lookupList;
+}
+GSUB, *GSUBPtr;
+
+#endif /* __TTF_OTFTABLES_H */
diff --git a/Build/source/texk/ttfdump/include/tables.h b/Build/source/texk/ttfdump/include/tables.h
index cef49726cb9..ed05e4f5385 100644
--- a/Build/source/texk/ttfdump/include/tables.h
+++ b/Build/source/texk/ttfdump/include/tables.h
@@ -1,16 +1,16 @@
-/* table.h -- define data structures for various ttf file internal tables
+/* tables.h -- define data structures for various ttf file internal tables
* See Also: True Type Font Specification
*/
-#ifndef __TTF_TABLE_H
-#define __TTF_TABLE_H
+#ifndef __TTF_TABLES_H
+#define __TTF_TABLES_H
/* $Id: tables.h,v 1.2 1998/07/06 06:07:01 werner Exp $ */
/* Offset Table:
* Into the beginning of a True Type font file
*/
-typedef struct _OffsetTable
+typedef struct
{
Fixed version;
USHORT numTables;
@@ -23,7 +23,7 @@ OffsetTable, *OffsetTablePtr;
/* Table Directory:
* The directory to find each table in a True Type font file
*/
-typedef struct _TableDir
+typedef struct
{
ULONG tag;
ULONG checksum;
@@ -34,16 +34,19 @@ TableDir, *TableDirPtr;
/* cmap: Character to Glyph Index Mapping Table
- * There are four kinds of cmap, format 0, 2, 4, and 6. They are defined
- * as follows
+ * There are nine kinds of cmap, format 0, 2, 4, 6, 8, 10, 12,
+ * 13, and 14. They are defined as follows
*/
typedef struct
{
+ USHORT format; /* = 0 */
+ USHORT length;
+ USHORT version;
BYTE glyphIndexArray[256];
}
CMAP0;
-typedef struct _subHeaders
+typedef struct
{
USHORT firstCode;
USHORT entryCount;
@@ -54,6 +57,9 @@ SubHeader, *SubHeaderPtr;
typedef struct
{
+ USHORT format; /* = 2 */
+ USHORT length;
+ USHORT version;
USHORT subHeaderKeys[256];
SubHeaderPtr subHeaders;
USHORT *glyphIndexArray;
@@ -62,6 +68,9 @@ CMAP2;
typedef struct
{
+ USHORT format; /* = 4 */
+ USHORT length;
+ USHORT version;
USHORT segCountX2;
USHORT searchRange;
USHORT entrySelector;
@@ -73,43 +82,125 @@ typedef struct
USHORT *idRangeOffset;
USHORT *glyphIndexArray;
}
-
CMAP4;
+
typedef struct
{
+ USHORT format; /* = 6 */
+ USHORT length;
+ USHORT version;
USHORT firstCode;
USHORT entryCount;
USHORT *glyphIndexArray;
}
CMAP6;
-/* SubTable: one for each encoding scheme */
+typedef struct
+{
+ ULONG startCharCode;
+ ULONG endCharCode;
+ ULONG startGlyphID;
+}
+CharGroup, *CharGroupPtr;
+
+typedef struct
+{
+ USHORT format; /* = 8 */
+ ULONG length;
+ ULONG version;
+ BYTE is32[8192];
+ ULONG nGroups;
+ CharGroupPtr charGroup; /* size = nGroups */
+}
+CMAP8;
+
+typedef struct
+{
+ USHORT format; /* = 10 */
+ ULONG length;
+ ULONG version;
+ ULONG startCharCode;
+ ULONG numChars;
+ USHORT *glyphs;
+}
+CMAP10;
+
+typedef struct
+{
+ USHORT format; /* = 12 */
+ ULONG length;
+ ULONG version;
+ ULONG nGroups;
+ CharGroupPtr charGroup; /* size = nGroups */
+}
+CMAP12;
+
+typedef struct
+{
+ USHORT format; /* = 13 */
+ ULONG length;
+ ULONG version;
+ ULONG nGroups;
+ CharGroupPtr charGroup; /* size = nGroups */
+}
+CMAP13;
+
+typedef struct
+{
+ int notYet;
+}
+VarSelRec, *VarSelRecPtr;
+
+typedef struct
+{
+ USHORT format; /* = 14 */
+ ULONG length;
+ ULONG numVarSelRec;
+ VarSelRecPtr varSelRec; /* size = numVarSelRec */
+}
+CMAP14;
+
+typedef union
+{
+ USHORT *format;
+ CMAP0 *cmap0;
+ CMAP2 *cmap2;
+ CMAP4 *cmap4;
+ CMAP6 *cmap6;
+ CMAP8 *cmap8;
+ CMAP10 *cmap10;
+ CMAP12 *cmap12;
+ CMAP13 *cmap13;
+ CMAP14 *cmap14;
+}
+MapPtr;
+
+/* Encoding: one for each encoding scheme */
typedef struct
{
/* encoding table */
USHORT PlatformID;
USHORT EncodingID;
ULONG offset;
+ USHORT mapindex;
+ MapPtr map;
+}
+Encoding, *EncodingPtr;
- USHORT format;
- USHORT length;
- USHORT version;
- union
- {
- CMAP0 *cmap0;
- CMAP2 *cmap2;
- CMAP4 *cmap4;
- CMAP6 *cmap6;
- }
- map;
+typedef struct
+{
+ ULONG offset;
+ MapPtr map;
}
SubTable, *SubTablePtr;
-typedef struct _cmap
+typedef struct
{
USHORT version;
USHORT numberOfEncodings;
- SubTablePtr subTables; /* size = numberOfEncodings */
+ USHORT numberOfMaps;
+ EncodingPtr encoding; /* size = numberOfEncodings */
+ SubTablePtr subTable; /* size = numberOfMaps */
}
CMAP, *CMAPPtr;
@@ -209,8 +300,8 @@ typedef struct
ULONG magicNumber;
USHORT flags;
USHORT unitsPerEm;
- BYTE created[8];
- BYTE modified[8];
+ ULONG created[2];
+ ULONG modified[2];
FWord xMin;
FWord yMin;
FWord xMax;
@@ -258,7 +349,7 @@ HHEA, *HHEAPtr;
/* for a new created HMTX, one have to fill numberofHMetrics manually for
* hhea */
-typedef struct _longHorMetric
+typedef struct
{
uFWord advanceWidth;
FWord lsb;
@@ -579,7 +670,10 @@ typedef struct
}
VMTX, *VMTXPtr;
-#endif /* __TTF_TABLE_H */
+/* Additional OpenType Tables */
+#include "otftables.h"
+
+#endif /* __TTF_TABLES_H */
/* end of tables.h */
diff --git a/Build/source/texk/ttfdump/include/ttf.h b/Build/source/texk/ttfdump/include/ttf.h
index dd226235b23..57fa03ed1a3 100644
--- a/Build/source/texk/ttfdump/include/ttf.h
+++ b/Build/source/texk/ttfdump/include/ttf.h
@@ -121,7 +121,7 @@ typedef struct
* OffsetTables */
ULONG glyphOffset; /* where the glyph table starts */
TableDirPtr dir; /* Pointer to Table Directories */
- SubTablePtr encoding; /* `encoding' is the currently used encoding
+ EncodingPtr encoding; /* `encoding' is the currently used encoding
* table */
USHORT numCacheElements; /* number of glyph cache elements */
@@ -158,6 +158,10 @@ typedef struct
VDMXPtr vdmx;
VHEAPtr vhea;
VMTXPtr vmtx;
+
+ /* Additional OpenType Tables */
+ GPOSPtr gpos;
+ GSUBPtr gsub;
}
TTFont, *TTFontPtr;
diff --git a/Build/source/texk/ttfdump/include/ttfutil.h b/Build/source/texk/ttfdump/include/ttfutil.h
index e660bfce5fa..28be2cdd070 100644
--- a/Build/source/texk/ttfdump/include/ttfutil.h
+++ b/Build/source/texk/ttfdump/include/ttfutil.h
@@ -16,6 +16,7 @@ char *TagToStr(ULONG tag);
/* Functions copied or adapted from kpathsea. */
void xfseek (FILE *fp, long offset, int wherefrom, const char *funcname);
+long xftell (FILE *fp, const char *funcname);
void *xmalloc (size_t size);
void *xcalloc (size_t nelem, size_t elsize);
char *xstrdup(const char *s);
diff --git a/Build/source/texk/ttfdump/libttf/cmap.c b/Build/source/texk/ttfdump/libttf/cmap.c
index d876cfb8a96..c3ae65f3b61 100644
--- a/Build/source/texk/ttfdump/libttf/cmap.c
+++ b/Build/source/texk/ttfdump/libttf/cmap.c
@@ -54,32 +54,56 @@ typedef union _TwoBytes {
unsigned char c[2];
} TwoBytes;
-static void ttfLoadCMAP(FILE *fp,CMAPPtr cmap,ULONG offset);
-
-static void ttfLoadEncodingTable(FILE *fp,SubTablePtr subTable,ULONG offset);
-static void ttfLoadSubTable(FILE *fp,SubTablePtr subTable,ULONG offset);
-static void ttfPrintSubTable(FILE* fp,SubTablePtr ptable);
-static void ttfFreeSubTable(SubTablePtr ptable);
-
-static void ttfLoadCMAP0(FILE *fp,SubTablePtr subTable,ULONG offset);
-static void ttfPrintCMAP0(FILE *fp,SubTablePtr subTable);
-static USHORT ttfLookUpCMAP0(SubTablePtr subTable,USHORT cc);
-static void ttfFreeCMAP0(SubTablePtr subTable);
-
-static void ttfLoadCMAP2(FILE *fp,SubTablePtr subTable,ULONG offset);
-static void ttfPrintCMAP2(FILE *fp,SubTablePtr subTable);
-static USHORT ttfLookUpCMAP2(SubTablePtr subTable,USHORT cc);
-static void ttfFreeCMAP2(SubTablePtr subTable);
-
-static void ttfLoadCMAP4(FILE *fp,SubTablePtr subTable,ULONG offset);
-static void ttfPrintCMAP4(FILE *fp,SubTablePtr subTable);
-static USHORT ttfLookUpCMAP4(SubTablePtr subTable,USHORT cc);
-static void ttfFreeCMAP4(SubTablePtr subTable);
-
-static void ttfLoadCMAP6(FILE *fp,SubTablePtr subTable,ULONG offset);
-static void ttfPrintCMAP6(FILE *fp, SubTablePtr sbuTable);
-static USHORT ttfLookUpCMAP6(SubTablePtr subTable,USHORT cc);
-static void ttfFreeCMAP6(SubTablePtr subTable);
+static void ttfLoadCMAP(FILE *fp, CMAPPtr cmap, ULONG offset);
+
+static void ttfLoadSubTable(FILE *fp, SubTablePtr subTable, ULONG offset);
+static void ttfPrintSubTable(FILE* fp, SubTablePtr subTable);
+static void ttfFreeSubTable(SubTablePtr subTable);
+
+static void ttfLoadCMAP0(FILE *fp, MapPtr *map);
+static void ttfPrintCMAP0(FILE *fp, MapPtr map);
+static USHORT ttfLookUpCMAP0(MapPtr map, USHORT cc);
+static void ttfFreeCMAP0(MapPtr map);
+
+static void ttfLoadCMAP2(FILE *fp, MapPtr *map);
+static void ttfPrintCMAP2(FILE *fp, MapPtr map);
+static USHORT ttfLookUpCMAP2(MapPtr map, USHORT cc);
+static void ttfFreeCMAP2(MapPtr map);
+
+static void ttfLoadCMAP4(FILE *fp, MapPtr *map);
+static void ttfPrintCMAP4(FILE *fp, MapPtr map);
+static USHORT ttfLookUpCMAP4(MapPtr map, USHORT cc);
+static void ttfFreeCMAP4(MapPtr map);
+
+static void ttfLoadCMAP6(FILE *fp, MapPtr *map);
+static void ttfPrintCMAP6(FILE *fp, MapPtr map);
+static USHORT ttfLookUpCMAP6(MapPtr map, USHORT cc);
+static void ttfFreeCMAP6(MapPtr map);
+
+static void ttfLoadCMAP8(FILE *fp, MapPtr *map);
+static void ttfPrintCMAP8(FILE *fp, MapPtr map);
+static USHORT ttfLookUpCMAP8(MapPtr map, ULONG cc);
+static void ttfFreeCMAP8(MapPtr map);
+
+static void ttfLoadCMAP10(FILE *fp, MapPtr *map);
+static void ttfPrintCMAP10(FILE *fp, MapPtr map);
+static USHORT ttfLookUpCMAP10(MapPtr map, ULONG cc);
+static void ttfFreeCMAP10(MapPtr map);
+
+static void ttfLoadCMAP12(FILE *fp, MapPtr *map);
+static void ttfPrintCMAP12(FILE *fp, MapPtr map);
+static USHORT ttfLookUpCMAP12(MapPtr map, ULONG cc);
+static void ttfFreeCMAP12(MapPtr map);
+
+static void ttfLoadCMAP13(FILE *fp, MapPtr *map);
+static void ttfPrintCMAP13(FILE *fp, MapPtr map);
+static USHORT ttfLookUpCMAP13(MapPtr map, ULONG cc);
+static void ttfFreeCMAP13(MapPtr map);
+
+static void ttfLoadCMAP14(FILE *fp, MapPtr *map);
+static void ttfPrintCMAP14(FILE *fp, MapPtr map);
+static USHORT ttfLookUpCMAP14(MapPtr map, ULONG cc);
+static void ttfFreeCMAP14(MapPtr map);
void ttfInitCMAP(TTFontPtr font)
{
@@ -87,34 +111,47 @@ void ttfInitCMAP(TTFontPtr font)
TableDirPtr ptd;
if ((ptd = ttfLookUpTableDir(tag,font)) != NULL)
- {
- font->cmap = XCALLOC1 (CMAP);
- ttfLoadCMAP(font->fp,font->cmap,ptd->offset);
- }
+ {
+ font->cmap = XCALLOC1 (CMAP);
+ ttfLoadCMAP(font->fp,font->cmap,ptd->offset);
+ }
}
static void ttfLoadCMAP(FILE *fp,CMAPPtr cmap,ULONG offset)
{
USHORT i,n;
- ULONG posEnc; /* beginning of the Encoding Table */
- ULONG baseSub = offset; /* base of SubTable offset */
+ int k = 0;
xfseek(fp, offset, SEEK_SET, "ttfLoadCMAP");
cmap->version = ttfGetUSHORT(fp);
cmap->numberOfEncodings = n = ttfGetUSHORT(fp);
- cmap->subTables = XCALLOC (cmap->numberOfEncodings, SubTable);
-
- posEnc = baseSub + sizeof(USHORT)*2; /* step over the beginning of encoding
- * table */
-
- /* for each encoding scheme, load the encoding table (EncodingTable) and
- * the real cmap data (SubTable) */
- for (i=0;i<n;i++,posEnc += 8)
- { /* 8 == ushort*2 + ulong*1 */
- ttfLoadEncodingTable(fp,cmap->subTables+i,posEnc);
- ttfLoadSubTable(fp,cmap->subTables+i,baseSub);
- }
+ cmap->encoding = XCALLOC (cmap->numberOfEncodings, Encoding);
+
+ for (i = 0; i < n; i++)
+ {
+ int j;
+
+ cmap->encoding[i].PlatformID = ttfGetUSHORT(fp);
+ cmap->encoding[i].EncodingID = ttfGetUSHORT(fp);
+ cmap->encoding[i].offset = ttfGetULONG(fp);
+ cmap->encoding[i].mapindex = k++;
+ for (j = 0; j < i; j++) {
+ if (cmap->encoding[i].offset == cmap->encoding[j].offset)
+ {
+ cmap->encoding[i].mapindex = cmap->encoding[j].mapindex;
+ k--;
+ break;
+
+ }
+ }
+ }
+ cmap->numberOfMaps = k;
+ cmap->subTable = XCALLOC (cmap->numberOfMaps, SubTable);
+ for (i = 0; i < n; i++)
+ cmap->subTable[cmap->encoding[i].mapindex].offset = cmap->encoding[i].offset;
+ for (i = 0; i < k; i++)
+ ttfLoadSubTable(fp, cmap->subTable+i, offset);
}
void ttfPrintCMAP(FILE *fp,CMAPPtr cmap)
{
@@ -122,75 +159,79 @@ void ttfPrintCMAP(FILE *fp,CMAPPtr cmap)
fprintf(fp,"'cmap' Table - Character to Glyph Index Mapping Table\n");
fprintf(fp,"-----------------------------------------------------\n");
- fprintf(fp,"\t 'cmap' version: %d\n",cmap->version);
- fprintf(fp,"\t number of encoding: %d\n\n",cmap->numberOfEncodings);
-
- for (i=0;i<cmap->numberOfEncodings;i++)
- {
- fprintf(fp,"Subtable %3d.\t",i);
- ttfPrintSubTable(fp,cmap->subTables+i);
- fprintf(fp,"\n");
- }
+ fprintf(fp,"\t 'cmap' version: %d\n", cmap->version);
+ fprintf(fp,"\t number of encodings: %d\n", cmap->numberOfEncodings);
+ fprintf(fp,"\t number of subtables: %d\n\n", cmap->numberOfMaps);
+
+ for (i = 0; i < cmap->numberOfEncodings; i++)
+ {
+ fprintf(fp, "Encoding %3d.\t PlatformID: %2d\n", i,
+ cmap->encoding[i].PlatformID);
+ fprintf(fp, "\t\t EcodingID: %2d\n",
+ cmap->encoding[i].EncodingID);
+ fprintf(fp, "\t\t SubTable: %d, Offset: 0x%08x\n\n",
+ cmap->encoding[i].mapindex, cmap->encoding[i].offset);
+ }
+ for (i = 0; i < cmap->numberOfMaps; i++)
+ {
+ fprintf(fp,"SubTable %3d.\t",i);
+ ttfPrintSubTable(fp, cmap->subTable+i);
+ fprintf(fp,"\n");
+ }
}
-USHORT ttfLookUpCMAP(SubTablePtr subTable,USHORT cc)
+USHORT ttfLookUpCMAP(MapPtr map, USHORT cc)
{
- USHORT idx,format = subTable->format;
+ USHORT idx,format = *map.format;
switch (format)
- {
- case 0:
- idx = ttfLookUpCMAP0(subTable,cc);
- break;
- case 2:
- idx = ttfLookUpCMAP2(subTable,cc);
- break;
- case 4:
- idx = ttfLookUpCMAP4(subTable,cc);
- break;
- case 6:
- idx = ttfLookUpCMAP6(subTable,cc);
- break;
- default:
- ttfError("Unrecognized CMAP format\n");
- return 0;
- }
+ {
+ case 0:
+ idx = ttfLookUpCMAP0(map, cc);
+ break;
+ case 2:
+ idx = ttfLookUpCMAP2(map, cc);
+ break;
+ case 4:
+ idx = ttfLookUpCMAP4(map, cc);
+ break;
+ case 6:
+ idx = ttfLookUpCMAP6(map, cc);
+ break;
+ case 8:
+ idx = ttfLookUpCMAP8(map, cc);
+ break;
+ case 10:
+ idx = ttfLookUpCMAP10(map, cc);
+ break;
+ case 12:
+ idx = ttfLookUpCMAP12(map, cc);
+ break;
+ case 13:
+ idx = ttfLookUpCMAP13(map, cc);
+ break;
+ case 14:
+ idx = ttfLookUpCMAP14(map, cc);
+ break;
+ default:
+ ttfError("Unrecognized CMAP format\n");
+ return 0;
+ }
return idx;
}
-SubTablePtr ttfSelectCMAP(CMAPPtr cmap, USHORT PlatformID, USHORT EncodingID)
-{
- USHORT i;
-
- for (i=0;i<cmap->numberOfEncodings;i++)
- {
- if ((cmap->subTables+i)->PlatformID == PlatformID &&
- (cmap->subTables+i)->EncodingID == EncodingID)
- return cmap->subTables+i;
- }
- return NULL;
-}
void ttfFreeCMAP(CMAPPtr cmap)
{
USHORT i;
- for (i=0;i<cmap->numberOfEncodings;i++)
- ttfFreeSubTable(cmap->subTables+i);
+ free(cmap->encoding);
- free(cmap->subTables);
- free(cmap);
-}
+ for (i = 0; i < cmap->numberOfMaps; i++)
+ ttfFreeSubTable(cmap->subTable+i);
+ free(cmap->subTable);
-/* actually, EncodingTable is a part of SubTable */
-static void ttfLoadEncodingTable(FILE *fp,SubTablePtr subTable,ULONG offset)
-{
- xfseek(fp, offset, SEEK_SET, "ttfLoadEncodingTable");
-
- subTable->PlatformID = ttfGetUSHORT(fp);
- subTable->EncodingID = ttfGetUSHORT(fp);
- subTable->offset = ttfGetULONG(fp);
+ free(cmap);
}
-/* should this one be static ? */
-static void ttfLoadSubTable(FILE *fp,SubTablePtr subTable,ULONG base)
+static void ttfLoadSubTable(FILE *fp, SubTablePtr subTable, ULONG offset)
{
ULONG pos;
USHORT format;
@@ -198,239 +239,275 @@ static void ttfLoadSubTable(FILE *fp,SubTablePtr subTable,ULONG base)
/* seek to the actuall position for this subtable
* base: beginning of cmap
* offset: offset field of each encoding table */
- pos = base + subTable->offset;
- xfseek(fp, pos, SEEK_SET, "ttfLoadSubTable");
+ pos = offset + subTable->offset;
+ xfseek(fp, pos, SEEK_SET, "ttfLoadEncoding");
- subTable->format = format = ttfGetUSHORT(fp);
- subTable->length = ttfGetUSHORT(fp);
- subTable->version = ttfGetUSHORT(fp);
+ format = ttfGetUSHORT(fp);
- pos += 6;/* step over format independent data,USHORT*3 */
-
switch(format)
- {
- case 0:
- ttfLoadCMAP0(fp,subTable,pos);
- break;
- case 2:
- ttfLoadCMAP2(fp,subTable,pos);
- break;
- case 4:
- ttfLoadCMAP4(fp,subTable,pos);
- break;
- case 6:
- ttfLoadCMAP6(fp,subTable,pos);
- break;
- default:
- ttfError("Unrecognized CMAP format\n");
- }
-}
-static void ttfPrintSubTable(FILE* fp,SubTablePtr ptable)
-{
- USHORT format = ptable->format;
-
- /* print encoding table */
- fprintf(fp, " PlatformID: %2d\n",ptable->PlatformID);
- fprintf(fp,"\t\t EcodingID: %2d\n",ptable->EncodingID);
- fprintf(fp,"\t\t 'cmap' Offset: 0x%08x\n",ptable->offset);
+ {
+ case 0:
+ ttfLoadCMAP0(fp, &subTable->map);
+ break;
+ case 2:
+ ttfLoadCMAP2(fp, &subTable->map);
+ break;
+ case 4:
+ ttfLoadCMAP4(fp, &subTable->map);
+ break;
+ case 6:
+ ttfLoadCMAP6(fp, &subTable->map);
+ break;
+ case 8:
+ ttfLoadCMAP8(fp, &subTable->map);
+ break;
+ case 10:
+ ttfLoadCMAP10(fp, &subTable->map);
+ break;
+ case 12:
+ ttfLoadCMAP12(fp, &subTable->map);
+ break;
+ case 13:
+ ttfLoadCMAP13(fp, &subTable->map);
+ break;
+ case 14:
+ ttfLoadCMAP14(fp, &subTable->map);
+ break;
+ default:
+ ttfError("Unrecognized CMAP format\n");
+ }
+
+ *subTable->map.format = format;
+}
+static void ttfPrintSubTable(FILE* fp, SubTablePtr subTable)
+{
+ USHORT format = *subTable->map.format;
- /* print SubTable part */
- fprintf(fp,"\t\t Length: %6d\n",ptable->length);
- fprintf(fp,"\t\t Version: %6d\n",ptable->version);
-
switch(format)
- {
- case 0:
- fprintf(fp,"\t\t Format 0 - Byte encoding table\n");
- ttfPrintCMAP0(fp,ptable);
- break;
- case 2:
- fprintf(fp,"\t\t Format 2 - High-byte mapping through table\n");
- ttfPrintCMAP2(fp,ptable);
- break;
- case 4:
- fprintf(fp,"\t\t Format 4 - Segment mapping to delta values\n");
- ttfPrintCMAP4(fp,ptable);
- break;
- case 6:
- fprintf(fp,"\t\t Format 6 - Trimmed table mapping\n");
- ttfPrintCMAP6(fp,ptable);
- break;
- default:
- ttfError("Unrecognized CMAP format\n");
- }
-}
-static void ttfFreeSubTable(SubTablePtr ptable)
-{
- USHORT format = ptable->format;
+ {
+ case 0:
+ ttfPrintCMAP0(fp, subTable->map);
+ break;
+ case 2:
+ ttfPrintCMAP2(fp, subTable->map);
+ break;
+ case 4:
+ ttfPrintCMAP4(fp, subTable->map);
+ break;
+ case 6:
+ ttfPrintCMAP6(fp, subTable->map);
+ break;
+ case 8:
+ ttfPrintCMAP8(fp, subTable->map);
+ break;
+ case 10:
+ ttfPrintCMAP10(fp, subTable->map);
+ break;
+ case 12:
+ ttfPrintCMAP12(fp, subTable->map);
+ break;
+ case 13:
+ ttfPrintCMAP13(fp, subTable->map);
+ break;
+ case 14:
+ ttfPrintCMAP14(fp, subTable->map);
+ break;
+ default:
+ ttfError("Unrecognized CMAP format\n");
+ }
+}
+static void ttfFreeSubTable(SubTablePtr subTable)
+{
+ USHORT format = *subTable->map.format;
switch(format)
- {
- case 0:
- ttfFreeCMAP0(ptable);
- break;
- case 2:
- ttfFreeCMAP2(ptable);
- break;
- case 4:
- ttfFreeCMAP4(ptable);
- break;
- case 6:
- ttfFreeCMAP6(ptable);
- break;
- }
-}
-
-static void ttfLoadCMAP0(FILE *fp,SubTablePtr subTable,ULONG offset)
+ {
+ case 0:
+ ttfFreeCMAP0(subTable->map);
+ break;
+ case 2:
+ ttfFreeCMAP2(subTable->map);
+ break;
+ case 4:
+ ttfFreeCMAP4(subTable->map);
+ break;
+ case 6:
+ ttfFreeCMAP6(subTable->map);
+ break;
+ case 8:
+ ttfFreeCMAP8(subTable->map);
+ break;
+ case 10:
+ ttfFreeCMAP10(subTable->map);
+ break;
+ case 12:
+ ttfFreeCMAP12(subTable->map);
+ break;
+ case 13:
+ ttfFreeCMAP13(subTable->map);
+ break;
+ case 14:
+ ttfFreeCMAP14(subTable->map);
+ break;
+ }
+}
+
+static void ttfLoadCMAP0(FILE *fp, MapPtr *map)
{
BYTE * array;
- subTable->map.cmap0 = XCALLOC1 (CMAP0);
- array = subTable->map.cmap0->glyphIndexArray;
-
- xfseek(fp, offset, SEEK_SET, "ttfLoadCMAP0");
+ map->cmap0 = XCALLOC1 (CMAP0);
+ map->cmap0->length = ttfGetUSHORT(fp);
+ map->cmap0->version = ttfGetUSHORT(fp);
+ array = map->cmap0->glyphIndexArray;
/* Attention: we get lots of bytes at once as a work around of the
* usual ttfGet*, this cause byte sex trouble as will be seen
- * in the fellowing procedures */
+ * in the following procedures */
if (fread(array,sizeof(BYTE),256,fp) != 256)
- ttfError("Error when getting glyphIndexArray\n");
+ ttfError("Error when getting glyphIndexArray\n");
}
-static void ttfPrintCMAP0(FILE *fp,SubTablePtr subTable)
+static void ttfPrintCMAP0(FILE *fp, MapPtr map)
{
USHORT index;
int i;
+ fprintf(fp, " Format 0 - Byte encoding table\n");
+ fprintf(fp,"\t\t Length: %6d\n", map.cmap0->length);
+ fprintf(fp,"\t\t Version: %6d\n", map.cmap0->version);
for (i=0;i<256;i++)
- {
- index = ttfLookUpCMAP(subTable,i);
- fprintf(fp,"\t\t Char %3d -> Index %4d\n",i,index);
- }
+ {
+ index = ttfLookUpCMAP(map, i);
+ fprintf(fp,"\t\t Char %3d -> Index %4d\n",i,index);
+ }
}
-static USHORT ttfLookUpCMAP0(SubTablePtr subTable,USHORT cc)
+static USHORT ttfLookUpCMAP0(MapPtr map, USHORT cc)
{
- return subTable->map.cmap0->glyphIndexArray[cc & 0x00ff];
+ return map.cmap0->glyphIndexArray[cc & 0x00ff];
}
-static void ttfFreeCMAP0(SubTablePtr subTable)
+static void ttfFreeCMAP0(MapPtr map)
{
- free(subTable->map.cmap0);
+ free(map.cmap0);
}
-static void ttfLoadCMAP2(FILE *fp,SubTablePtr subTable,ULONG offset)
+static void ttfLoadCMAP2(FILE *fp, MapPtr *map)
{
USHORT * array,i,n = 0;
USHORT numGlyphId;
SubHeaderPtr header;
- xfseek(fp, offset, SEEK_SET, "ttfLoadCMAP2");
-
- subTable->map.cmap2 = XCALLOC1 (CMAP2);
- array = subTable->map.cmap2->subHeaderKeys;
+ map->cmap2 = XCALLOC1 (CMAP2);
+ map->cmap2->length = ttfGetUSHORT(fp);
+ map->cmap2->version = ttfGetUSHORT(fp);
+ array = map->cmap2->subHeaderKeys;
ttfReadUSHORT (array, 256, fp);
for (i=0;i<256;i++)
- {
- array[i] /= 8;
- if (n< array[i])
- n = array[i]; /* find the max of subHeaderKeys */
- }
+ {
+ array[i] /= 8;
+ if (n< array[i])
+ n = array[i]; /* find the max of subHeaderKeys */
+ }
n += 1; /* the number of subHeaders is one plus the max of subHeaderKeys */
- subTable->map.cmap2->subHeaders = header = XCALLOC (n, SubHeader);
+ map->cmap2->subHeaders = header = XCALLOC (n, SubHeader);
for (i=0;i<n;i++)
- {
- (header+i)->firstCode = ttfGetUSHORT(fp);
- (header+i)->entryCount = ttfGetUSHORT(fp);
- (header+i)->idDelta = ttfGetSHORT(fp);
- (header+i)->idRangeOffset = ttfGetUSHORT(fp);
-
- /* it makes things easier to let the offset starts from
- * the beginning of glyphIndexArray */
- if ((header+i)->idRangeOffset != 0)
- (header+i)->idRangeOffset -= (sizeof(USHORT) +
- (n-i-1) * sizeof(SubHeader)) ;
- }
+ {
+ (header+i)->firstCode = ttfGetUSHORT(fp);
+ (header+i)->entryCount = ttfGetUSHORT(fp);
+ (header+i)->idDelta = ttfGetSHORT(fp);
+ (header+i)->idRangeOffset = ttfGetUSHORT(fp);
+
+ /* it makes things easier to let the offset starts from
+ * the beginning of glyphIndexArray */
+ if ((header+i)->idRangeOffset != 0)
+ (header+i)->idRangeOffset -= (sizeof(USHORT) +
+ (n-i-1) * sizeof(SubHeader)) ;
+ }
/* caculate the length of glyphIndexArray, this is ugly, there should be
* a better way to get this information. */
numGlyphId =
- subTable->length - (256 + 3) * sizeof(USHORT) - n * sizeof(SubHeader);
+ map->cmap2->length - (256 + 3) * sizeof(USHORT) - n * sizeof(SubHeader);
numGlyphId /= sizeof(USHORT);
- subTable->map.cmap2->glyphIndexArray = XCALLOC (numGlyphId, USHORT);
+ map->cmap2->glyphIndexArray = XCALLOC (numGlyphId, USHORT);
for (i=0;i<numGlyphId;i++)
- {
- subTable->map.cmap2->glyphIndexArray[i] = ttfGetUSHORT(fp);
- }
+ {
+ map->cmap2->glyphIndexArray[i] = ttfGetUSHORT(fp);
+ }
}
-static void ttfPrintCMAP2(FILE *fp,SubTablePtr subTable)
+static void ttfPrintCMAP2(FILE *fp, MapPtr map)
{
USHORT i,j,numGlyphId;
USHORT *array,n=0,index;
SubHeaderPtr header;
TwoBytes tb;
- array = subTable->map.cmap2->subHeaderKeys;
- header = subTable->map.cmap2->subHeaders;
+ fprintf(fp, " Format 2 - High-byte mapping through table\n");
+ fprintf(fp,"\t\t Length: %6d\n", map.cmap2->length);
+ fprintf(fp,"\t\t Version: %6d\n", map.cmap2->version);
+ array = map.cmap2->subHeaderKeys;
+ header = map.cmap2->subHeaders;
for (i=0;i<256;i++)
- {
- /* find the number of subHeader */
- if (n< array[i])
- n = array[i];
- fprintf(fp,"\t\t subHeaderKeys[%d] = %d\n",i,array[i]);
- }
+ {
+ /* find the number of subHeader */
+ if (n< array[i])
+ n = array[i];
+ fprintf(fp,"\t\t subHeaderKeys[%d] = %d\n",i,array[i]);
+ }
n += 1; /* the number of subHeaders is one plus the max of subHeaderKeys */
fprintf(fp,"\t\t Number of SubHeaders is %d\n",n);
for (i=0;i<=n;i++)
- {
- fprintf(fp,"\t\t SubHeader[%d]\n",i);
- fprintf(fp,"\t\t firstCode \t 0x%04x\n",(header+i)->firstCode);
- fprintf(fp,"\t\t entryCount \t %d\n",(header+i)->entryCount);
- fprintf(fp,"\t\t idDelta \t %d\n",(header+i)->idDelta);
- fprintf(fp,"\t\t idRangeOffset \t 0x%04x\n\n",
- (header+i)->idRangeOffset);
- }
+ {
+ fprintf(fp,"\t\t SubHeader[%d]\n",i);
+ fprintf(fp,"\t\t firstCode \t 0x%04x\n",(header+i)->firstCode);
+ fprintf(fp,"\t\t entryCount \t %d\n",(header+i)->entryCount);
+ fprintf(fp,"\t\t idDelta \t %d\n",(header+i)->idDelta);
+ fprintf(fp,"\t\t idRangeOffset \t 0x%04x\n\n",
+ (header+i)->idRangeOffset);
+ }
/* caculate the length of glyphIndexArray, this is ugly, there should be
* a better way to get this information. */
numGlyphId =
- subTable->length - (256 + 3) * sizeof(USHORT) - n * sizeof(SubHeader);
+ map.cmap2->length - (256 + 3) * sizeof(USHORT) - n * sizeof(SubHeader);
numGlyphId /= sizeof(USHORT);
fprintf(fp,"Number of glyphIndex: %d\n", numGlyphId);
for (i=0;i<numGlyphId;i++)
- {
- fprintf(fp,"\t\t glyphIdArray[%d] = %4d\n",i,
- subTable->map.cmap2->glyphIndexArray[i]);
- }
+ {
+ fprintf(fp,"\t\t glyphIdArray[%d] = %4d\n",i,
+ map.cmap2->glyphIndexArray[i]);
+ }
i = 0;
fprintf(fp,"\t\t First Byte:\t %2x\n",i);
tb.c[1] = i;
for(j=0;j<=255;j++)
- {
- tb.c[0] = j;
- index = ttfLookUpCMAP2(subTable,tb.u);
- fprintf(fp,"\t\t Char %2x -> Index %d\n",j,index);
- }
+ {
+ tb.c[0] = j;
+ index = ttfLookUpCMAP2(map, tb.u);
+ fprintf(fp,"\t\t Char %2x -> Index %d\n",j,index);
+ }
for (i=128;i<=255;i++)
- {
- fprintf(fp,"\t\t First Byte:\t %2x\n",i);
- tb.c[1] = i;
- for(j=0;j<=255;j++)
- {
- tb.c[0] = j;
- index = ttfLookUpCMAP2(subTable,tb.u);
- fprintf(fp,"\t\t Char %2x -> Index %d\n",j,index);
- }
- }
-}
-static USHORT ttfLookUpCMAP2(SubTablePtr subTable,USHORT cc)
+ {
+ fprintf(fp,"\t\t First Byte:\t %2x\n",i);
+ tb.c[1] = i;
+ for(j=0;j<=255;j++)
+ {
+ tb.c[0] = j;
+ index = ttfLookUpCMAP2(map, tb.u);
+ fprintf(fp,"\t\t Char %2x -> Index %d\n",j,index);
+ }
+ }
+}
+static USHORT ttfLookUpCMAP2(MapPtr map, USHORT cc)
{
USHORT index,idx = 0;
- USHORT *array = subTable->map.cmap2->subHeaderKeys;
- SubHeaderPtr headers = subTable->map.cmap2->subHeaders;
+ USHORT *array = map.cmap2->subHeaderKeys;
+ SubHeaderPtr headers = map.cmap2->subHeaders;
SHORT idDelta;
USHORT firstCode, entryCount, idRangeOffset;
TwoBytes tb;
@@ -459,195 +536,431 @@ static USHORT ttfLookUpCMAP2(SubTablePtr subTable,USHORT cc)
idRangeOffset = (headers+idx)->idRangeOffset / sizeof (USHORT);
if (second >= firstCode && second < firstCode+entryCount)
- {
- /* use idRangeOffset to find where in the glyphIndexArray
- * the correspinding index is */
- idRangeOffset += (second - firstCode);
- index = subTable->map.cmap2->glyphIndexArray[idRangeOffset];
- if (index != 0)
- /* if the character is not a missing character then
- * add idDelta to it */
- index += idDelta;
- }
+ {
+ /* use idRangeOffset to find where in the glyphIndexArray
+ * the correspinding index is */
+ idRangeOffset += (second - firstCode);
+ index = map.cmap2->glyphIndexArray[idRangeOffset];
+ if (index != 0)
+ /* if the character is not a missing character then
+ * add idDelta to it */
+ index += idDelta;
+ }
else
- /* The second code is out ranged then return the
- * missing glyph character */
- index = 0;
-
+ /* The second code is out ranged then return the
+ * missing glyph character */
+ index = 0;
+
return index;
}
-static void ttfFreeCMAP2(SubTablePtr subTable)
+static void ttfFreeCMAP2(MapPtr map)
{
- free(subTable->map.cmap2->subHeaders);
- free(subTable->map.cmap2->glyphIndexArray);
- free(subTable->map.cmap2);
+ free(map.cmap2->subHeaders);
+ free(map.cmap2->glyphIndexArray);
+ free(map.cmap2);
}
-static void ttfLoadCMAP4(FILE *fp,SubTablePtr subTable,ULONG offset)
+static void ttfLoadCMAP4(FILE *fp, MapPtr *map)
{
USHORT segCount;
USHORT len;
- xfseek(fp, offset, SEEK_SET, "ttfLoadCMAP4");
-
- subTable->map.cmap4 = XCALLOC1 (CMAP4);
+ map->cmap4 = XCALLOC1 (CMAP4);
+ map->cmap4->length = ttfGetUSHORT(fp);
+ map->cmap4->version = ttfGetUSHORT(fp);
- subTable->map.cmap4->segCountX2 = segCount = ttfGetUSHORT(fp);
- subTable->map.cmap4->searchRange = ttfGetUSHORT(fp);
- subTable->map.cmap4->entrySelector = ttfGetUSHORT(fp);
- subTable->map.cmap4->rangeShift = ttfGetUSHORT(fp);
+ map->cmap4->segCountX2 = segCount = ttfGetUSHORT(fp);
+ map->cmap4->searchRange = ttfGetUSHORT(fp);
+ map->cmap4->entrySelector = ttfGetUSHORT(fp);
+ map->cmap4->rangeShift = ttfGetUSHORT(fp);
segCount /= 2;
- subTable->map.cmap4->endCount = ttfMakeUSHORT (segCount, fp);
+ map->cmap4->endCount = ttfMakeUSHORT (segCount, fp);
- subTable->map.cmap4->reservedPad = ttfGetUSHORT(fp);
+ map->cmap4->reservedPad = ttfGetUSHORT(fp);
- subTable->map.cmap4->startCount = ttfMakeUSHORT (segCount, fp);
+ map->cmap4->startCount = ttfMakeUSHORT (segCount, fp);
- subTable->map.cmap4->idDelta = ttfMakeUSHORT (segCount, fp);
+ map->cmap4->idDelta = ttfMakeUSHORT (segCount, fp);
- subTable->map.cmap4->idRangeOffset = ttfMakeUSHORT (segCount, fp);
+ map->cmap4->idRangeOffset = ttfMakeUSHORT (segCount, fp);
/* caculate the length of glyphIndexArray, this is ugly, there should be
* a better way to get this information. */
- len = subTable->length - 8*sizeof(USHORT) - 4*segCount*sizeof(USHORT);
+ len = map->cmap4->length - 8*sizeof(USHORT) - 4*segCount*sizeof(USHORT);
len /= sizeof(USHORT);
- subTable->map.cmap4->glyphIndexArray = ttfMakeUSHORT (len, fp);
+ map->cmap4->glyphIndexArray = ttfMakeUSHORT (len, fp);
}
-static void ttfPrintCMAP4(FILE *fp,SubTablePtr subTable)
+static void ttfPrintCMAP4(FILE *fp, MapPtr map)
{
USHORT i;
USHORT segCount,len;
- segCount = subTable->map.cmap4->segCountX2/2;
+ fprintf(fp, " Format 4 - Segment mapping to delta values\n");
+ fprintf(fp,"\t\t Length: %6d\n", map.cmap4->length);
+ fprintf(fp,"\t\t Version: %6d\n", map.cmap4->version);
+ segCount = map.cmap4->segCountX2/2;
fprintf(fp, "\t\t segCount:\t %d\n", segCount);
- fprintf(fp, "\t\t searchRange:\t %d\n", subTable->map.cmap4->searchRange);
- fprintf(fp, "\t\t entrySelector:\t %d\n", subTable->map.cmap4->entrySelector);
- fprintf(fp, "\t\t rangeShift:\t %d\n", subTable->map.cmap4->rangeShift);
+ fprintf(fp, "\t\t searchRange:\t %d\n", map.cmap4->searchRange);
+ fprintf(fp, "\t\t entrySelector:\t %d\n", map.cmap4->entrySelector);
+ fprintf(fp, "\t\t rangeShift:\t %d\n", map.cmap4->rangeShift);
for (i=0;i<segCount;i++)
- {
- fprintf(fp, "\t\t Seg %3d :", i);
- fprintf(fp, " St = %04x,", subTable->map.cmap4->startCount[i]);
- fprintf(fp, " En = %04x,", subTable->map.cmap4->endCount[i]);
- /* should this filed be SHORT or USHORT ?? */
- fprintf(fp, " D = %6d," ,
- (subTable->map.cmap4->idDelta[i]));
- fprintf(fp, " RO = %6d," , subTable->map.cmap4->idRangeOffset[i]);
-
- /* find the glyphIndex correpsonding to this segment */
- if (subTable->map.cmap4->idRangeOffset[i] != 0)
- {
- USHORT j;
- j = subTable->map.cmap4->segCountX2/2 - i;
- j = subTable->map.cmap4->idRangeOffset[i] -
- j*sizeof(USHORT);
- fprintf(fp, " gId# = %d\n", (int) (j/sizeof(USHORT)));
- }
- else
- fprintf(fp, " gId# = N/A\n");
- }
+ {
+ fprintf(fp, "\t\t Seg %3d :", i);
+ fprintf(fp, " St = %04x,", map.cmap4->startCount[i]);
+ fprintf(fp, " En = %04x,", map.cmap4->endCount[i]);
+ /* should this filed be SHORT or USHORT ?? */
+ fprintf(fp, " D = %6d," ,
+ (map.cmap4->idDelta[i]));
+ fprintf(fp, " RO = %6d," , map.cmap4->idRangeOffset[i]);
+
+ /* find the glyphIndex correpsonding to this segment */
+ if (map.cmap4->idRangeOffset[i] != 0)
+ {
+ USHORT j;
+ j = map.cmap4->segCountX2/2 - i;
+ j = map.cmap4->idRangeOffset[i] -
+ j*sizeof(USHORT);
+ fprintf(fp, " gId# = %d\n", (int) (j/sizeof(USHORT)));
+ }
+ else
+ fprintf(fp, " gId# = N/A\n");
+ }
/* caculate the length of glyphIndexArray, this is ugly, there should be
* a better way to get this information. */
- len = subTable->length - 8*sizeof(USHORT) - 4*segCount*sizeof(USHORT);
+ len = map.cmap4->length - 8*sizeof(USHORT) - 4*segCount*sizeof(USHORT);
len /= sizeof(USHORT);
fprintf(fp,"\t\t Number of glyphIndex %d\n",len);
for (i=0;i<len;i++)
- {
- fprintf(fp,"\t\t glyphIdArray[%d] = %d\n",i,
- subTable->map.cmap4->glyphIndexArray[i]);
- }
+ {
+ fprintf(fp,"\t\t glyphIdArray[%d] = %d\n",i,
+ map.cmap4->glyphIndexArray[i]);
+ }
for (i=0;i<segCount;i++)
- {
- int j,index;
- fprintf(fp,"Segment %d:\n",i);
- for (j=subTable->map.cmap4->startCount[i];
- j<=subTable->map.cmap4->endCount[i];j++)
- {
- index = ttfLookUpCMAP4(subTable,j);
- fprintf(fp,"\t\tChar 0x%04x -> Index %d\n",j,index);
- }
- }
-}
-static USHORT ttfLookUpCMAP4(SubTablePtr subTable,USHORT cc)
+ {
+ int j,index;
+ fprintf(fp,"Segment %d:\n",i);
+ for (j=map.cmap4->startCount[i];
+ j<=map.cmap4->endCount[i];j++)
+ {
+ index = ttfLookUpCMAP4(map, j);
+ fprintf(fp,"\t\tChar 0x%04x -> Index %d\n",j,index);
+ }
+ }
+}
+static USHORT ttfLookUpCMAP4(MapPtr map, USHORT cc)
{
USHORT i;
- USHORT index=0, segCount = subTable->map.cmap4->segCountX2/2;
+ USHORT index=0, segCount = map.cmap4->segCountX2/2;
for (i=0;i<segCount;i++)
- {
- if (cc <= subTable->map.cmap4->endCount[i] &&
- cc >= subTable->map.cmap4->startCount[i])
- {
- USHORT j;
- if (subTable->map.cmap4->idRangeOffset[i] != 0)
- {
- j = subTable->map.cmap4->idRangeOffset[i] -
- (segCount - i)*sizeof(USHORT);
- j = cc - subTable->map.cmap4->startCount[i] + j/2;
- index = subTable->map.cmap4->glyphIndexArray[j];
- if (index != 0)
- index += subTable->map.cmap4->idDelta[i];
- }
- else
- {
- index = cc + subTable->map.cmap4->idDelta[i];
- }
- break;
- }
- }
+ {
+ if (cc <= map.cmap4->endCount[i] &&
+ cc >= map.cmap4->startCount[i])
+ {
+ USHORT j;
+ if (map.cmap4->idRangeOffset[i] != 0)
+ {
+ j = map.cmap4->idRangeOffset[i] -
+ (segCount - i)*sizeof(USHORT);
+ j = cc - map.cmap4->startCount[i] + j/2;
+ index = map.cmap4->glyphIndexArray[j];
+ if (index != 0)
+ index += map.cmap4->idDelta[i];
+ }
+ else
+ {
+ index = cc + map.cmap4->idDelta[i];
+ }
+ break;
+ }
+ }
return index;
}
-static void ttfFreeCMAP4(SubTablePtr subTable)
+static void ttfFreeCMAP4(MapPtr map)
{
- free(subTable->map.cmap4->endCount);
- free(subTable->map.cmap4->startCount);
- free(subTable->map.cmap4->idDelta);
- free(subTable->map.cmap4->idRangeOffset);
- free(subTable->map.cmap4->glyphIndexArray);
- free(subTable->map.cmap4);
+ free(map.cmap4->endCount);
+ free(map.cmap4->startCount);
+ free(map.cmap4->idDelta);
+ free(map.cmap4->idRangeOffset);
+ free(map.cmap4->glyphIndexArray);
+ free(map.cmap4);
}
-static void ttfLoadCMAP6(FILE *fp,SubTablePtr subTable,ULONG offset)
+static void ttfLoadCMAP6(FILE *fp, MapPtr *map)
{
USHORT len;
- xfseek(fp, offset, SEEK_SET, "ttfLoadCMAP6");
-
- subTable->map.cmap6 = XCALLOC1 (CMAP6);
- subTable->map.cmap6->firstCode = ttfGetUSHORT(fp);
- subTable->map.cmap6->entryCount = len = ttfGetUSHORT(fp);
- subTable->map.cmap6->glyphIndexArray = ttfMakeUSHORT (len, fp);
+ map->cmap6 = XCALLOC1 (CMAP6);
+ map->cmap6->length = ttfGetUSHORT(fp);
+ map->cmap6->version = ttfGetUSHORT(fp);
+ map->cmap6->firstCode = ttfGetUSHORT(fp);
+ map->cmap6->entryCount = len = ttfGetUSHORT(fp);
+ map->cmap6->glyphIndexArray = ttfMakeUSHORT (len, fp);
}
-static void ttfPrintCMAP6(FILE *fp, SubTablePtr subTable)
+static void ttfPrintCMAP6(FILE *fp, MapPtr map)
{
USHORT i;
- fprintf(fp,"\t\t First Code: 0x%04x\n",subTable->map.cmap6->firstCode);
- fprintf(fp,"\t\t Entry Count: %d\n",subTable->map.cmap6->entryCount);
+
+ fprintf(fp, " Format 6 - Trimmed table mapping\n");
+ fprintf(fp,"\t\t Length: %6d\n", map.cmap6->length);
+ fprintf(fp,"\t\t Version: %6d\n", map.cmap6->version);
+ fprintf(fp,"\t\t First Code: 0x%04x\n", map.cmap6->firstCode);
+ fprintf(fp,"\t\t Entry Count: %d\n", map.cmap6->entryCount);
- for (i=0;i<subTable->map.cmap6->entryCount;i++)
- {
- fprintf(fp,"\t\t glyphIdArray[%d] = %d\n",i,
- subTable->map.cmap6->glyphIndexArray[i]);
- }
+ for (i=0;i<map.cmap6->entryCount;i++)
+ {
+ fprintf(fp,"\t\t glyphIdArray[%d] = %d\n",i,
+ map.cmap6->glyphIndexArray[i]);
+ }
}
-static USHORT ttfLookUpCMAP6(SubTablePtr subTable,USHORT cc)
+static USHORT ttfLookUpCMAP6(MapPtr map, USHORT cc)
{
USHORT index;
- index = cc - subTable->map.cmap6->firstCode;
- if (index < subTable->map.cmap6->entryCount)
- return subTable->map.cmap6->glyphIndexArray[index];
+ index = cc - map.cmap6->firstCode;
+ if (index < map.cmap6->entryCount)
+ return map.cmap6->glyphIndexArray[index];
+ else
+ /* index out of range, return missing glyph */
+ return 0;
+}
+static void ttfFreeCMAP6(MapPtr map)
+{
+ free(map.cmap6->glyphIndexArray);
+ free(map.cmap6);
+}
+
+static void ttfLoadCMAP8(FILE *fp, MapPtr *map)
+{
+ int i;
+
+ map->cmap8 = XCALLOC1 (CMAP8);
+ ttfGetUSHORT(fp);
+ map->cmap8->length = ttfGetULONG(fp);
+ map->cmap8->version = ttfGetULONG(fp);
+ if (fread(map->cmap8->is32, sizeof(BYTE), 8192, fp) != 8192)
+ ttfError("Error when getting is32\n");
+ map->cmap8->nGroups = ttfGetULONG(fp);
+ map->cmap8->charGroup = XCALLOC (map->cmap8->nGroups, CharGroup);
+ for (i = 0; i < map->cmap8->nGroups; i++) {
+ map->cmap8->charGroup[i].startCharCode = ttfGetULONG(fp);
+ map->cmap8->charGroup[i].endCharCode = ttfGetULONG(fp);
+ map->cmap8->charGroup[i].startGlyphID = ttfGetULONG(fp);
+ }
+}
+static void ttfPrintCMAP8(FILE *fp, MapPtr map)
+{
+ int i;
+
+ fprintf(fp, " Format 8 - Mixed 16-bit and 32-bit coverage\n");
+ fprintf(fp,"\t\t Length: %6d\n", map.cmap8->length);
+ fprintf(fp,"\t\t Version: %6d\n", map.cmap8->version);
+ fprintf(fp,"\t\t nGroups: %6d\n", map.cmap8->nGroups);
+ for (i = 0; i < 256; i++) {
+ int j;
+
+ fprintf(fp, "\t is32 %2x", i);
+ for (j = 0; j < 32; j++)
+ fprintf(fp, j % 4 ? "%2x" : " %2x", map.cmap8->is32[i << 5 | j]);
+ fprintf(fp, "\n");
+ }
+ for (i = 0; i < map.cmap8->nGroups; i++)
+ fprintf(fp, "\t\t Group %4d : startCharCode = %d, endCharCode = %d, startGlyphID = %d\n", i,
+ map.cmap8->charGroup[i].startCharCode,
+ map.cmap8->charGroup[i].endCharCode,
+ map.cmap8->charGroup[i].startGlyphID);
+}
+static USHORT ttfLookUpCMAP8(MapPtr map, ULONG cc)
+{
+ int i;
+
+ for (i = 0; i < map.cmap8->nGroups; i++)
+ if (cc > map.cmap8->charGroup[i].endCharCode)
+ continue;
+ else if (cc < map.cmap8->charGroup[i].startCharCode)
+ break;
+ else
+ return map.cmap8->charGroup[i].startGlyphID +
+ (cc - map.cmap8->charGroup[i].startCharCode);
+
+ /* index out of range, return missing glyph */
+ return 0;
+}
+static void ttfFreeCMAP8(MapPtr map)
+{
+ free(map.cmap8->charGroup);
+ free(map.cmap8);
+}
+
+static void ttfLoadCMAP10(FILE *fp, MapPtr *map)
+{
+ ULONG len;
+
+ map->cmap10 = XCALLOC1 (CMAP10);
+ ttfGetUSHORT(fp);
+ map->cmap10->length = ttfGetULONG(fp);
+ map->cmap10->version = ttfGetULONG(fp);
+ map->cmap10->startCharCode = ttfGetULONG(fp);
+ map->cmap10->numChars = len = ttfGetULONG(fp);
+ map->cmap10->glyphs = ttfMakeUSHORT (len, fp);
+}
+static void ttfPrintCMAP10(FILE *fp, MapPtr map)
+{
+ int i;
+
+ fprintf(fp, " Format 10 - Trimmed array\n");
+ fprintf(fp,"\t\t Length: %6d\n", map.cmap10->length);
+ fprintf(fp,"\t\t Version: %6d\n", map.cmap10->version);
+ fprintf(fp,"\t\t Start Char Code: 0x%04x\n", map.cmap10->startCharCode);
+ fprintf(fp,"\t\t Num Chars: %d\n", map.cmap10->numChars);
+
+ for (i = 0; i < map.cmap10->numChars; i++)
+ {
+ fprintf(fp, "\t\t glyphs[%d] = %d\n", i, map.cmap10->glyphs[i]);
+ }
+}
+static USHORT ttfLookUpCMAP10(MapPtr map, ULONG cc)
+{
+ ULONG index;
+
+ index = cc - map.cmap10->startCharCode;
+ if (index < map.cmap10->numChars)
+ return map.cmap10->glyphs[index];
else
- /* index out of range, return missing glyph */
- return 0;
+ /* index out of range, return missing glyph */
+ return 0;
+}
+static void ttfFreeCMAP10(MapPtr map)
+{
+ free(map.cmap10->glyphs);
+ free(map.cmap10);
+}
+
+static void ttfLoadCMAP12(FILE *fp, MapPtr *map)
+{
+ int i;
+
+ map->cmap12 = XCALLOC1 (CMAP12);
+ ttfGetUSHORT(fp);
+ map->cmap12->length = ttfGetULONG(fp);
+ map->cmap12->version = ttfGetULONG(fp);
+ map->cmap12->nGroups = ttfGetULONG(fp);
+ map->cmap12->charGroup = XCALLOC (map->cmap12->nGroups, CharGroup);
+ for (i = 0; i < map->cmap12->nGroups; i++) {
+ map->cmap12->charGroup[i].startCharCode = ttfGetULONG(fp);
+ map->cmap12->charGroup[i].endCharCode = ttfGetULONG(fp);
+ map->cmap12->charGroup[i].startGlyphID = ttfGetULONG(fp);
+ }
+}
+static void ttfPrintCMAP12(FILE *fp, MapPtr map)
+{
+ int i;
+
+ fprintf(fp, " Format 12 - Segmented coverage\n");
+ fprintf(fp,"\t\t Length: %6d\n", map.cmap12->length);
+ fprintf(fp,"\t\t Version: %6d\n", map.cmap12->version);
+ fprintf(fp,"\t\t nGroups: %6d\n", map.cmap12->nGroups);
+ for (i = 0; i < map.cmap12->nGroups; i++)
+ fprintf(fp, "\t\t Group %4d : startCharCode = %d, endCharCode = %d, startGlyphID = %d\n", i,
+ map.cmap12->charGroup[i].startCharCode,
+ map.cmap12->charGroup[i].endCharCode,
+ map.cmap12->charGroup[i].startGlyphID);
+}
+static USHORT ttfLookUpCMAP12(MapPtr map, ULONG cc)
+{
+ int i;
+
+ for (i = 0; i < map.cmap12->nGroups; i++)
+ if (cc > map.cmap12->charGroup[i].endCharCode)
+ continue;
+ else if (cc < map.cmap12->charGroup[i].startCharCode)
+ break;
+ else
+ return map.cmap12->charGroup[i].startGlyphID +
+ (cc - map.cmap12->charGroup[i].startCharCode);
+
+ /* index out of range, return missing glyph */
+ return 0;
+}
+static void ttfFreeCMAP12(MapPtr map)
+{
+ free(map.cmap12->charGroup);
+ free(map.cmap12);
+}
+
+static void ttfLoadCMAP13(FILE *fp, MapPtr *map)
+{
+ int i;
+
+ map->cmap13 = XCALLOC1 (CMAP13);
+ ttfGetUSHORT(fp);
+ map->cmap13->length = ttfGetULONG(fp);
+ map->cmap13->version = ttfGetULONG(fp);
+ map->cmap13->nGroups = ttfGetULONG(fp);
+ map->cmap13->charGroup = XCALLOC (map->cmap13->nGroups, CharGroup);
+ for (i = 0; i < map->cmap13->nGroups; i++) {
+ map->cmap13->charGroup[i].startCharCode = ttfGetULONG(fp);
+ map->cmap13->charGroup[i].endCharCode = ttfGetULONG(fp);
+ map->cmap13->charGroup[i].startGlyphID = ttfGetULONG(fp);
+ }
+}
+static void ttfPrintCMAP13(FILE *fp, MapPtr map)
+{
+ int i;
+
+ fprintf(fp, " Format 13 - Many-to-one range mappings\n");
+ fprintf(fp,"\t\t Length: %6d\n", map.cmap13->length);
+ fprintf(fp,"\t\t Version: %6d\n", map.cmap13->version);
+ fprintf(fp,"\t\t nGroups: %6d\n", map.cmap13->nGroups);
+ for (i = 0; i < map.cmap13->nGroups; i++)
+ fprintf(fp, "\t\t Group %4d : startCharCode = %d, endCharCode = %d, glyphID = %d\n", i,
+ map.cmap13->charGroup[i].startCharCode,
+ map.cmap13->charGroup[i].endCharCode,
+ map.cmap13->charGroup[i].startGlyphID);
+}
+static USHORT ttfLookUpCMAP13(MapPtr map, ULONG cc)
+{
+ int i;
+
+ for (i = 0; i < map.cmap13->nGroups; i++)
+ if (cc > map.cmap13->charGroup[i].endCharCode)
+ continue;
+ else if (cc < map.cmap13->charGroup[i].startCharCode)
+ break;
+ else
+ return map.cmap12->charGroup[i].startGlyphID;
+
+ /* index out of range, return missing glyph */
+ return 0;
+}
+static void ttfFreeCMAP13(MapPtr map)
+{
+ free(map.cmap13->charGroup);
+ free(map.cmap13);
+}
+
+static void ttfLoadCMAP14(FILE *fp, MapPtr *map)
+{
+ map->cmap14 = XCALLOC1 (CMAP14);
+ map->cmap14->length = ttfGetULONG(fp);
+}
+static void ttfPrintCMAP14(FILE *fp, MapPtr map)
+{
+ fprintf(fp, " Format 14 - Unicode variation sequences\n");
+ fprintf(fp,"\t\t Length: %6d\n", map.cmap14->length);
+ fprintf(fp,"\t\t *** NOT YET IMPLEMENTED ***\n");
+}
+static USHORT ttfLookUpCMAP14(MapPtr map, ULONG cc)
+{
+ return 0;
}
-static void ttfFreeCMAP6(SubTablePtr subTable)
+static void ttfFreeCMAP14(MapPtr map)
{
- free(subTable->map.cmap6->glyphIndexArray);
- free(subTable->map.cmap6);
+ free(map.cmap14);
}
diff --git a/Build/source/texk/ttfdump/libttf/font.c b/Build/source/texk/ttfdump/libttf/font.c
index 0ee6c25ec02..8b5e0d0a247 100644
--- a/Build/source/texk/ttfdump/libttf/font.c
+++ b/Build/source/texk/ttfdump/libttf/font.c
@@ -42,6 +42,7 @@ void ttfLoadFont(TTFontPtr font, ULONG offset)
ttfLoadRequiredTables(font);
ttfLoadOptionalTables(font);
+ ttfLoadOpenTypeTables(font);
ttfInitInterpreter(font);
@@ -55,6 +56,8 @@ void ttfFreeFont(TTFontPtr font)
ttfFreeOptionalTables(font);
+ ttfFreeOpenTypeTables(font);
+
ttfFreeTableDir(font->dir);
free(font->refcount);
free(font);
@@ -67,7 +70,6 @@ void ttfLoadRequiredTables(TTFontPtr font)
ttfInitMAXP(font);
ttfInitHEAD(font);
- ttfInitLOCA(font);
ttfInitGlyphCache(font);
ttfInitGLYF(font);
@@ -85,7 +87,6 @@ void ttfFreeRequiredTables(TTFontPtr font)
ttfFreeNAME(font->name);
ttfCleanUpGlyphCache(font);
- ttfFreeLOCA(font->loca);
ttfFreeHEAD(font->head);
ttfFreeMAXP(font->maxp);
@@ -103,6 +104,7 @@ void ttfLoadOptionalTables(TTFontPtr font)
ttfInitGASP(font);
ttfInitHDMX(font);
ttfInitKERN(font);
+ ttfInitLOCA(font);
ttfInitPREP(font);
ttfInitLTSH(font);
ttfInitPCLT(font);
@@ -117,6 +119,7 @@ void ttfFreeOptionalTables(TTFontPtr font)
ttfFreeGASP(font->gasp);
ttfFreeHDMX(font->hdmx);
ttfFreeKERN(font->kern);
+ ttfFreeLOCA(font->loca);
ttfFreePREP(font->prep);
ttfFreeLTSH(font->ltsh);
ttfFreePCLT(font->pclt);
@@ -125,6 +128,17 @@ void ttfFreeOptionalTables(TTFontPtr font)
ttfFreeVMTX(font->vmtx);
}
+void ttfLoadOpenTypeTables(TTFontPtr font)
+{
+ ttfInitGPOS(font);
+ ttfInitGSUB(font);
+}
+void ttfFreeOpenTypeTables(TTFontPtr font)
+{
+ ttfFreeGPOS(font->gpos);
+ ttfFreeGSUB(font->gsub);
+}
+
#if 0
/* Not used */
/* make a clone of the origional font
diff --git a/Build/source/texk/ttfdump/libttf/glyf.c b/Build/source/texk/ttfdump/libttf/glyf.c
index 9804d1bb126..ca922d0e07f 100644
--- a/Build/source/texk/ttfdump/libttf/glyf.c
+++ b/Build/source/texk/ttfdump/libttf/glyf.c
@@ -54,8 +54,8 @@ void ttfLoadGLYF(FILE *fp, GLYFPtr glyf, ULONG offset)
}
void ttfPrintGLYF(FILE *fp, GLYFPtr glyf)
{
- fprintf(fp,"\t numberOfContours:\t %d %s\n", glyf->numberOfContours,
- glyf->numberOfContours == -1 ? "(Composite)": "");
+ fprintf(fp,"\t numberOfContours:\t %d%s\n", glyf->numberOfContours,
+ glyf->numberOfContours == -1 ? " (Composite)": "");
fprintf(fp,"\t xMin:\t\t\t %d\n", glyf->xMin);
fprintf(fp,"\t yMin:\t\t\t %d\n", glyf->yMin);
fprintf(fp,"\t xMax:\t\t\t %d\n", glyf->xMax);
@@ -404,7 +404,7 @@ GLYFPtr ttfLoadGlyphCode(TTFont *font,USHORT cc)
{
USHORT index;
- index = ttfLookUpCMAP(font->encoding,cc);
+ index = ttfLookUpCMAP(font->encoding->map,cc);
return ttfLoadGlyphIndex(font,index);
}
diff --git a/Build/source/texk/ttfdump/libttf/gpos.c b/Build/source/texk/ttfdump/libttf/gpos.c
new file mode 100644
index 00000000000..9d040298099
--- /dev/null
+++ b/Build/source/texk/ttfdump/libttf/gpos.c
@@ -0,0 +1,971 @@
+/* gpos.c -- Glyph Positioning Table
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "config.h"
+#include "ttf.h"
+#include "ttfutil.h"
+
+static USHORT getValueFormat (FILE *fp)
+{
+ USHORT valueFormat = ttfGetUSHORT (fp);
+
+ if (valueFormat & ValueFormat_Reserved)
+ ttfError ("Unrecognized GPOS valueFormat\n");
+
+ return valueFormat;
+}
+
+static ValueRecordPtr
+gposMakeValueRecord (USHORT valueFormat, FILE *fp, ULONG offset)
+{
+ int i;
+ ValueRecordPtr value;
+
+ if (valueFormat == 0)
+ return NULL;
+
+ value = XCALLOC1 (ValueRecord);
+ for (i = 0; i < 4; i++)
+ if (valueFormat & (ValueFormat_XPlacement << i))
+ value->valDesign[i] = ttfGetSHORT (fp);
+ for (i = 0; i < 4; i++)
+ if (valueFormat & (ValueFormat_XPlaDevice << i))
+ ttfGetUSHORT (fp);
+
+ return value;
+}
+
+static const char *txtDesign[4] = {
+ "XPlacement",
+ "YPlacement",
+ "XAdvance",
+ "YAdvance"
+};
+
+static void
+gposPrintValueRecord (FILE *fp, const char *str, USHORT valueFormat, ValueRecordPtr value)
+{
+ const char *s = ":";
+ int i;
+
+ for (i = 0; i < 4; i++)
+ if (valueFormat & (ValueFormat_XPlacement << i)) {
+ fprintf (fp, "%s %s = %d\n", s, txtDesign[i], value->valDesign[i]);
+ s = str;
+ }
+ if (valueFormat & ValueFormat_AllDevice)
+ fprintf (fp, "\t\t *** Device Table NOT YET IMPLEMENTED ***\n");
+}
+
+static void freeValueRecord (ValueRecordPtr value)
+{
+ if (value) {
+ int i;
+
+ for (i = 0; i < 4; i++)
+ if (value->valDevice[i])
+ free (value->valDevice[i]);
+ free (value);
+ }
+}
+
+static AnchorPtr gposMakeAnchor (FILE *fp, ULONG offset)
+{
+ AnchorPtr anchor;
+ USHORT anchorFormat;
+ USHORT xOffset, yOffset;
+
+ xfseek (fp, offset, SEEK_SET, "gposMakeAnchor");
+
+ anchorFormat = ttfGetUSHORT (fp);
+ switch (anchorFormat)
+ {
+ case 1:
+ anchor.anchor1 = XCALLOC1 (Anchor1);
+ break;
+ case 2:
+ anchor.anchor2 = XCALLOC1 (Anchor2);
+ break;
+ case 3:
+ anchor.anchor3 = XCALLOC1 (Anchor3);
+ break;
+ default:
+ ttfError ("Unrecognized GPOS anchorFormat\n");
+ }
+ anchor.anchor1->anchorFormat = anchorFormat;
+ anchor.anchor1->xCoordinate = ttfGetSHORT (fp);
+ anchor.anchor1->yCoordinate = ttfGetSHORT (fp);
+
+ switch (anchorFormat)
+ {
+ case 2:
+ anchor.anchor2->anchorPoint = ttfGetUSHORT (fp);
+ break;
+ case 3:
+ xOffset = ttfGetUSHORT (fp);
+ yOffset = ttfGetUSHORT (fp);
+ if (xOffset)
+ anchor.anchor3->xDevice = otfMakeDevice (fp, offset + xOffset);
+ if (yOffset)
+ anchor.anchor3->yDevice = otfMakeDevice (fp, offset + yOffset);
+ break;
+ }
+
+ return anchor;
+}
+
+static void
+gposPrintAnchor (FILE *fp, const char *str, AnchorPtr anchor)
+{
+ fprintf (fp, "anchorFormat = %d, xCoordinate = %d, yCoordinate = %d\n",
+ anchor.anchor1->anchorFormat, anchor.anchor1->xCoordinate, anchor.anchor1->yCoordinate);
+
+ switch (anchor.anchor1->anchorFormat)
+ {
+ case 2:
+ fprintf (fp, "%sanchorPoint = %d\n", str, anchor.anchor2->anchorPoint);
+ break;
+ case 3:
+ if (anchor.anchor3->xDevice) {
+ fprintf (fp, "%sxDevice: ", str);
+ otfPrintDevice (fp, anchor.anchor3->xDevice);
+ }
+ if (anchor.anchor3->yDevice) {
+ fprintf (fp, "%syDevice: ", str);
+ otfPrintDevice (fp, anchor.anchor3->yDevice);
+ }
+ break;
+ }
+}
+
+static void freeAnchor (AnchorPtr anchor)
+{
+ if (anchor.anchor3) {
+ if (anchor.anchor3->anchorFormat == 3) {
+ if (anchor.anchor3->xDevice)
+ free (anchor.anchor3->xDevice);
+ if (anchor.anchor3->yDevice)
+ free (anchor.anchor3->yDevice);
+ }
+ free (anchor.anchor3);
+ }
+}
+
+static MarkRecordPtr
+gposMakeMarkArray (FILE *fp, USHORT *markCount, ULONG offset)
+{
+ int i;
+ MarkRecordPtr markArray;
+ USHORT *aOffset;
+
+ xfseek (fp, offset, SEEK_SET, "gposMakeMarkArray");
+
+ *markCount = ttfGetUSHORT (fp);
+ markArray = XCALLOC (*markCount, MarkRecord);
+ aOffset = XCALLOC (*markCount, USHORT);
+ for (i = 0; i < *markCount; i++) {
+ markArray[i].class = ttfGetUSHORT (fp);
+ aOffset[i] = ttfGetUSHORT (fp);
+ }
+ for (i = 0; i < *markCount; i++)
+ markArray[i].markAnchor = gposMakeAnchor (fp, offset + aOffset[i]);
+ free (aOffset);
+
+ return markArray;
+}
+
+static void
+gposPrintMarkArray (FILE *fp, USHORT markCount, MarkRecordPtr markArray)
+{
+ int i;
+
+ for (i = 0; i < markCount; i++) {
+ fprintf (fp, "\t %2d. class: %d - ", i, markArray[i].class);
+ gposPrintAnchor (fp, "\t\t ", markArray[i].markAnchor);
+ }
+}
+
+/* Used for both pos41->baseArray and pos61->mark2Array. */
+static AnchorPtr *
+gposMakeBaseArray (FILE *fp, USHORT *baseCount, USHORT classCount, ULONG offset)
+{
+ int i;
+ AnchorPtr *baseArray;
+ USHORT *aOffset;
+
+ xfseek (fp, offset, SEEK_SET, "gposMakeBaseArray");
+
+ *baseCount = ttfGetUSHORT (fp);
+ aOffset = ttfMakeUSHORT (*baseCount * classCount, fp);
+ baseArray = XCALLOC (*baseCount * classCount, AnchorPtr);
+ for (i = 0; i < *baseCount * classCount; i++)
+ if (aOffset[i])
+ baseArray[i] = gposMakeAnchor (fp, offset + aOffset[i]);
+ free (aOffset);
+
+ return baseArray;
+}
+
+static Pos11Ptr makeGPOS11 (FILE *fp, ULONG offset)
+{
+ USHORT cOffset;
+ Pos11Ptr pos = XCALLOC1 (Pos11);
+
+ cOffset = ttfGetUSHORT (fp);
+ pos->valueFormat = getValueFormat (fp);
+ pos->value = gposMakeValueRecord (pos->valueFormat, fp, offset);
+ pos->coverage = otfMakeCoverage (fp, offset + cOffset);
+
+ return pos;
+}
+
+static void printGPOS11 (FILE *fp, Pos11Ptr pos)
+{
+ fprintf (fp, " - Single Adjustment Value\n\t ");
+ otfPrintCoverage (fp, pos->coverage);
+ fprintf (fp, "\t valueFormat: 0x%04x\n", pos->valueFormat);
+ if (pos->valueFormat) {
+ fprintf (fp, "\t value");
+ gposPrintValueRecord (fp, "\t\t", pos->valueFormat, pos->value);
+ }
+}
+
+static void freeGPOS11 (Pos11Ptr pos)
+{
+ freeValueRecord (pos->value);
+ otfFreeCoverage (pos->coverage);
+}
+
+static Pos12Ptr makeGPOS12 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ Pos12Ptr pos = XCALLOC1 (Pos12);
+
+ cOffset = ttfGetUSHORT (fp);
+ pos->valueFormat = getValueFormat (fp);
+ pos->valueCount = ttfGetUSHORT (fp);
+ pos->value = XCALLOC (pos->valueCount, ValueRecordPtr);
+ for (i = 0; i < pos->valueCount; i++)
+ pos->value[i] = gposMakeValueRecord (pos->valueFormat, fp, offset);
+ pos->coverage = otfMakeCoverage (fp, offset + cOffset);
+
+ return pos;
+}
+
+static void printGPOS12 (FILE *fp, Pos12Ptr pos)
+{
+ int i;
+
+ fprintf (fp, " - Single Adjustment List\n\t ");
+ otfPrintCoverage (fp, pos->coverage);
+ fprintf (fp, "\t valueFormat: 0x%04x, valueCount: %d\n", pos->valueFormat, pos->valueCount);
+ for (i = 0; i < pos->valueCount; i++) {
+ fprintf (fp, "\t %2d. value", i);
+ gposPrintValueRecord (fp, "\t\t ", pos->valueFormat, pos->value[i]);
+ }
+}
+
+static void freeGPOS12 (Pos12Ptr pos)
+{
+ int i;
+
+ for (i = 0; i < pos->valueCount; i++)
+ freeValueRecord (pos->value[i]);
+ free (pos->value);
+ otfFreeCoverage (pos->coverage);
+}
+
+static void gposLoadPairSet (Pos21Ptr pos, int i, FILE *fp, ULONG offset, USHORT poff)
+{
+ int j;
+ PairSetPtr pairSet = &pos->pairSet[i];
+
+ xfseek (fp, offset + poff, SEEK_SET, "gposLoadPairSet");
+
+ pairSet->pairValueCount = ttfGetUSHORT (fp);
+ pairSet->pairValue = XCALLOC (pairSet->pairValueCount, PairValueRecord);
+ for (j = 0; j < pairSet->pairValueCount; j++) {
+ pairSet->pairValue[j].secondGlyph = ttfGetUSHORT (fp);
+ pairSet->pairValue[j].value1 = gposMakeValueRecord (pos->valueFormat1, fp, offset);
+ pairSet->pairValue[j].value2 = gposMakeValueRecord (pos->valueFormat2, fp, offset);
+ }
+}
+
+static Pos21Ptr makeGPOS21 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT *pOffset;
+ Pos21Ptr pos = XCALLOC1 (Pos21);
+
+ cOffset = ttfGetUSHORT (fp);
+ pos->valueFormat1 = getValueFormat (fp);
+ pos->valueFormat2 = getValueFormat (fp);
+ pos->pairSetCount = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (pos->pairSetCount, fp);
+ pos->coverage = otfMakeCoverage (fp, offset + cOffset);
+ pos->pairSet = XCALLOC (pos->pairSetCount, PairSet);
+ for (i = 0; i < pos->pairSetCount; i++)
+ gposLoadPairSet (pos, i, fp, offset, pOffset[i]);
+ free (pOffset);
+
+ return pos;
+}
+
+static void printGPOS21 (FILE *fp, Pos21Ptr pos)
+{
+ int i;
+
+ fprintf (fp, " - Pair Adjustment List\n\t ");
+ otfPrintCoverage (fp, pos->coverage);
+ fprintf (fp, "\t valueFormat1: 0x%04x, valueFormat2: 0x%04x, pairSetCount: %d\n",
+ pos->valueFormat1, pos->valueFormat2, pos->pairSetCount);
+ for (i = 0; i < pos->pairSetCount; i++) {
+ int j;
+ fprintf (fp, "\t %2d. pairValueCount: %d\n", i, pos->pairSet[i].pairValueCount);
+ for (j = 0; j < pos->pairSet[i].pairValueCount; j++) {
+ fprintf (fp, "\t %2d. secondGlyph: %d\n", j,
+ pos->pairSet[i].pairValue[j].secondGlyph);
+ if (pos->valueFormat1) {
+ fprintf (fp, "\t\t value1");
+ gposPrintValueRecord (fp, "\t\t\t ", pos->valueFormat1,
+ pos->pairSet[i].pairValue[j].value1);
+ }
+ if (pos->valueFormat2) {
+ fprintf (fp, "\t\t value2");
+ gposPrintValueRecord (fp, "\t\t\t ", pos->valueFormat2,
+ pos->pairSet[i].pairValue[j].value2);
+ }
+ }
+ }
+}
+
+static void freeGPOS21 (Pos21Ptr pos)
+{
+ int i;
+
+ for (i = 0; i < pos->pairSetCount; i++) {
+ int j;
+ for (j = 0; j < pos->pairSet[i].pairValueCount; j++) {
+ freeValueRecord (pos->pairSet[i].pairValue[j].value1);
+ freeValueRecord (pos->pairSet[i].pairValue[j].value2);
+ }
+ free (pos->pairSet[i].pairValue);
+ }
+ free (pos->pairSet);
+ otfFreeCoverage (pos->coverage);
+}
+
+static Pos22Ptr makeGPOS22 (FILE *fp, ULONG offset)
+{
+ int num = 0, i;
+ USHORT cOffset, cOffset1, cOffset2;
+ Pos22Ptr pos = XCALLOC1 (Pos22);
+
+ cOffset = ttfGetUSHORT (fp);
+ pos->valueFormat1 = getValueFormat (fp);
+ pos->valueFormat2 = getValueFormat (fp);
+ cOffset1 = ttfGetUSHORT (fp);
+ cOffset2 = ttfGetUSHORT (fp);
+ pos->class1Count = ttfGetUSHORT (fp);
+ pos->class2Count = ttfGetUSHORT (fp);
+ pos->values = XCALLOC (2 * pos->class1Count * pos->class2Count, ValueRecordPtr);
+ for (i = 0; i < pos->class1Count; i++) {
+ int j;
+
+ for (j = 0; j < pos->class2Count; j++) {
+ pos->values[num++] = gposMakeValueRecord (pos->valueFormat1, fp, offset);
+ pos->values[num++] = gposMakeValueRecord (pos->valueFormat2, fp, offset);
+ }
+ }
+ pos->coverage = otfMakeCoverage (fp, offset + cOffset);
+ pos->classDef1 = otfMakeClassDef (fp, offset + cOffset1);
+ pos->classDef2 = otfMakeClassDef (fp, offset + cOffset2);
+
+ return pos;
+}
+
+static void printGPOS22 (FILE *fp, Pos22Ptr pos)
+{
+ int num = 0, i;
+
+ fprintf (fp, " - Pair Adjustment Class\n\t ");
+ otfPrintCoverage (fp, pos->coverage);
+ fprintf (fp, "\t valueFormat1: 0x%04x, valueFormat2: 0x%04x\n",
+ pos->valueFormat1, pos->valueFormat2);
+ fprintf (fp, "\t ClassDef1 - ");
+ otfPrintClassDef (fp, pos->classDef1);
+ fprintf (fp, "\t ClassDef2 - ");
+ otfPrintClassDef (fp, pos->classDef2);
+ fprintf (fp, "\t class1Count: %d, class2Count: %d\n",
+ pos->class1Count, pos->class2Count);
+ for (i = 0; i < pos->class1Count; i++) {
+ int j;
+ const char *s = "";
+
+ fprintf (fp, "\t %2d.", i);
+ for (j = 0; j < pos->class2Count; j++) {
+ fprintf (fp, "%s %2d.", s, j);
+ s = "\t ";
+
+ if (pos->valueFormat1) {
+ fprintf (fp, " value1");
+ gposPrintValueRecord (fp, "\t\t\t ", pos->valueFormat1,
+ pos->values[num]);
+ }
+ num++;
+ if (pos->valueFormat2) {
+ fprintf (fp, " value2");
+ gposPrintValueRecord (fp, "\t\t\t ", pos->valueFormat2,
+ pos->values[num]);
+ }
+ num++;
+ }
+ }
+}
+
+static void freeGPOS22 (Pos22Ptr pos)
+{
+ int i;
+
+ for (i = 0; i < 2 * pos->class1Count * pos->class2Count; i++)
+ freeValueRecord (pos->values[i]);
+ free (pos->values);
+ otfFreeCoverage (pos->coverage);
+ otfFreeClassDef (pos->classDef1);
+ otfFreeClassDef (pos->classDef2);
+}
+
+static Pos31Ptr makeGPOS31 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT *eOffset;
+ Pos31Ptr pos = XCALLOC1 (Pos31);
+
+ cOffset = ttfGetUSHORT (fp);
+ pos->entryExitCount = ttfGetUSHORT (fp);
+ eOffset = ttfMakeUSHORT (2 * pos->entryExitCount, fp);
+ pos->coverage = otfMakeCoverage (fp, offset + cOffset);
+ pos->entryExit = XCALLOC (2 * pos->entryExitCount, AnchorPtr);
+ for (i = 0; i < 2 * pos->entryExitCount; i++)
+ if (eOffset[i])
+ pos->entryExit[i] = gposMakeAnchor (fp, offset + eOffset[i]);
+ free (eOffset);
+
+ return pos;
+}
+
+static void printGPOS31 (FILE *fp, Pos31Ptr pos)
+{
+ int i, num = 0;
+ fprintf (fp, " - Cursive Attachment\n\t ");
+ otfPrintCoverage (fp, pos->coverage);
+ fprintf (fp, "\t entryExitCount: %d\n", pos->entryExitCount);
+ for (i = 0; i < pos->entryExitCount; i++) {
+ int j;
+ const char *s = "";
+
+ fprintf (fp, "\t %2d. ", i);
+ for (j = 0; j < 2; j++) {
+ if (pos->entryExit[num].anchor1) {
+ fprintf (fp, "%s%sAnchor - ", s, j ? "exit" : "entry");
+ gposPrintAnchor (fp, "\t\t ", pos->entryExit[num]);
+ s = "\t ";
+ }
+ num++;
+ }
+ }
+}
+
+static void freeGPOS31 (Pos31Ptr pos)
+{
+ int i;
+
+ for (i = 0; i < 2 * pos->entryExitCount; i++)
+ freeAnchor (pos->entryExit[i]);
+ free (pos->entryExit);
+ otfFreeCoverage (pos->coverage);
+}
+
+static Pos41Ptr makeGPOS41 (FILE *fp, ULONG offset)
+{
+ USHORT mcOffset, bcOffset, maOffset, baOffset;
+ Pos41Ptr pos = XCALLOC1 (Pos41);
+
+ mcOffset = ttfGetUSHORT (fp);
+ bcOffset = ttfGetUSHORT (fp);
+ pos->classCount = ttfGetUSHORT (fp);
+ maOffset = ttfGetUSHORT (fp);
+ baOffset = ttfGetUSHORT (fp);
+ pos->markCoverage = otfMakeCoverage (fp, offset + mcOffset);
+ pos->baseCoverage = otfMakeCoverage (fp, offset + bcOffset);
+ pos->markArray = gposMakeMarkArray (fp, &pos->markCount, offset + maOffset);
+ pos->baseArray = gposMakeBaseArray (fp, &pos->baseCount, pos->classCount, offset + baOffset);
+
+ return pos;
+}
+
+static void printGPOS41 (FILE *fp, Pos41Ptr pos)
+{
+ int i, num = 0;
+
+ fprintf (fp, " - Mark To Base Attachment\n\t mark");
+ otfPrintCoverage (fp, pos->markCoverage);
+ fprintf (fp, "\t markArray - markCount: %d\n", pos->markCount);
+ gposPrintMarkArray (fp, pos->markCount, pos->markArray);
+ fprintf (fp, "\t base");
+ otfPrintCoverage (fp, pos->baseCoverage);
+ fprintf (fp, "\t baseArray - baseCount: %d, classCount: %d\n",
+ pos->baseCount, pos->classCount);
+ for (i = 0; i < pos->baseCount; i++) {
+ int j;
+ const char *s = "";
+
+ fprintf (fp, "\t %2d. ", i);
+ for (j = 0; j < pos->classCount; j++) {
+ if (pos->baseArray[num].anchor1) {
+ fprintf (fp, "%s%2d. ", s, j);
+ gposPrintAnchor (fp, "\t\t ", pos->baseArray[num]);
+ s = "\t ";
+ }
+ num++;
+ }
+ }
+}
+
+static void freeGPOS41 (Pos41Ptr pos)
+{
+ int i;
+
+ for (i = 0; i < pos->markCount; i++)
+ freeAnchor (pos->markArray[i].markAnchor);
+ free (pos->markArray);
+ for (i = 0; i < pos->baseCount * pos->classCount; i++)
+ freeAnchor (pos->baseArray[i]);
+ free (pos->baseArray);
+ otfFreeCoverage (pos->markCoverage);
+ otfFreeCoverage (pos->baseCoverage);
+}
+
+static void
+gposLoadLigatureArray (LigatureAttachPtr ligatureArray, USHORT classCount, FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *aOffset;
+
+ xfseek (fp, offset, SEEK_SET, "gposLoadLigatureArray");
+
+ ligatureArray->componentCount = ttfGetUSHORT (fp);
+ aOffset = ttfMakeUSHORT (ligatureArray->componentCount * classCount, fp);
+ ligatureArray->componentRecord = XCALLOC (ligatureArray->componentCount * classCount, AnchorPtr);
+ for (i = 0; i < ligatureArray->componentCount * classCount; i++)
+ if (aOffset[i])
+ ligatureArray->componentRecord[i] = gposMakeAnchor (fp, offset + aOffset[i]);
+ free (aOffset);
+}
+
+static LigatureAttachPtr
+gposMakeLigatureArray (FILE *fp, USHORT *ligatureCount, USHORT classCount, ULONG offset)
+{
+ int i;
+ LigatureAttachPtr ligatureArray;
+ USHORT *aOffset;
+
+ xfseek (fp, offset, SEEK_SET, "gposMakeLigatureArray");
+
+ *ligatureCount = ttfGetUSHORT (fp);
+ aOffset = ttfMakeUSHORT (*ligatureCount, fp);
+ ligatureArray = XCALLOC (*ligatureCount, LigatureAttach);
+ for (i = 0; i < *ligatureCount; i++)
+ gposLoadLigatureArray (&ligatureArray[i], classCount, fp, offset + aOffset[i]);
+ free (aOffset);
+
+ return ligatureArray;
+}
+
+static Pos51Ptr makeGPOS51 (FILE *fp, ULONG offset)
+{
+ USHORT mcOffset, lcOffset, maOffset, laOffset;
+ Pos51Ptr pos = XCALLOC1 (Pos51);
+
+ mcOffset = ttfGetUSHORT (fp);
+ lcOffset = ttfGetUSHORT (fp);
+ pos->classCount = ttfGetUSHORT (fp);
+ maOffset = ttfGetUSHORT (fp);
+ laOffset = ttfGetUSHORT (fp);
+ pos->markCoverage = otfMakeCoverage (fp, offset + mcOffset);
+ pos->ligatureCoverage = otfMakeCoverage (fp, offset + lcOffset);
+ pos->markArray = gposMakeMarkArray (fp, &pos->markCount, offset + maOffset);
+ pos->ligatureArray = gposMakeLigatureArray (fp, &pos->ligatureCount, pos->classCount, offset + laOffset);
+
+ return pos;
+}
+
+static void printGPOS51 (FILE *fp, Pos51Ptr pos)
+{
+ int i;
+
+ fprintf (fp, " - Mark To Ligature Attachment\n\t mark");
+ otfPrintCoverage (fp, pos->markCoverage);
+ fprintf (fp, "\t markArray - markCount: %d\n", pos->markCount);
+ gposPrintMarkArray (fp, pos->markCount, pos->markArray);
+ fprintf (fp, "\t ligature");
+ otfPrintCoverage (fp, pos->ligatureCoverage);
+ fprintf (fp, "\t ligatureArray - ligatureCount: %d\n", pos->ligatureCount);
+ for (i = 0; i < pos->ligatureCount; i++) {
+ int j, num = 0;
+
+ fprintf (fp, "\t %2d. componentCount: %d, classCount: %d\n", i,
+ pos->ligatureArray[i].componentCount, pos->classCount);
+ for (j = 0; j < pos->ligatureArray[i].componentCount; j++) {
+ int k;
+ const char *s = "";
+
+ fprintf (fp, "\t %2d. ", j);
+ for (k = 0; k < pos->classCount; k++) {
+ if (pos->ligatureArray[i].componentRecord[num].anchor1) {
+ fprintf (fp, "%s%2d. ", s, k);
+ gposPrintAnchor (fp, "\t\t ", pos->ligatureArray[i].componentRecord[num]);
+ s = "\t\t ";
+ }
+ num++;
+ }
+ }
+ }
+}
+
+static void freeGPOS51 (Pos51Ptr pos)
+{
+ int i;
+
+ for (i = 0; i < pos->markCount; i++)
+ freeAnchor (pos->markArray[i].markAnchor);
+ free (pos->markArray);
+ for (i = 0; i < pos->ligatureCount; i++) {
+ int j;
+
+ for (j = 0; j < pos->ligatureArray[i].componentCount * pos->classCount; j++)
+ freeAnchor (pos->ligatureArray[i].componentRecord[j]);
+ }
+ free (pos->ligatureArray);
+ otfFreeCoverage (pos->markCoverage);
+ otfFreeCoverage (pos->ligatureCoverage);
+}
+
+static Pos61Ptr makeGPOS61 (FILE *fp, ULONG offset)
+{
+ USHORT c1Offset, c2Offset, a1Offset, a2Offset;
+ Pos61Ptr pos = XCALLOC1 (Pos61);
+
+ c1Offset = ttfGetUSHORT (fp);
+ c2Offset = ttfGetUSHORT (fp);
+ pos->classCount = ttfGetUSHORT (fp);
+ a1Offset = ttfGetUSHORT (fp);
+ a2Offset = ttfGetUSHORT (fp);
+ pos->mark1Coverage = otfMakeCoverage (fp, offset + c1Offset);
+ pos->mark2Coverage = otfMakeCoverage (fp, offset + c2Offset);
+ pos->mark1Array = gposMakeMarkArray (fp, &pos->mark1Count, offset + a1Offset);
+ pos->mark2Array = gposMakeBaseArray (fp, &pos->mark2Count, pos->classCount, offset + a2Offset);
+
+ return pos;
+}
+
+static void printGPOS61 (FILE *fp, Pos61Ptr pos)
+{
+ int i, num = 0;
+
+ fprintf (fp, " - Mark To Mark Attachment\n\t mark1");
+ otfPrintCoverage (fp, pos->mark1Coverage);
+ fprintf (fp, "\t mark1Array - mark1Count: %d\n", pos->mark1Count);
+ gposPrintMarkArray (fp, pos->mark1Count, pos->mark1Array);
+ fprintf (fp, "\t mark2");
+ otfPrintCoverage (fp, pos->mark2Coverage);
+ fprintf (fp, "\t mark2Array - mark2Count: %d, classCount: %d\n",
+ pos->mark2Count, pos->classCount);
+ for (i = 0; i < pos->mark2Count; i++) {
+ int j;
+ const char *s = "";
+
+ fprintf (fp, "\t %2d. ", i);
+ for (j = 0; j < pos->classCount; j++) {
+ if (pos->mark2Array[num].anchor1) {
+ fprintf (fp, "%s%2d. ", s, j);
+ gposPrintAnchor (fp, "\t\t ", pos->mark2Array[num]);
+ s = "\t ";
+ }
+ num++;
+ }
+ }
+}
+
+static void freeGPOS61 (Pos61Ptr pos)
+{
+ int i;
+
+ for (i = 0; i < pos->mark1Count; i++)
+ freeAnchor (pos->mark1Array[i].markAnchor);
+ free (pos->mark1Array);
+ for (i = 0; i < pos->mark2Count * pos->classCount; i++)
+ freeAnchor (pos->mark2Array[i]);
+ free (pos->mark2Array);
+ otfFreeCoverage (pos->mark1Coverage);
+ otfFreeCoverage (pos->mark2Coverage);
+}
+
+#define makeGPOS71 makeOTFCtx1
+#define printGPOS71 printOTFCtx1
+#define freeGPOS71 freeOTFCtx1
+
+#define makeGPOS72 makeOTFCtx2
+#define printGPOS72 printOTFCtx2
+#define freeGPOS72 freeOTFCtx2
+
+#define makeGPOS73 makeOTFCtx3
+#define printGPOS73 printOTFCtx3
+#define freeGPOS73 freeOTFCtx3
+
+#define makeGPOS81 makeOTFChn1
+#define printGPOS81 printOTFChn1
+#define freeGPOS81 freeOTFChn1
+
+#define makeGPOS82 makeOTFChn2
+#define printGPOS82 printOTFChn2
+#define freeGPOS82 freeOTFChn2
+
+#define makeGPOS83 makeOTFChn3
+#define printGPOS83 printOTFChn3
+#define freeGPOS83 freeOTFChn3
+
+static LookupPtr makeGPOSLookup (FILE *fp, USHORT lookupType, ULONG offset)
+{
+ LookupPtr lookup;
+ USHORT lookupFormat;
+
+again:
+ if (lookupType == 0 || lookupType > PosLookup_Max)
+ ttfError ("Unrecognized GPOS lookupType\n");
+
+ xfseek (fp, offset, SEEK_SET, "makeGPOSLookup");
+
+ lookupFormat = ttfGetUSHORT (fp);
+ if (lookupFormat & 0xfff0)
+ lookupFormat = 0x000f;
+
+ switch (lookupType << 4 | lookupFormat)
+ {
+ case 0x011:
+ lookup.pos.pos11 = makeGPOS11 (fp, offset);
+ break;
+ case 0x012:
+ lookup.pos.pos12 = makeGPOS12 (fp, offset);
+ break;
+ case 0x021:
+ lookup.pos.pos21 = makeGPOS21 (fp, offset);
+ break;
+ case 0x022:
+ lookup.pos.pos22 = makeGPOS22 (fp, offset);
+ break;
+ case 0x031:
+ lookup.pos.pos31 = makeGPOS31 (fp, offset);
+ break;
+ case 0x041:
+ lookup.pos.pos41 = makeGPOS41 (fp, offset);
+ break;
+ case 0x051:
+ lookup.pos.pos51 = makeGPOS51 (fp, offset);
+ break;
+ case 0x061:
+ lookup.pos.pos61 = makeGPOS61 (fp, offset);
+ break;
+ case 0x071:
+ lookup.pos.pos71 = makeGPOS71 (fp, offset);
+ break;
+ case 0x072:
+ lookup.pos.pos72 = makeGPOS72 (fp, offset);
+ break;
+ case 0x073:
+ lookup.pos.pos73 = makeGPOS73 (fp, offset);
+ break;
+ case 0x081:
+ lookup.pos.pos81 = makeGPOS81 (fp, offset);
+ break;
+ case 0x082:
+ lookup.pos.pos82 = makeGPOS82 (fp, offset);
+ break;
+ case 0x083:
+ lookup.pos.pos83 = makeGPOS83 (fp, offset);
+ break;
+ case 0x091:
+ lookupType = ttfGetUSHORT (fp);
+ if (lookupType == 9)
+ ttfError ("Invalid GPOS extensionLookupType\n");
+ offset += ttfGetULONG (fp);
+ goto again;
+ default:
+ ttfError ("Unrecognized GPOS lookupFormat\n");
+ }
+
+ lookup.otf->lookupType = lookupType;
+ lookup.otf->lookupFormat = lookupFormat;
+
+ return lookup;
+}
+
+static void printGPOSLookup (FILE *fp, LookupPtr lookup)
+{
+ switch (lookup.otf->lookupType << 4 | lookup.otf->lookupFormat)
+ {
+ case 0x011:
+ printGPOS11 (fp, lookup.pos.pos11);
+ break;
+ case 0x012:
+ printGPOS12 (fp, lookup.pos.pos12);
+ break;
+ case 0x021:
+ printGPOS21 (fp, lookup.pos.pos21);
+ break;
+ case 0x022:
+ printGPOS22 (fp, lookup.pos.pos22);
+ break;
+ case 0x031:
+ printGPOS31 (fp, lookup.pos.pos31);
+ break;
+ case 0x041:
+ printGPOS41 (fp, lookup.pos.pos41);
+ break;
+ case 0x051:
+ printGPOS51 (fp, lookup.pos.pos51);
+ break;
+ case 0x061:
+ printGPOS61 (fp, lookup.pos.pos61);
+ break;
+ case 0x071:
+ printGPOS71 (fp, lookup.pos.pos71);
+ break;
+ case 0x072:
+ printGPOS72 (fp, lookup.pos.pos72);
+ break;
+ case 0x073:
+ printGPOS73 (fp, lookup.pos.pos73);
+ break;
+ case 0x081:
+ printGPOS81 (fp, lookup.pos.pos81);
+ break;
+ case 0x082:
+ printGPOS82 (fp, lookup.pos.pos82);
+ break;
+ case 0x083:
+ printGPOS83 (fp, lookup.pos.pos83);
+ break;
+ default:
+ ttfError ("Internal error: printGPOSLookup\n");
+ }
+}
+
+static void freeGPOSLookup (LookupPtr lookup)
+{
+ switch (lookup.otf->lookupType << 4 | lookup.otf->lookupFormat)
+ {
+ case 0x011:
+ freeGPOS11 (lookup.pos.pos11);
+ break;
+ case 0x012:
+ freeGPOS12 (lookup.pos.pos12);
+ break;
+ case 0x021:
+ freeGPOS21 (lookup.pos.pos21);
+ break;
+ case 0x022:
+ freeGPOS22 (lookup.pos.pos22);
+ break;
+ case 0x031:
+ freeGPOS31 (lookup.pos.pos31);
+ break;
+ case 0x041:
+ freeGPOS41 (lookup.pos.pos41);
+ break;
+ case 0x051:
+ freeGPOS51 (lookup.pos.pos51);
+ break;
+ case 0x061:
+ freeGPOS61 (lookup.pos.pos61);
+ break;
+ case 0x071:
+ freeGPOS71 (lookup.pos.pos71);
+ break;
+ case 0x072:
+ freeGPOS72 (lookup.pos.pos72);
+ break;
+ case 0x073:
+ freeGPOS73 (lookup.pos.pos73);
+ break;
+ case 0x081:
+ freeGPOS81 (lookup.pos.pos81);
+ break;
+ case 0x082:
+ freeGPOS82 (lookup.pos.pos82);
+ break;
+ case 0x083:
+ freeGPOS83 (lookup.pos.pos83);
+ break;
+ default:
+ ttfError ("Internal error: freeGPOSLookup\n");
+ }
+}
+
+static void ttfLoadGPOS (FILE *fp, GPOSPtr gpos, ULONG offset)
+{
+ USHORT sOffset, fOffset, lOffset;
+
+ xfseek (fp, offset, SEEK_SET, "ttfLoadGPOS");
+
+ gpos->version = ttfGetFixed (fp);
+ sOffset = ttfGetUSHORT (fp);
+ fOffset = ttfGetUSHORT (fp);
+ lOffset = ttfGetUSHORT (fp);
+
+ gpos->scriptList = otfMakeScriptList (fp, offset + sOffset);
+ gpos->featureList = otfMakeFeatureList (fp, offset + fOffset);
+ gpos->lookupList = otfMakeLookupList (fp, offset + lOffset, &makeGPOSLookup);
+}
+
+void ttfInitGPOS (TTFontPtr font)
+{
+ ULONG tag = FT_MAKE_TAG ('G', 'P', 'O', 'S');
+ TableDirPtr ptd;
+
+ if ((ptd = ttfLookUpTableDir (tag, font)) != NULL)
+ {
+ font->gpos = XCALLOC1 (GPOS);
+ ttfLoadGPOS (font->fp, font->gpos, ptd->offset);
+ }
+}
+
+void ttfPrintGPOS (FILE *fp, GPOSPtr gpos)
+{
+ int b[2];
+
+ FixedSplit (gpos->version, b);
+
+ fprintf (fp, "'GPOS' Table - Glyph Positioning Data\n");
+ fprintf (fp, "-------------------------------------\n");
+ fprintf (fp, "\t 'GPOS' Version:\t %d.%d\n",b[1],b[0]);
+
+ otfPrintScriptList (fp, gpos->scriptList);
+ otfPrintFeatureList (fp, gpos->featureList);
+ otfPrintLookupList (fp, gpos->lookupList, &printGPOSLookup);
+}
+
+void ttfFreeGPOS (GPOSPtr gpos)
+{
+ if (gpos != NULL)
+ {
+ otfFreeScriptList (gpos->scriptList);
+ otfFreeFeatureList (gpos->featureList);
+ otfFreeLookupList (gpos->lookupList, &freeGPOSLookup);
+ free (gpos);
+ }
+}
diff --git a/Build/source/texk/ttfdump/libttf/gsub.c b/Build/source/texk/ttfdump/libttf/gsub.c
new file mode 100644
index 00000000000..a0c8549bfc2
--- /dev/null
+++ b/Build/source/texk/ttfdump/libttf/gsub.c
@@ -0,0 +1,553 @@
+/* gsub.c -- Glyph Substitution Table
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "config.h"
+#include "ttf.h"
+#include "ttfutil.h"
+
+static Sub11Ptr makeGSUB11 (FILE *fp, ULONG offset)
+{
+ USHORT cOffset;
+ Sub11Ptr sub = XCALLOC1 (Sub11);
+
+ cOffset = ttfGetUSHORT (fp);
+ sub->deltaGlyphID = ttfGetUSHORT (fp);
+ sub->coverage = otfMakeCoverage (fp, offset + cOffset);
+
+ return sub;
+}
+
+static void printGSUB11 (FILE *fp, Sub11Ptr sub)
+{
+ fprintf (fp, " - Single Substitution Delta\n\t ");
+ otfPrintCoverage (fp, sub->coverage);
+ fprintf (fp, "\t deltaGlyphID: %d\n", sub->deltaGlyphID);
+}
+
+static void freeGSUB11 (Sub11Ptr sub)
+{
+ otfFreeCoverage (sub->coverage);
+}
+
+static Sub12Ptr makeGSUB12 (FILE *fp, ULONG offset)
+{
+ USHORT cOffset;
+ Sub12Ptr sub = XCALLOC1 (Sub12);
+
+ cOffset = ttfGetUSHORT (fp);
+ sub->glyphCount = ttfGetUSHORT (fp);
+ sub->substitute = ttfMakeUSHORT (sub->glyphCount, fp);
+ sub->coverage = otfMakeCoverage (fp, offset + cOffset);
+
+ return sub;
+}
+
+static void printGSUB12 (FILE *fp, Sub12Ptr sub)
+{
+ int i;
+
+ fprintf (fp, " - Single Substitution List\n\t ");
+ otfPrintCoverage (fp, sub->coverage);
+ fprintf (fp, "\t glyphCount: %d\n\t\t substitute: %d",
+ sub->glyphCount, sub->substitute[0]);
+ for (i = 1; i < sub->glyphCount; i++)
+ fprintf (fp, i % 8 ? ", %d" : ",\n\t\t\t %d", sub->substitute[i]);
+ fprintf (fp, "\n");
+}
+
+static void freeGSUB12 (Sub12Ptr sub)
+{
+ otfFreeCoverage (sub->coverage);
+ free (sub->substitute);
+}
+
+static void gsubLoadSequence (SequencePtr sequence, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "gsubLoadSequence");
+
+ sequence->glyphCount = ttfGetUSHORT (fp);
+ sequence->substitute = ttfMakeUSHORT (sequence->glyphCount, fp);
+}
+
+static Sub21Ptr makeGSUB21 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT *sOffset;
+ Sub21Ptr sub = XCALLOC1 (Sub21);
+
+ cOffset = ttfGetUSHORT (fp);
+ sub->sequenceCount = ttfGetUSHORT (fp);
+ sOffset = ttfMakeUSHORT (sub->sequenceCount, fp);
+ sub->coverage = otfMakeCoverage (fp, offset + cOffset);
+ sub->sequence = XCALLOC (sub->sequenceCount, Sequence);
+ for (i = 0; i < sub->sequenceCount; i++)
+ gsubLoadSequence (&sub->sequence[i], fp, offset + sOffset[i]);
+ free (sOffset);
+
+ return sub;
+}
+
+static void printGSUB21 (FILE *fp, Sub21Ptr sub)
+{
+ int i;
+
+ fprintf (fp, " - Multiple Substitution\n\t ");
+ otfPrintCoverage (fp, sub->coverage);
+ fprintf (fp, "\t sequenceCount: %d\n", sub->sequenceCount);
+ for (i = 0; i < sub->sequenceCount; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. glyphCount: %d - ", i, sub->sequence[i].glyphCount);
+ for (j = 0; j < sub->sequence[i].glyphCount; j++)
+ fprintf (fp, j == 0 ? "- %d" : ", %d", sub->sequence[i].substitute[j]);
+ fprintf (fp, "\n");
+ }
+}
+
+static void freeGSUB21 (Sub21Ptr sub)
+{
+ int i;
+
+ otfFreeCoverage (sub->coverage);
+ for (i = 0; i < sub->sequenceCount; i++)
+ free (sub->sequence[i].substitute);
+ free (sub->sequence);
+}
+
+static void gsubLoadAlternateSet (AlternateSetPtr alternateSet, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "gsubLoadAlternateSet");
+
+ alternateSet->glyphCount = ttfGetUSHORT (fp);
+ alternateSet->alternate = ttfMakeUSHORT (alternateSet->glyphCount, fp);
+}
+
+static Sub31Ptr makeGSUB31 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT *aOffset;
+ Sub31Ptr sub = XCALLOC1 (Sub31);
+
+ cOffset = ttfGetUSHORT (fp);
+ sub->alternateSetCount = ttfGetUSHORT (fp);
+ aOffset = ttfMakeUSHORT (sub->alternateSetCount, fp);
+ sub->coverage = otfMakeCoverage (fp, offset + cOffset);
+ sub->alternateSet = XCALLOC (sub->alternateSetCount, AlternateSet);
+ for (i = 0; i < sub->alternateSetCount; i++)
+ gsubLoadAlternateSet (&sub->alternateSet[i], fp, offset + aOffset[i]);
+ free (aOffset);
+
+ return sub;
+}
+
+static void printGSUB31 (FILE *fp, Sub31Ptr sub)
+{
+ int i;
+
+ fprintf (fp, " - Alternate Substitution\n\t ");
+ otfPrintCoverage (fp, sub->coverage);
+ fprintf (fp, "\t alternateSetCount: %d\n", sub->alternateSetCount);
+ for (i = 0; i < sub->alternateSetCount; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. glyphCount: %d ", i, sub->alternateSet[i].glyphCount);
+ for (j = 0; j < sub->alternateSet[i].glyphCount; j++)
+ fprintf (fp, j == 0 ? "- %d" : ", %d", sub->alternateSet[i].alternate[j]);
+ fprintf (fp, "\n");
+ }
+}
+
+static void freeGSUB31 (Sub31Ptr sub)
+{
+ int i;
+
+ otfFreeCoverage (sub->coverage);
+ for (i = 0; i < sub->alternateSetCount; i++)
+ free (sub->alternateSet[i].alternate);
+ free (sub->alternateSet);
+}
+
+static void gsubLoadLigature (LigaturePtr ligature, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "gsubLoadLigature");
+
+ ligature->ligGlyph = ttfGetUSHORT (fp);
+ ligature->compCount = ttfGetUSHORT (fp);
+ ligature->component = ttfMakeUSHORT (ligature->compCount - 1, fp);
+}
+
+static void gsubLoadLigatureSet (LigatureSetPtr ligatureSet, FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *lOffset;
+
+ xfseek (fp, offset, SEEK_SET, "gsubLoadLigatureSet");
+
+ ligatureSet->ligatureCount = ttfGetUSHORT (fp);
+ lOffset = ttfMakeUSHORT (ligatureSet->ligatureCount, fp);
+ ligatureSet->ligature = XCALLOC (ligatureSet->ligatureCount, Ligature);
+ for (i = 0; i < ligatureSet->ligatureCount; i++)
+ gsubLoadLigature (&ligatureSet->ligature[i], fp, offset + lOffset[i]);
+ free (lOffset);
+}
+
+static Sub41Ptr makeGSUB41 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT *lOffset;
+ Sub41Ptr sub = XCALLOC1 (Sub41);
+
+ cOffset = ttfGetUSHORT (fp);
+ sub->ligSetCount = ttfGetUSHORT (fp);
+ lOffset = ttfMakeUSHORT (sub->ligSetCount, fp);
+ sub->coverage = otfMakeCoverage (fp, offset + cOffset);
+ sub->ligatureSet = XCALLOC (sub->ligSetCount, LigatureSet);
+ for (i = 0; i < sub->ligSetCount; i++)
+ gsubLoadLigatureSet (&sub->ligatureSet[i], fp, offset + lOffset[i]);
+ free (lOffset);
+
+ return sub;
+}
+
+static void printGSUB41 (FILE *fp, Sub41Ptr sub)
+{
+ int i;
+
+ fprintf (fp, " - Ligature Substitution\n\t ");
+ otfPrintCoverage (fp, sub->coverage);
+ fprintf (fp, "\t ligSetCount: %d\n", sub->ligSetCount);
+ for (i = 0; i < sub->ligSetCount; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. ligatureCount: %d\n", i, sub->ligatureSet[i].ligatureCount);
+ for (j = 0; j < sub->ligatureSet[i].ligatureCount; j++) {
+ int k;
+
+ fprintf (fp, "\t %2d. ligGlyph: %d, compCount: %d ", j,
+ sub->ligatureSet[i].ligature[j].ligGlyph,
+ sub->ligatureSet[i].ligature[j].compCount);
+ for (k = 0; k < sub->ligatureSet[i].ligature[j].compCount - 1; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", sub->ligatureSet[i].ligature[j].component[k]);
+ fprintf (fp, "\n");
+ }
+ }
+}
+
+static void freeGSUB41 (Sub41Ptr sub)
+{
+ int i;
+
+ otfFreeCoverage (sub->coverage);
+ for (i = 0; i < sub->ligSetCount; i++) {
+ int j;
+
+ for (j = 0; j < sub->ligatureSet[i].ligatureCount; j++)
+ free (sub->ligatureSet[i].ligature[j].component);
+ free (sub->ligatureSet[i].ligature);
+ }
+ free (sub->ligatureSet);
+}
+
+#define makeGSUB51 makeOTFCtx1
+#define printGSUB51 printOTFCtx1
+#define freeGSUB51 freeOTFCtx1
+
+#define makeGSUB52 makeOTFCtx2
+#define printGSUB52 printOTFCtx2
+#define freeGSUB52 freeOTFCtx2
+
+#define makeGSUB53 makeOTFCtx3
+#define printGSUB53 printOTFCtx3
+#define freeGSUB53 freeOTFCtx3
+
+#define makeGSUB61 makeOTFChn1
+#define printGSUB61 printOTFChn1
+#define freeGSUB61 freeOTFChn1
+
+#define makeGSUB62 makeOTFChn2
+#define printGSUB62 printOTFChn2
+#define freeGSUB62 freeOTFChn2
+
+#define makeGSUB63 makeOTFChn3
+#define printGSUB63 printOTFChn3
+#define freeGSUB63 freeOTFChn3
+
+static Sub81Ptr makeGSUB81 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT *bOffset, *lOffset;
+ Sub81Ptr sub = XCALLOC1 (Sub81);
+
+ cOffset = ttfGetUSHORT (fp);
+ sub->backtrackGlyphCount = ttfGetUSHORT (fp);
+ bOffset = ttfMakeUSHORT (sub->backtrackGlyphCount, fp);
+ sub->lookaheadGlyphCount = ttfGetUSHORT (fp);
+ lOffset = ttfMakeUSHORT (sub->lookaheadGlyphCount, fp);
+ sub->glyphCount = ttfGetUSHORT (fp);
+ sub->substitute = ttfMakeUSHORT (sub->glyphCount, fp);
+ sub->coverage = otfMakeCoverage (fp, offset + cOffset);
+ sub->backtrack = XCALLOC (sub->backtrackGlyphCount, CoveragePtr);
+ for (i = 0; i < sub->backtrackGlyphCount; i++)
+ sub->backtrack[i] = otfMakeCoverage (fp, offset + bOffset[i]);
+ free (bOffset);
+ sub->lookahead = XCALLOC (sub->lookaheadGlyphCount, CoveragePtr);
+ for (i = 0; i < sub->lookaheadGlyphCount; i++)
+ sub->lookahead[i] = otfMakeCoverage (fp, offset + lOffset[i]);
+ free (lOffset);
+
+ return sub;
+}
+
+static void printGSUB81 (FILE *fp, Sub81Ptr sub)
+{
+ int i;
+
+ fprintf (fp, " - Reverse Chaining Context Single Substitution\n\t ");
+ otfPrintCoverage (fp, sub->coverage);
+ fprintf (fp, "\t backtrackGlyphCount: %d\n", sub->backtrackGlyphCount);
+ for (i = 0; i < sub->backtrackGlyphCount; i++) {
+ fprintf (fp, "\t %2d. backtrack", i);
+ otfPrintCoverage (fp, sub->backtrack[i]);
+ }
+ fprintf (fp, "\t lookaheadGlyphCount: %d\n", sub->lookaheadGlyphCount);
+ for (i = 0; i < sub->lookaheadGlyphCount; i++) {
+ fprintf (fp, "\t %2d. lookahead", i);
+ otfPrintCoverage (fp, sub->lookahead[i]);
+ }
+ fprintf (fp, "\t glyphCount: %d\n\t substitute - %d",
+ sub->glyphCount, sub->substitute[0]);
+ for (i = 1; i < sub->glyphCount; i++)
+ fprintf (fp, i % 8 ? ",\n\t\t %d" : ", %d", sub->substitute[i]);
+}
+
+static void freeGSUB81 (Sub81Ptr sub)
+{
+ int i;
+
+ otfFreeCoverage (sub->coverage);
+ for (i = 0; i < sub->backtrackGlyphCount; i++)
+ otfFreeCoverage (sub->backtrack[i]);
+ free (sub->backtrack);
+ for (i = 0; i < sub->lookaheadGlyphCount; i++)
+ otfFreeCoverage (sub->lookahead[i]);
+ free (sub->lookahead);
+ free (sub->substitute);
+}
+
+static LookupPtr makeGSUBLookup (FILE *fp, USHORT lookupType, ULONG offset)
+{
+ LookupPtr lookup;
+ USHORT lookupFormat;
+
+again:
+ if (lookupType == 0 || lookupType > SubLookup_Max)
+ ttfError ("Unrecognized GSUB lookupType\n");
+
+ xfseek (fp, offset, SEEK_SET, "makeGSUBLookup");
+
+ lookupFormat = ttfGetUSHORT (fp);
+ if (lookupFormat & 0xfff0)
+ lookupFormat = 0x000f;
+
+ switch (lookupType << 4 | lookupFormat)
+ {
+ case 0x011:
+ lookup.sub.sub11 = makeGSUB11 (fp, offset);
+ break;
+ case 0x012:
+ lookup.sub.sub12 = makeGSUB12 (fp, offset);
+ break;
+ case 0x021:
+ lookup.sub.sub21 = makeGSUB21 (fp, offset);
+ break;
+ case 0x031:
+ lookup.sub.sub31 = makeGSUB31 (fp, offset);
+ break;
+ case 0x041:
+ lookup.sub.sub41 = makeGSUB41 (fp, offset);
+ break;
+ case 0x051:
+ lookup.sub.sub51 = makeGSUB51 (fp, offset);
+ break;
+ case 0x052:
+ lookup.sub.sub52 = makeGSUB52 (fp, offset);
+ break;
+ case 0x053:
+ lookup.sub.sub53 = makeGSUB53 (fp, offset);
+ break;
+ case 0x061:
+ lookup.sub.sub61 = makeGSUB61 (fp, offset);
+ break;
+ case 0x062:
+ lookup.sub.sub62 = makeGSUB62 (fp, offset);
+ break;
+ case 0x063:
+ lookup.sub.sub63 = makeGSUB63 (fp, offset);
+ break;
+ case 0x081:
+ lookup.sub.sub81 = makeGSUB81 (fp, offset);
+ break;
+ case 0x071:
+ lookupType = ttfGetUSHORT (fp);
+ if (lookupType == 7)
+ ttfError ("Invalid GSUB extensionLookupType\n");
+ offset += ttfGetULONG (fp);
+ goto again;
+ default:
+ ttfError ("Unrecognized GSUB lookupFormat\n");
+ }
+
+ lookup.otf->lookupType = lookupType;
+ lookup.otf->lookupFormat = lookupFormat;
+
+ return lookup;
+}
+
+static void printGSUBLookup (FILE *fp, LookupPtr lookup)
+{
+ switch (lookup.otf->lookupType << 4 | lookup.otf->lookupFormat)
+ {
+ case 0x011:
+ printGSUB11 (fp, lookup.sub.sub11);
+ break;
+ case 0x012:
+ printGSUB12 (fp, lookup.sub.sub12);
+ break;
+ case 0x021:
+ printGSUB21 (fp, lookup.sub.sub21);
+ break;
+ case 0x031:
+ printGSUB31 (fp, lookup.sub.sub31);
+ break;
+ case 0x041:
+ printGSUB41 (fp, lookup.sub.sub41);
+ break;
+ case 0x051:
+ printGSUB51 (fp, lookup.sub.sub51);
+ break;
+ case 0x052:
+ printGSUB52 (fp, lookup.sub.sub52);
+ break;
+ case 0x053:
+ printGSUB53 (fp, lookup.sub.sub53);
+ break;
+ case 0x061:
+ printGSUB61 (fp, lookup.sub.sub61);
+ break;
+ case 0x062:
+ printGSUB62 (fp, lookup.sub.sub62);
+ break;
+ case 0x063:
+ printGSUB63 (fp, lookup.sub.sub63);
+ break;
+ case 0x081:
+ printGSUB81 (fp, lookup.sub.sub81);
+ break;
+ default:
+ ttfError ("Internal error: printGSUBLookup\n");
+ }
+}
+
+static void freeGSUBLookup (LookupPtr lookup)
+{
+ switch (lookup.otf->lookupType << 4 | lookup.otf->lookupFormat)
+ {
+ case 0x011:
+ freeGSUB11 (lookup.sub.sub11);
+ break;
+ case 0x012:
+ freeGSUB12 (lookup.sub.sub12);
+ break;
+ case 0x021:
+ freeGSUB21 (lookup.sub.sub21);
+ break;
+ case 0x031:
+ freeGSUB31 (lookup.sub.sub31);
+ break;
+ case 0x041:
+ freeGSUB41 (lookup.sub.sub41);
+ break;
+ case 0x051:
+ freeGSUB51 (lookup.sub.sub51);
+ break;
+ case 0x052:
+ freeGSUB52 (lookup.sub.sub52);
+ break;
+ case 0x053:
+ freeGSUB53 (lookup.sub.sub53);
+ break;
+ case 0x061:
+ freeGSUB61 (lookup.sub.sub61);
+ break;
+ case 0x062:
+ freeGSUB62 (lookup.sub.sub62);
+ break;
+ case 0x063:
+ freeGSUB63 (lookup.sub.sub63);
+ break;
+ case 0x081:
+ freeGSUB81 (lookup.sub.sub81);
+ break;
+ default:
+ ttfError ("Internal error: freeGSUBLookup\n");
+ }
+}
+
+static void ttfLoadGSUB (FILE *fp, GSUBPtr gsub, ULONG offset)
+{
+ USHORT sOffset, fOffset, lOffset;
+
+ xfseek (fp, offset, SEEK_SET, "ttfLoadGSUB");
+
+ gsub->version = ttfGetFixed (fp);
+ sOffset = ttfGetUSHORT (fp);
+ fOffset = ttfGetUSHORT (fp);
+ lOffset = ttfGetUSHORT (fp);
+
+ gsub->scriptList = otfMakeScriptList (fp, offset + sOffset);
+ gsub->featureList = otfMakeFeatureList (fp, offset + fOffset);
+ gsub->lookupList = otfMakeLookupList (fp, offset + lOffset, &makeGSUBLookup);
+}
+
+void ttfInitGSUB (TTFontPtr font)
+{
+ ULONG tag = FT_MAKE_TAG ('G', 'S', 'U', 'B');
+ TableDirPtr ptd;
+
+ if ((ptd = ttfLookUpTableDir (tag, font)) != NULL)
+ {
+ font->gsub = XCALLOC1 (GSUB);
+ ttfLoadGSUB (font->fp, font->gsub, ptd->offset);
+ }
+}
+
+void ttfPrintGSUB (FILE *fp, GSUBPtr gsub)
+{
+ int b[2];
+
+ FixedSplit (gsub->version, b);
+
+ fprintf (fp, "'GSUB' Table - Glyph Substitution Data\n");
+ fprintf (fp, "--------------------------------------\n");
+ fprintf (fp, "\t 'GSUB' Version:\t %d.%d\n",b[1],b[0]);
+
+ otfPrintScriptList (fp, gsub->scriptList);
+ otfPrintFeatureList (fp, gsub->featureList);
+ otfPrintLookupList (fp, gsub->lookupList, &printGSUBLookup);
+}
+
+void ttfFreeGSUB (GSUBPtr gsub)
+{
+ if (gsub != NULL)
+ {
+ otfFreeScriptList (gsub->scriptList);
+ otfFreeFeatureList (gsub->featureList);
+ otfFreeLookupList (gsub->lookupList, &freeGSUBLookup);
+ free (gsub);
+ }
+}
diff --git a/Build/source/texk/ttfdump/libttf/head.c b/Build/source/texk/ttfdump/libttf/head.c
index ec4b33bcbaa..eec89cc9b2c 100644
--- a/Build/source/texk/ttfdump/libttf/head.c
+++ b/Build/source/texk/ttfdump/libttf/head.c
@@ -34,10 +34,8 @@ static void ttfLoadHEAD(FILE *fp,HEADPtr head,ULONG offset)
head->flags = ttfGetUSHORT(fp);
head->unitsPerEm = ttfGetUSHORT(fp);
- if (fread(head->created,sizeof(char),8,fp) != 8)
- ttfError("Error when getting HEAD created\n");
- if (fread(head->modified,sizeof(char),8,fp) != 8)
- ttfError("Error when getting HEAD modified\n");
+ ttfReadULONG (head->created, 2, fp);
+ ttfReadULONG (head->modified, 2, fp);
head->xMin = ttfGetFWord(fp);
head->yMin = ttfGetFWord(fp);
@@ -61,16 +59,16 @@ void ttfPrintHEAD(FILE *fp,HEADPtr head)
fprintf(fp,"'head' Table - Font Header\n");
fprintf(fp,"--------------------------\n");
- fprintf(fp,"\t 'head' version:\t %2d.%2d\n",b1[1],b1[0]);
- fprintf(fp,"\t fontReversion:\t\t %2d.%2d\n",b2[1],b2[0]);
+ fprintf(fp,"\t 'head' version:\t %d.%d\n",b1[1],b1[0]);
+ fprintf(fp,"\t fontReversion:\t\t %d.%d\n",b2[1],b2[0]);
fprintf(fp,"\t checkSumAdjustment:\t 0x%08x\n",head->checkSumAdj);
fprintf(fp,"\t magicNumber:\t\t 0x%08x\n",head->magicNumber);
fprintf(fp,"\t flags:\t\t\t 0x%04x\n",head->flags);
fprintf(fp,"\t unitsPerEm:\t\t %d\n",head->unitsPerEm);
/* don't know how to compute */
- fprintf(fp,"\t created:\n");
- fprintf(fp,"\t modified:\n");
+ fprintf(fp,"\t created:\t\t 0x%08x%08x\n", head->created[0], head->created[1]);
+ fprintf(fp,"\t modified:\t\t 0x%08x%08x\n", head->modified[0], head->modified[1]);
fprintf(fp,"\t xMin:\t\t\t %d\n",head->xMin);
fprintf(fp,"\t yMin:\t\t\t %d\n",head->yMin);
diff --git a/Build/source/texk/ttfdump/libttf/hhea.c b/Build/source/texk/ttfdump/libttf/hhea.c
index 9b056dde6ab..3ec85c827d4 100644
--- a/Build/source/texk/ttfdump/libttf/hhea.c
+++ b/Build/source/texk/ttfdump/libttf/hhea.c
@@ -53,7 +53,7 @@ void ttfPrintHHEA(FILE *fp,HHEAPtr hhea)
fprintf(fp,"'hhea' Table - Horizontal Header\n");
fprintf(fp,"--------------------------\n");
- fprintf(fp,"\t 'hhea' version:\t %2d.%2d\n",b[1],b[0]);
+ fprintf(fp,"\t 'hhea' version:\t %d.%d\n",b[1],b[0]);
fprintf(fp,"\t yAscender:\t\t %d\n",hhea->Ascender);
fprintf(fp,"\t yDescender:\t\t %d\n",hhea->Descender);
fprintf(fp,"\t yLineGap:\t\t %d\n",hhea->LineGap);
diff --git a/Build/source/texk/ttfdump/libttf/loca.c b/Build/source/texk/ttfdump/libttf/loca.c
index 44ec5e05fcc..5342fbf20c3 100644
--- a/Build/source/texk/ttfdump/libttf/loca.c
+++ b/Build/source/texk/ttfdump/libttf/loca.c
@@ -59,20 +59,26 @@ void ttfPrintLOCA(FILE *fp,LOCAPtr loca)
{
USHORT i;
- fprintf(fp,"'loca' Table - Index to Location\n");
- fprintf(fp,"--------------------------------\n");
- for (i=0;i<loca->numGlyphs;i++)
- {
- fprintf(fp,"\t Idx %6d -> GlyphOffset 0x%08x\n",i,
- (loca->offset)[i]);
- }
- fprintf (fp,"\t Ended at 0x%08x\n",(loca->offset)[loca->numGlyphs]);
+ if (loca)
+ {
+ fprintf(fp,"'loca' Table - Index to Location\n");
+ fprintf(fp,"--------------------------------\n");
+ for (i=0;i<loca->numGlyphs;i++)
+ {
+ fprintf(fp,"\t Idx %6d -> GlyphOffset 0x%08x\n",i,
+ (loca->offset)[i]);
+ }
+ fprintf (fp,"\t Ended at 0x%08x\n",(loca->offset)[loca->numGlyphs]);
+ }
}
void ttfFreeLOCA(LOCAPtr loca)
{
- free (loca->offset);
- free (loca);
+ if (loca)
+ {
+ free (loca->offset);
+ free (loca);
+ }
}
ULONG ttfLookUpGlyfLOCA(LOCAPtr loca,USHORT idx)
diff --git a/Build/source/texk/ttfdump/libttf/maxp.c b/Build/source/texk/ttfdump/libttf/maxp.c
index cefa38a4c0d..1b36fb2690b 100644
--- a/Build/source/texk/ttfdump/libttf/maxp.c
+++ b/Build/source/texk/ttfdump/libttf/maxp.c
@@ -49,7 +49,7 @@ void ttfPrintMAXP(FILE *fp,MAXPPtr maxp)
fprintf(fp,"'maxp' Table - Maximum Profile\n");
fprintf(fp,"------------------------------\n");
- fprintf(fp,"\t 'maxp' version:\t %2d.%2d\n",b[1],b[0]);
+ fprintf(fp,"\t 'maxp' version:\t %d.%d\n",b[1],b[0]);
fprintf(fp,"\t numGlyphs:\t\t %d\n",maxp->numGlyphs);
fprintf(fp,"\t maxPoints:\t\t %d\n",maxp->maxPoints);
fprintf(fp,"\t maxContours:\t\t %d\n",maxp->maxContours);
diff --git a/Build/source/texk/ttfdump/libttf/otfcommon.c b/Build/source/texk/ttfdump/libttf/otfcommon.c
new file mode 100644
index 00000000000..8102aae6ab5
--- /dev/null
+++ b/Build/source/texk/ttfdump/libttf/otfcommon.c
@@ -0,0 +1,1074 @@
+/* otfcommon.c -- OpenType Common Table Formats
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include "config.h"
+#include "ttf.h"
+#include "ttfutil.h"
+
+static LangSysPtr
+otfMakeLangSys (FILE *fp, ULONG offset)
+{
+ LangSysPtr langSys = XCALLOC1 (LangSys);
+ USHORT lookupOrder;
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeLangSys");
+
+ if ((lookupOrder = ttfGetUSHORT (fp)) != 0)
+ ttfError ("Non-zero lookupOrder\n");
+ langSys->reqFeatureIndex = ttfGetUSHORT (fp);
+ langSys->featureCount = ttfGetUSHORT (fp);
+ langSys->featureIndex = ttfMakeUSHORT (langSys->featureCount, fp);
+
+ return langSys;
+}
+
+static void
+otfLoadScriptRecord (FILE *fp, ScriptRecordPtr scriptRecord, ULONG offset)
+{
+ int i;
+ USHORT dOffset;
+ USHORT *lOffset;
+
+ xfseek (fp, offset, SEEK_SET, "otfLoadScriptRecord");
+
+ dOffset = ttfGetUSHORT (fp);
+
+ scriptRecord->langSysCount = ttfGetUSHORT (fp);
+ if (scriptRecord->langSysCount) {
+ scriptRecord->langSysRecord = XCALLOC (scriptRecord->langSysCount, LangSysRecord);
+ lOffset = XTALLOC (scriptRecord->langSysCount, USHORT);
+
+ for (i = 0; i < scriptRecord->langSysCount; i++) {
+ scriptRecord->langSysRecord[i].tag = ttfGetULONG (fp);
+ lOffset[i] = ttfGetUSHORT (fp);
+ }
+
+ for (i = 0; i < scriptRecord->langSysCount; i++)
+ scriptRecord->langSysRecord[i].langSys = otfMakeLangSys (fp, offset + lOffset[i]);
+
+ free (lOffset);
+ }
+
+ if (dOffset)
+ scriptRecord->defaultLangSys = otfMakeLangSys (fp, offset + dOffset);
+}
+
+ScriptListPtr
+otfMakeScriptList (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *sOffset;
+ ScriptListPtr scriptList = XCALLOC1 (ScriptList);
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeScriptList");
+
+ scriptList->scriptCount = ttfGetUSHORT (fp);
+ scriptList->scriptRecord = XCALLOC (scriptList->scriptCount, ScriptRecord);
+ sOffset = XTALLOC (scriptList->scriptCount, USHORT);
+
+ for (i = 0; i < scriptList->scriptCount; i++) {
+ scriptList->scriptRecord[i].tag = ttfGetULONG (fp);
+ sOffset[i] = ttfGetUSHORT (fp);
+ }
+
+ for (i = 0; i < scriptList->scriptCount; i++)
+ otfLoadScriptRecord (fp, &scriptList->scriptRecord[i], offset + sOffset[i]);
+
+ free (sOffset);
+
+ return scriptList;
+}
+
+static void
+otfPrintLangSys (FILE *fp, LangSysPtr langSys)
+{
+ int i;
+
+ fprintf (fp, " lang - featureCount: %d\n", langSys->featureCount);
+ if (langSys->reqFeatureIndex != 0xffff)
+ fprintf (fp, "\t\t reqFeatureIndex: %d\n", langSys->reqFeatureIndex);
+ if (langSys->featureCount) {
+ fprintf (fp, "\t\t featureIndex: %d", langSys->featureIndex[0]);
+ for (i = 1; i < langSys->featureCount; i++)
+ fprintf (fp, i % 8 ? ", %d" : ",\n\t\t\t\t%d",
+ langSys->featureIndex[i]);
+ fprintf (fp, "\n");
+ }
+}
+
+static void
+otfPrintScriptRecord (FILE *fp, ScriptRecordPtr scriptRecord)
+{
+ int i;
+
+ fprintf (fp, "'%s' script - langSysCount: %d\n",
+ TagToStr (scriptRecord->tag), scriptRecord->langSysCount);
+ if (scriptRecord->defaultLangSys) {
+ fprintf (fp, "\t default");
+ otfPrintLangSys (fp, scriptRecord->defaultLangSys);
+ }
+ for (i = 0; i < scriptRecord->langSysCount; i++) {
+ fprintf (fp, " %2d. '%s'", i,
+ TagToStr (scriptRecord->langSysRecord[i].tag));
+ otfPrintLangSys (fp, scriptRecord->langSysRecord[i].langSys);
+ }
+}
+
+void
+otfPrintScriptList (FILE *fp, ScriptListPtr scriptList)
+{
+ int i;
+
+ fprintf (fp, " scriptCount: %d\n", scriptList->scriptCount);
+
+ for (i = 0; i < scriptList->scriptCount; i++) {
+ fprintf (fp, " %2d. ", i);
+ otfPrintScriptRecord (fp, &scriptList->scriptRecord[i]);
+ }
+ fprintf (fp, "\n");
+}
+
+static void
+otfFreeLangSys (LangSysPtr langSys)
+{
+ free (langSys->featureIndex);
+ free (langSys);
+}
+
+static void
+otfFreeScriptRecord (ScriptRecordPtr scriptRecord)
+{
+ int i;
+
+ if (scriptRecord->defaultLangSys)
+ otfFreeLangSys (scriptRecord->defaultLangSys);
+ for (i = 0; i < scriptRecord->langSysCount; i++)
+ otfFreeLangSys (scriptRecord->langSysRecord[i].langSys);
+ free (scriptRecord->langSysRecord);
+}
+
+void
+otfFreeScriptList (ScriptListPtr scriptList)
+{
+ int i;
+
+ for (i = 0; i < scriptList->scriptCount; i++)
+ otfFreeScriptRecord (&scriptList->scriptRecord[i]);
+ free (scriptList->scriptRecord);
+ free (scriptList);
+}
+
+static void
+otfLoadFeatureRecord (FILE *fp, FeatureRecordPtr featureRecord, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "otfLoadFeatureRecord");
+
+ featureRecord->featureParams = ttfGetUSHORT (fp);
+ featureRecord->lookupCount = ttfGetUSHORT (fp);
+ featureRecord->lookupListIndex = ttfMakeUSHORT (featureRecord->lookupCount, fp);
+}
+
+FeatureListPtr
+otfMakeFeatureList (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *fOffset;
+ FeatureListPtr featureList = XCALLOC1 (FeatureList);
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeFeatureList");
+
+ featureList->featureCount = ttfGetUSHORT (fp);
+ if (featureList->featureCount) {
+ featureList->featureRecord = XCALLOC (featureList->featureCount, FeatureRecord);
+ fOffset = XTALLOC (featureList->featureCount, USHORT);
+
+ for (i = 0; i < featureList->featureCount; i++) {
+ featureList->featureRecord[i].tag = ttfGetULONG (fp);
+ fOffset[i] = ttfGetUSHORT (fp);
+ }
+
+ for (i = 0; i < featureList->featureCount; i++)
+ otfLoadFeatureRecord (fp, &featureList->featureRecord[i], offset + fOffset[i]);
+
+ free (fOffset);
+ }
+
+ return featureList;
+}
+
+static void
+otfPrintFeatureRecord (FILE *fp, FeatureRecordPtr featureRecord)
+{
+ int i;
+
+ fprintf (fp, "'%s' feature - lookupCount: %d\n",
+ TagToStr (featureRecord->tag), featureRecord->lookupCount);
+ fprintf (fp, "\t\tlookupListIndex: %d", featureRecord->lookupListIndex[0]);
+ for (i = 1; i < featureRecord->lookupCount; i++)
+ fprintf (fp, i % 8 ? ", %d" : ",\n\t\t\t\t %d",
+ featureRecord->lookupListIndex[i]);
+ fprintf (fp, "\n");
+ if (featureRecord->featureParams)
+ fprintf (fp, "\t\tfeatureParams Offset: 0x%04x\n", featureRecord->featureParams);
+}
+
+void
+otfPrintFeatureList (FILE *fp, FeatureListPtr featureList)
+{
+ int i;
+
+ fprintf (fp, " featureCount: %d\n", featureList->featureCount);
+
+ for (i = 0; i < featureList->featureCount; i++) {
+ fprintf (fp, " %2d. ", i);
+ otfPrintFeatureRecord (fp, &featureList->featureRecord[i]);
+ }
+ fprintf (fp, "\n");
+}
+
+void
+otfFreeFeatureList (FeatureListPtr featureList)
+{
+ int i;
+
+ if (featureList->featureCount) {
+ for (i = 0; i < featureList->featureCount; i++)
+ free (featureList->featureRecord[i].lookupListIndex);
+ free (featureList->featureRecord);
+ }
+ free (featureList);
+}
+
+static void
+otfLoadLookupRecord (FILE *fp, LookupRecordPtr lookupRecord, ULONG offset, MakeLookupFunc makeLookup)
+{
+ int i;
+ USHORT lookupType;
+ USHORT *lOffset;
+
+ xfseek (fp, offset, SEEK_SET, "otfLoadLookupRecord");
+
+ lookupType = ttfGetUSHORT (fp);
+ lookupRecord->lookupFlag = ttfGetUSHORT (fp);
+ lookupRecord->subTableCount = ttfGetUSHORT (fp);
+ lookupRecord->lookup = XCALLOC (lookupRecord->subTableCount, LookupPtr);
+ lOffset = ttfMakeUSHORT (lookupRecord->subTableCount, fp);
+ if (lookupRecord->lookupFlag & lookupFlag_UseMarkFilteringSet)
+ lookupRecord->markFilteringSet = ttfGetUSHORT (fp);
+ for (i = 0; i < lookupRecord->subTableCount; i++)
+ lookupRecord->lookup[i] = (*makeLookup) (fp, lookupType, offset + lOffset[i]);
+ free (lOffset);
+}
+
+LookupListPtr
+otfMakeLookupList (FILE *fp, ULONG offset, MakeLookupFunc makeLookup)
+{
+ int i;
+ USHORT *lOffset;
+ LookupListPtr lookupList = XCALLOC1 (LookupList);
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeLookupList");
+
+ lookupList->lookupCount = ttfGetUSHORT (fp);
+ if (lookupList->lookupCount) {
+ lookupList->lookupRecord = XCALLOC (lookupList->lookupCount, LookupRecord);
+ lOffset = ttfMakeUSHORT (lookupList->lookupCount, fp);
+
+ for (i = 0; i < lookupList->lookupCount; i++)
+ otfLoadLookupRecord (fp, &lookupList->lookupRecord[i], offset + lOffset[i], makeLookup);
+
+ free (lOffset);
+ }
+
+ return lookupList;
+}
+
+void
+otfPrintLookupList (FILE *fp, LookupListPtr lookupList, PrintLookupFunc printLookup)
+{
+ int i;
+
+ fprintf (fp, " lookupCount: %d\n", lookupList->lookupCount);
+
+ for (i = 0; i < lookupList->lookupCount; i++) {
+ int j;
+
+ fprintf (fp, " %2d. lookupType: %d, lookupFlag: 0x%04x", i,
+ lookupList->lookupRecord[i].lookup[0].otf->lookupType,
+ lookupList->lookupRecord[i].lookupFlag);
+ if (lookupList->lookupRecord[i].lookupFlag & lookupFlag_UseMarkFilteringSet)
+ fprintf (fp, ", markFilteringSet: %d", lookupList->lookupRecord[i].markFilteringSet);
+ fprintf (fp, "\n\tsubTableCount:\t%d\n", lookupList->lookupRecord[i].subTableCount);
+ for (j = 0; j < lookupList->lookupRecord[i].subTableCount; j++) {
+ fprintf (fp, " %2d. lookupFormat: %d", j,
+ lookupList->lookupRecord[i].lookup[j].otf->lookupFormat);
+ (*printLookup) (fp, lookupList->lookupRecord[i].lookup[j]);
+ }
+ }
+ fprintf (fp, "\n");
+}
+
+void
+otfFreeLookupList (LookupListPtr lookupList, FreeLookupFunc freeLookup)
+{
+ int i;
+
+ if (lookupList->lookupCount) {
+ for (i = 0; i < lookupList->lookupCount; i++) {
+ int j;
+
+ for (j = 0; j < lookupList->lookupRecord[i].subTableCount; j++) {
+ (*freeLookup) (lookupList->lookupRecord[i].lookup[j]);
+ free (lookupList->lookupRecord[i].lookup[j].otf);
+ }
+ free (lookupList->lookupRecord[i].lookup);
+ }
+ free (lookupList->lookupRecord);
+ }
+ free (lookupList);
+}
+
+CoveragePtr
+otfMakeCoverage (FILE *fp, ULONG offset)
+{
+ CoveragePtr coverage;
+ int i;
+ USHORT format;
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeCoverage");
+
+ format = ttfGetUSHORT (fp);
+ switch (format)
+ {
+ case 1:
+ coverage.coverage1 = XCALLOC1 (Coverage1);
+ coverage.coverage1->glyphCount = ttfGetUSHORT (fp);
+ coverage.coverage1->glyphArray = ttfMakeUSHORT (coverage.coverage1->glyphCount, fp);
+ break;
+ case 2:
+ coverage.coverage2 = XCALLOC1 (Coverage2);
+ coverage.coverage2->rangeCount = ttfGetUSHORT (fp);
+ coverage.coverage2->rangeRecord = XTALLOC (coverage.coverage2->rangeCount, RangeRecord);
+ for (i = 0; i < coverage.coverage2->rangeCount; i++) {
+ coverage.coverage2->rangeRecord[i].start = ttfGetUSHORT (fp);
+ coverage.coverage2->rangeRecord[i].end = ttfGetUSHORT (fp);
+ coverage.coverage2->rangeRecord[i].startCoverageIndex = ttfGetUSHORT (fp);
+ }
+ break;
+ default:
+ ttfError ("Unrecognized coverageFormat\n");
+ }
+
+ *coverage.format = format;
+ return coverage;
+}
+
+void
+otfPrintCoverage (FILE *fp, CoveragePtr coverage)
+{
+ int i;
+
+ fprintf (fp, "Coverage - ");
+ switch (*coverage.format)
+ {
+ case 1:
+ fprintf (fp, "glyphCount: %d\n\t\t glyphArray: %d",
+ coverage.coverage1->glyphCount, coverage.coverage1->glyphArray[0]);
+ for (i = 1; i < coverage.coverage1->glyphCount; i++)
+ fprintf (fp, i % 8 ? ", %d" : ",\n\t\t\t %d",
+ coverage.coverage1->glyphArray[i]);
+ fprintf (fp, "\n");
+ break;
+ case 2:
+ fprintf (fp, "rangeCount: %d\n", coverage.coverage2->rangeCount);
+ for (i = 0; i < coverage.coverage2->rangeCount; i++) {
+ fprintf (fp, "\t %2d. start: %d, end: %d, startCoverageIndex: %d\n", i,
+ coverage.coverage2->rangeRecord[i].start,
+ coverage.coverage2->rangeRecord[i].end,
+ coverage.coverage2->rangeRecord[i].startCoverageIndex);
+ }
+ break;
+ default:
+ ttfError ("Internal error: otfPrintCoverage\n");
+ }
+}
+
+void
+otfFreeCoverage (CoveragePtr coverage)
+{
+ switch (*coverage.format)
+ {
+ case 1:
+ free (coverage.coverage1->glyphArray);
+ break;
+ case 2:
+ free (coverage.coverage2->rangeRecord);
+ break;
+ default:
+ ttfError ("Internal error: otfFreeCoverage\n");
+ }
+ free (coverage.format);
+}
+
+ClassDefPtr
+otfMakeClassDef (FILE *fp, ULONG offset)
+{
+ ClassDefPtr classDef;
+ int i;
+ USHORT format;
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeClassDef");
+
+ format = ttfGetUSHORT (fp);
+ switch (format)
+ {
+ case 1:
+ classDef.classDef1 = XCALLOC1 (ClassDef1);
+ classDef.classDef1->startGlyph = ttfGetUSHORT (fp);
+ classDef.classDef1->glyphCount = ttfGetUSHORT (fp);
+ classDef.classDef1->classValueArray = ttfMakeUSHORT (classDef.classDef1->glyphCount, fp);
+ break;
+ case 2:
+ classDef.classDef2 = XCALLOC1 (ClassDef2);
+ classDef.classDef2->classRangeCount = ttfGetUSHORT (fp);
+ classDef.classDef2->classRangeRecord = XTALLOC (classDef.classDef2->classRangeCount, ClassRangeRecord);
+ for (i = 0; i < classDef.classDef2->classRangeCount; i++) {
+ classDef.classDef2->classRangeRecord[i].start = ttfGetUSHORT (fp);
+ classDef.classDef2->classRangeRecord[i].end = ttfGetUSHORT (fp);
+ classDef.classDef2->classRangeRecord[i].classValue = ttfGetUSHORT (fp);
+ }
+ break;
+ default:
+ ttfError ("Unrecognized classDefFormat\n");
+ }
+
+ *classDef.format = format;
+ return classDef;
+}
+
+void
+otfPrintClassDef (FILE *fp, ClassDefPtr classDef)
+{
+ int i;
+
+ switch (*classDef.format)
+ {
+ case 1:
+ fprintf (fp, "startGlyph: %d, glyphCount: %d\n\t\tclassValueArray ",
+ classDef.classDef1->startGlyph, classDef.classDef1->glyphCount);
+ for (i = 0; i < classDef.classDef1->glyphCount; i++)
+ fprintf (fp, i == 0 ? "- %d" : i % 8 ? ", %d" : ",\n\t\t\t\t %d",
+ classDef.classDef1->classValueArray[i]);
+ fprintf (fp, "\n");
+ break;
+ case 2:
+ fprintf (fp, "classRangeCount: %d\n", classDef.classDef2->classRangeCount);
+ for (i = 0; i < classDef.classDef2->classRangeCount; i++)
+ fprintf (fp, "\t\t%2d. start: %d, end: %d, classValue: %d\n", i,
+ classDef.classDef2->classRangeRecord[i].start,
+ classDef.classDef2->classRangeRecord[i].end,
+ classDef.classDef2->classRangeRecord[i].classValue);
+ break;
+ default:
+ ttfError ("Internal error: otfPrintClassDef\n");
+ }
+}
+
+void
+otfFreeClassDef (ClassDefPtr classDef)
+{
+ switch (*classDef.format)
+ {
+ case 1:
+ free (classDef.classDef1->classValueArray);
+ break;
+ case 2:
+ free (classDef.classDef2->classRangeRecord);
+ break;
+ default:
+ ttfError ("Internal error: otfFreeClassDef\n");
+ }
+ free (classDef.format);
+}
+
+DevicePtr
+otfMakeDevice (FILE *fp, ULONG offset)
+{
+ size_t num;
+ DevicePtr device;
+ USHORT startSize, endSize, deltaFormat;
+
+ xfseek (fp, offset, SEEK_SET, "otfMakeDevice");
+
+ startSize = ttfGetUSHORT (fp);
+ endSize = ttfGetUSHORT (fp);
+ deltaFormat = ttfGetUSHORT (fp);
+ if (deltaFormat < 1 || deltaFormat > 3)
+ ttfError ("Unrecognized deltaFormat\n");
+ num = (endSize - startSize) >> (4 - deltaFormat);
+ device = (DevicePtr) xcalloc (1, sizeof (Device) + num * sizeof (USHORT));
+ device->startSize = startSize;
+ device->endSize = endSize;
+ device->deltaFormat = deltaFormat;
+ ttfReadUSHORT (device->deltaValue, num + 1, fp);
+
+ return device;
+}
+
+void
+otfPrintDevice (FILE *fp, DevicePtr device)
+{
+ int i;
+ size_t num = (device->endSize - device->startSize) >> (4 - device->deltaFormat);
+
+ fprintf (fp, "startSize = %d, endSize = %d, deltaFormat = %d, deltaValue = 0x",
+ device->startSize, device->endSize, device->deltaFormat);
+ for (i = 0; i < num; i++)
+ fprintf (fp, "%04x", device->deltaValue[i]);
+ fprintf (fp, "%04x\n", device->deltaValue[num]);
+}
+
+static OtfLookupRecordPtr
+makeOtfLookupRecord (USHORT otfCount, FILE *fp)
+{
+ int i;
+ OtfLookupRecordPtr otf = XCALLOC (otfCount, OtfLookupRecord);
+
+ for (i = 0; i < otfCount; i++) {
+ otf[i].sequenceIndex = ttfGetUSHORT (fp);
+ otf[i].lookupListIndex = ttfGetUSHORT (fp);
+ }
+ return otf;
+}
+
+static void
+printOtfLookupRecord (FILE * fp, const char *str, USHORT otfCount, OtfLookupRecordPtr otf)
+{
+ int i;
+
+ fprintf (fp, "\t%sotfCount: %d\n", str, otfCount);
+ for (i = 0; i < otfCount; i++)
+ fprintf (fp, "\t%s%2d. sequenceIndex: %d, lookupListIndex: %d\n",
+ str, i, otf[i].sequenceIndex, otf[i].lookupListIndex);
+}
+
+static void loadOtfRule (OtfRulePtr otfRule, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "loadOtfRule");
+
+ otfRule->glyphCount = ttfGetUSHORT (fp);
+ otfRule->otfCount = ttfGetUSHORT (fp);
+ otfRule->input = ttfMakeUSHORT (otfRule->glyphCount - 1, fp);
+ otfRule->otf = makeOtfLookupRecord (otfRule->otfCount, fp);
+}
+
+static void loadOtfRuleSet (OtfRuleSetPtr otfRuleSet, FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *pOffset;
+
+ xfseek (fp, offset, SEEK_SET, "loadOtfRuleSet");
+
+ otfRuleSet->otfRuleCount = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otfRuleSet->otfRuleCount, fp);
+ otfRuleSet->otfRule = XCALLOC (otfRuleSet->otfRuleCount, OtfRule);
+ for (i = 0; i < otfRuleSet->otfRuleCount; i++)
+ loadOtfRule (&otfRuleSet->otfRule[i], fp, offset + pOffset[i]);
+ free (pOffset);
+}
+
+OtfCtx1Ptr makeOTFCtx1 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT *pOffset;
+ OtfCtx1Ptr otf = XCALLOC1 (OtfCtx1);
+
+ cOffset = ttfGetUSHORT (fp);
+ otf->otfRuleSetCount = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otf->otfRuleSetCount, fp);
+ otf->otfRuleSet = XCALLOC (otf->otfRuleSetCount, OtfRuleSet);
+ otf->coverage = otfMakeCoverage (fp, offset + cOffset);
+ for (i = 0; i < otf->otfRuleSetCount; i++)
+ loadOtfRuleSet (&otf->otfRuleSet[i], fp, offset + pOffset[i]);
+ free (pOffset);
+
+ return otf;
+}
+
+void printOTFCtx1 (FILE *fp, OtfCtx1Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Context Simple\n\t ");
+ otfPrintCoverage (fp, otf->coverage);
+ fprintf (fp, "\t otfRuleSetCount: %d\n", otf->otfRuleSetCount);
+ for (i = 0; i < otf->otfRuleSetCount; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. otfRuleCount: %d\n", i, otf->otfRuleSet[i].otfRuleCount);
+ for (j = 0; j < otf->otfRuleSet[i].otfRuleCount; j++) {
+ int k;
+
+ fprintf (fp, "\t %2d. glyphtCount: %d ", j,
+ otf->otfRuleSet[i].otfRule[j].glyphCount);
+ for (k = 0; k < otf->otfRuleSet[i].otfRule[j].glyphCount - 1; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", otf->otfRuleSet[i].otfRule[j].input[k]);
+ fprintf (fp, "\n");
+ printOtfLookupRecord (fp, " ",
+ otf->otfRuleSet[i].otfRule[j].otfCount,
+ otf->otfRuleSet[i].otfRule[j].otf);
+ }
+ }
+}
+
+void freeOTFCtx1 (OtfCtx1Ptr otf)
+{
+ int i;
+
+ otfFreeCoverage (otf->coverage);
+ for (i = 0; i < otf->otfRuleSetCount; i++) {
+ int j;
+
+ for (j = 0; j < otf->otfRuleSet[i].otfRuleCount; j++) {
+ free (otf->otfRuleSet[i].otfRule[j].input);
+ free (otf->otfRuleSet[i].otfRule[j].otf);
+ }
+ free (otf->otfRuleSet[i].otfRule);
+ }
+ free (otf->otfRuleSet);
+}
+
+static void loadOtfClassRule (OtfClassRulePtr otfClassRule, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "loadOtfClassRule");
+
+ otfClassRule->glyphCount = ttfGetUSHORT (fp);
+ otfClassRule->otfCount = ttfGetUSHORT (fp);
+ otfClassRule->class = ttfMakeUSHORT (otfClassRule->glyphCount - 1, fp);
+ otfClassRule->otf = makeOtfLookupRecord (otfClassRule->otfCount, fp);
+}
+
+static void loadOtfClassSet (OtfClassSetPtr otfClassSet, FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *pOffset;
+
+ xfseek (fp, offset, SEEK_SET, "loadOtfClassSet");
+
+ otfClassSet->otfClassRuleCnt = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otfClassSet->otfClassRuleCnt, fp);
+ otfClassSet->otfClassRule = XCALLOC (otfClassSet->otfClassRuleCnt, OtfClassRule);
+ for (i = 0; i < otfClassSet->otfClassRuleCnt; i++)
+ loadOtfClassRule (&otfClassSet->otfClassRule[i], fp, offset + pOffset[i]);
+ free (pOffset);
+}
+
+OtfCtx2Ptr makeOTFCtx2 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT clOffset;
+ USHORT *pOffset;
+ OtfCtx2Ptr otf = XCALLOC1 (OtfCtx2);
+
+ cOffset = ttfGetUSHORT (fp);
+ clOffset = ttfGetUSHORT (fp);
+ otf->otfClassSetCnt = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otf->otfClassSetCnt, fp);
+ otf->otfClassSet = XCALLOC (otf->otfClassSetCnt, OtfClassSet);
+ otf->coverage = otfMakeCoverage (fp, offset + cOffset);
+ otf->classDef = otfMakeClassDef (fp, offset + clOffset);
+ for (i = 0; i < otf->otfClassSetCnt; i++)
+ if (pOffset[i])
+ loadOtfClassSet (&otf->otfClassSet[i], fp, offset + pOffset[i]);
+ free (pOffset);
+
+ return otf;
+}
+
+void printOTFCtx2 (FILE *fp, OtfCtx2Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Context Class-based\n\t ");
+ otfPrintCoverage (fp, otf->coverage);
+ fprintf (fp, "\t ClassDef - ");
+ otfPrintClassDef (fp, otf->classDef);
+ fprintf (fp, "\t otfClassSetCnt: %d\n", otf->otfClassSetCnt);
+ for (i = 0; i < otf->otfClassSetCnt; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. otfClassRuleCnt: %d\n", i, otf->otfClassSet[i].otfClassRuleCnt);
+ for (j = 0; j < otf->otfClassSet[i].otfClassRuleCnt; j++) {
+ int k;
+
+ fprintf (fp, "\t %2d. glyphtCount: %d ", j,
+ otf->otfClassSet[i].otfClassRule[j].glyphCount);
+ for (k = 0; k < otf->otfClassSet[i].otfClassRule[j].glyphCount - 1; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", otf->otfClassSet[i].otfClassRule[j].class[k]);
+ fprintf (fp, "\n");
+ printOtfLookupRecord (fp, " ",
+ otf->otfClassSet[i].otfClassRule[j].otfCount,
+ otf->otfClassSet[i].otfClassRule[j].otf);
+ }
+ }
+}
+
+void freeOTFCtx2 (OtfCtx2Ptr otf)
+{
+ int i;
+
+ otfFreeCoverage (otf->coverage);
+ otfFreeClassDef (otf->classDef);
+ for (i = 0; i < otf->otfClassSetCnt; i++) {
+ int j;
+
+ for (j = 0; j < otf->otfClassSet[i].otfClassRuleCnt; j++) {
+ free (otf->otfClassSet[i].otfClassRule[j].class);
+ free (otf->otfClassSet[i].otfClassRule[j].otf);
+ }
+ free (otf->otfClassSet[i].otfClassRule);
+ }
+ free (otf->otfClassSet);
+}
+
+OtfCtx3Ptr makeOTFCtx3 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *gOffset;
+ OtfCtx3Ptr otf = XCALLOC1 (OtfCtx3);
+
+ otf->glyphCount = ttfGetUSHORT (fp);
+ otf->otfCount = ttfGetUSHORT (fp);
+ gOffset = ttfMakeUSHORT (otf->glyphCount, fp);
+ otf->otf = makeOtfLookupRecord (otf->otfCount, fp);
+ otf->glyphs = XCALLOC (otf->glyphCount, CoveragePtr);
+ for (i = 0; i < otf->glyphCount; i++)
+ otf->glyphs[i] = otfMakeCoverage (fp, offset + gOffset[i]);
+ free (gOffset);
+
+ return otf;
+}
+
+void printOTFCtx3 (FILE *fp, OtfCtx3Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Context Coverage-based\n");
+ fprintf (fp, "\t glyphCount: %d\n", otf->glyphCount);
+ for (i = 0; i < otf->glyphCount; i++) {
+ fprintf (fp, "\t %2d. ", i);
+ otfPrintCoverage (fp, otf->glyphs[i]);
+ }
+ printOtfLookupRecord (fp, " ", otf->otfCount, otf->otf);
+}
+
+void freeOTFCtx3 (OtfCtx3Ptr otf)
+{
+ int i;
+
+ for (i = 0; i < otf->glyphCount; i++)
+ otfFreeCoverage (otf->glyphs[i]);
+ free (otf->glyphs);
+ free (otf->otf);
+}
+
+static void
+loadChainOtfRule (ChainOtfRulePtr chainOtfRule, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "loadChainOtfRule");
+
+ chainOtfRule->backtrackGlyphCount = ttfGetUSHORT (fp);
+ chainOtfRule->backtrack = ttfMakeUSHORT (chainOtfRule->backtrackGlyphCount, fp);
+ chainOtfRule->inputGlyphCount = ttfGetUSHORT (fp);
+ chainOtfRule->input = ttfMakeUSHORT (chainOtfRule->inputGlyphCount - 1, fp);
+ chainOtfRule->lookaheadGlyphCount = ttfGetUSHORT (fp);
+ chainOtfRule->lookahead = ttfMakeUSHORT (chainOtfRule->lookaheadGlyphCount, fp);
+ chainOtfRule->otfCount = ttfGetUSHORT (fp);
+ chainOtfRule->otf = makeOtfLookupRecord (chainOtfRule->otfCount, fp);
+}
+
+static void
+loadChainOtfRuleSet (ChainOtfRuleSetPtr chainOtfRuleSet, FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *pOffset;
+
+ xfseek (fp, offset, SEEK_SET, "loadChainOtfRuleSet");
+
+ chainOtfRuleSet->chainOtfRuleCount = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (chainOtfRuleSet->chainOtfRuleCount, fp);
+ chainOtfRuleSet->chainOtfRule = XCALLOC (chainOtfRuleSet->chainOtfRuleCount, ChainOtfRule);
+ for (i = 0; i < chainOtfRuleSet->chainOtfRuleCount; i++)
+ loadChainOtfRule (&chainOtfRuleSet->chainOtfRule[i], fp, offset + pOffset[i]);
+ free (pOffset);
+}
+
+OtfChn1Ptr makeOTFChn1 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT *pOffset;
+ OtfChn1Ptr otf = XCALLOC1 (OtfChn1);
+
+ cOffset = ttfGetUSHORT (fp);
+ otf->chainOtfRuleSetCount = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otf->chainOtfRuleSetCount, fp);
+ otf->coverage = otfMakeCoverage (fp, offset + cOffset);
+ otf->chainOtfRuleSet = XCALLOC (otf->chainOtfRuleSetCount, ChainOtfRuleSet);
+ for (i = 0; i < otf->chainOtfRuleSetCount; i++)
+ loadChainOtfRuleSet (&otf->chainOtfRuleSet[i], fp, offset + pOffset[i]);
+ free (pOffset);
+
+ return otf;
+}
+
+void printOTFChn1 (FILE *fp, OtfChn1Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Chained Context Simple\n\t ");
+ otfPrintCoverage (fp, otf->coverage);
+ fprintf (fp, "\t chainOtfRuleSetCount: %d\n", otf->chainOtfRuleSetCount);
+ for (i = 0; i < otf->chainOtfRuleSetCount; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. chainOtfRuleCount: %d\n", i,
+ otf->chainOtfRuleSet[i].chainOtfRuleCount);
+ for (j = 0; j < otf->chainOtfRuleSet[i].chainOtfRuleCount; j++) {
+ int k;
+
+ fprintf (fp, "\t %2d. backtrackGlyphCount: %d ", j,
+ otf->chainOtfRuleSet[i].chainOtfRule[j].backtrackGlyphCount);
+ for (k = 0; k < otf->chainOtfRuleSet[i].chainOtfRule[j].backtrackGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", otf->chainOtfRuleSet[i].chainOtfRule[j].backtrack[k]);
+ fprintf (fp, "\n\t\tinputGlyphCount: %d ",
+ otf->chainOtfRuleSet[i].chainOtfRule[j].inputGlyphCount);
+ for (k = 0; k < otf->chainOtfRuleSet[i].chainOtfRule[j].inputGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", otf->chainOtfRuleSet[i].chainOtfRule[j].input[k]);
+ fprintf (fp, "\n\t\tlookaheadGlyphCount: %d ",
+ otf->chainOtfRuleSet[i].chainOtfRule[j].lookaheadGlyphCount);
+ for (k = 0; k < otf->chainOtfRuleSet[i].chainOtfRule[j].lookaheadGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : ", %d", otf->chainOtfRuleSet[i].chainOtfRule[j].lookahead[k]);
+ fprintf (fp, "\n");
+ printOtfLookupRecord (fp, " ",
+ otf->chainOtfRuleSet[i].chainOtfRule[j].otfCount,
+ otf->chainOtfRuleSet[i].chainOtfRule[j].otf);
+ }
+ }
+}
+
+void freeOTFChn1 (OtfChn1Ptr otf)
+{
+ int i;
+
+ otfFreeCoverage (otf->coverage);
+ for (i = 0; i < otf->chainOtfRuleSetCount; i++) {
+ int j;
+
+ for (j = 0; j < otf->chainOtfRuleSet[i].chainOtfRuleCount; j++) {
+ free (otf->chainOtfRuleSet[i].chainOtfRule[j].backtrack);
+ free (otf->chainOtfRuleSet[i].chainOtfRule[j].input);
+ free (otf->chainOtfRuleSet[i].chainOtfRule[j].lookahead);
+ free (otf->chainOtfRuleSet[i].chainOtfRule[j].otf);
+ }
+ free (otf->chainOtfRuleSet[i].chainOtfRule);
+ }
+ free (otf->chainOtfRuleSet);
+}
+
+static void
+loadChainOtfClassRule (ChainOtfClassRulePtr chainOtfClassRule, FILE *fp, ULONG offset)
+{
+ xfseek (fp, offset, SEEK_SET, "loadChainOtfClassRule");
+
+ chainOtfClassRule->backtrackGlyphCount = ttfGetUSHORT (fp);
+ chainOtfClassRule->backtrack = ttfMakeUSHORT (chainOtfClassRule->backtrackGlyphCount, fp);
+ chainOtfClassRule->inputGlyphCount = ttfGetUSHORT (fp);
+ chainOtfClassRule->input = ttfMakeUSHORT (chainOtfClassRule->inputGlyphCount - 1, fp);
+ chainOtfClassRule->lookaheadGlyphCount = ttfGetUSHORT (fp);
+ chainOtfClassRule->lookahead = ttfMakeUSHORT (chainOtfClassRule->lookaheadGlyphCount, fp);
+ chainOtfClassRule->otfCount = ttfGetUSHORT (fp);
+ chainOtfClassRule->otf = makeOtfLookupRecord (chainOtfClassRule->otfCount, fp);
+}
+
+static void
+loadChainOtfClassSet (ChainOtfClassSetPtr chainOtfClassSet, FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *pOffset;
+
+ xfseek (fp, offset, SEEK_SET, "loadChainOtfClassSet");
+
+ chainOtfClassSet->chainOtfClassRuleCnt = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (chainOtfClassSet->chainOtfClassRuleCnt, fp);
+ chainOtfClassSet->chainOtfClassRule = XCALLOC (chainOtfClassSet->chainOtfClassRuleCnt, ChainOtfClassRule);
+ for (i = 0; i < chainOtfClassSet->chainOtfClassRuleCnt; i++)
+ loadChainOtfClassRule (&chainOtfClassSet->chainOtfClassRule[i], fp, offset + pOffset[i]);
+ free (pOffset);
+}
+
+OtfChn2Ptr makeOTFChn2 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT cOffset;
+ USHORT bOffset, iOffset, lOffset;
+ USHORT *pOffset;
+ OtfChn2Ptr otf = XCALLOC1 (OtfChn2);
+
+ cOffset = ttfGetUSHORT (fp);
+ bOffset = ttfGetUSHORT (fp);
+ iOffset = ttfGetUSHORT (fp);
+ lOffset = ttfGetUSHORT (fp);
+ otf->chainOtfClassSetCnt = ttfGetUSHORT (fp);
+ pOffset = ttfMakeUSHORT (otf->chainOtfClassSetCnt, fp);
+ otf->coverage = otfMakeCoverage (fp, offset + cOffset);
+ otf->backtrackClassDef = otfMakeClassDef (fp, offset + bOffset);
+ otf->inputClassDef = otfMakeClassDef (fp, offset + iOffset);
+ otf->lookaheadClassDef = otfMakeClassDef (fp, offset + lOffset);
+ otf->chainOtfClassSet = XCALLOC (otf->chainOtfClassSetCnt, ChainOtfClassSet);
+ for (i = 0; i < otf->chainOtfClassSetCnt; i++)
+ if (pOffset[i])
+ loadChainOtfClassSet (&otf->chainOtfClassSet[i], fp, offset + pOffset[i]);
+ free (pOffset);
+
+ return otf;
+}
+
+void printOTFChn2 (FILE *fp, OtfChn2Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Chained Context Class-based\n\t ");
+ otfPrintCoverage (fp, otf->coverage);
+ fprintf (fp, "\t backtrackClassDef - ");
+ otfPrintClassDef (fp, otf->backtrackClassDef);
+ fprintf (fp, "\t inputClassDef - ");
+ otfPrintClassDef (fp, otf->inputClassDef);
+ fprintf (fp, "\t lookaheadClassDef - ");
+ otfPrintClassDef (fp, otf->lookaheadClassDef);
+ fprintf (fp, "\t chainOtfClassSetCnt: %d\n", otf->chainOtfClassSetCnt);
+ for (i = 0; i < otf->chainOtfClassSetCnt; i++) {
+ int j;
+
+ fprintf (fp, "\t %2d. chainOtfClassRuleCnt: %d\n", i,
+ otf->chainOtfClassSet[i].chainOtfClassRuleCnt);
+ for (j = 0; j < otf->chainOtfClassSet[i].chainOtfClassRuleCnt; j++) {
+ int k;
+
+ fprintf (fp, "\t %2d. backtrackGlyphCount: %2d ", j,
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].backtrackGlyphCount);
+ for (k = 0; k < otf->chainOtfClassSet[i].chainOtfClassRule[j].backtrackGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : k % 8 ? ", %d" : ",\n\t\t\t\t\t %d",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].backtrack[k]);
+ fprintf (fp, "\n\t\tinputGlyphCount: %2d ",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].inputGlyphCount);
+ for (k = 0; k < otf->chainOtfClassSet[i].chainOtfClassRule[j].inputGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : k % 8 ? ", %d" : ",\n\t\t\t\t %d",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].input[k]);
+ fprintf (fp, "\n\t\tlookaheadGlyphCount: %2d ",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].lookaheadGlyphCount);
+ for (k = 0; k < otf->chainOtfClassSet[i].chainOtfClassRule[j].lookaheadGlyphCount; k++)
+ fprintf (fp, k == 0 ? "- %d" : k % 8 ? ", %d" : ",\n\t\t\t\t\t %d",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].lookahead[k]);
+ fprintf (fp, "\n");
+ printOtfLookupRecord (fp, " ",
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].otfCount,
+ otf->chainOtfClassSet[i].chainOtfClassRule[j].otf);
+ }
+ }
+}
+
+void freeOTFChn2 (OtfChn2Ptr otf)
+{
+ int i;
+
+ otfFreeCoverage (otf->coverage);
+ otfFreeClassDef (otf->backtrackClassDef);
+ otfFreeClassDef (otf->inputClassDef);
+ otfFreeClassDef (otf->lookaheadClassDef);
+ for (i = 0; i < otf->chainOtfClassSetCnt; i++) {
+ int j;
+
+ for (j = 0; j < otf->chainOtfClassSet[i].chainOtfClassRuleCnt; j++) {
+ free (otf->chainOtfClassSet[i].chainOtfClassRule[j].backtrack);
+ free (otf->chainOtfClassSet[i].chainOtfClassRule[j].input);
+ free (otf->chainOtfClassSet[i].chainOtfClassRule[j].lookahead);
+ free (otf->chainOtfClassSet[i].chainOtfClassRule[j].otf);
+ }
+ free (otf->chainOtfClassSet[i].chainOtfClassRule);
+ }
+ free (otf->chainOtfClassSet);
+}
+
+OtfChn3Ptr makeOTFChn3 (FILE *fp, ULONG offset)
+{
+ int i;
+ USHORT *bOffset, *iOffset, *lOffset;
+ OtfChn3Ptr otf = XCALLOC1 (OtfChn3);
+
+ otf->backtrackGlyphCount = ttfGetUSHORT (fp);
+ bOffset = ttfMakeUSHORT (otf->backtrackGlyphCount, fp);
+ otf->inputGlyphCount = ttfGetUSHORT (fp);
+ iOffset = ttfMakeUSHORT (otf->inputGlyphCount, fp);
+ otf->lookaheadGlyphCount = ttfGetUSHORT (fp);
+ lOffset = ttfMakeUSHORT (otf->lookaheadGlyphCount, fp);
+ otf->otfCount = ttfGetUSHORT (fp);
+ otf->otf = makeOtfLookupRecord (otf->otfCount, fp);
+ otf->backtrack = XCALLOC (otf->backtrackGlyphCount, CoveragePtr);
+ for (i = 0; i < otf->backtrackGlyphCount; i++)
+ otf->backtrack[i] = otfMakeCoverage (fp, offset + bOffset[i]);
+ free (bOffset);
+ otf->input = XCALLOC (otf->inputGlyphCount, CoveragePtr);
+ for (i = 0; i < otf->inputGlyphCount; i++)
+ otf->input[i] = otfMakeCoverage (fp, offset + iOffset[i]);
+ free (iOffset);
+ otf->lookahead = XCALLOC (otf->lookaheadGlyphCount, CoveragePtr);
+ for (i = 0; i < otf->lookaheadGlyphCount; i++)
+ otf->lookahead[i] = otfMakeCoverage (fp, offset + lOffset[i]);
+ free (lOffset);
+
+ return otf;
+}
+
+void printOTFChn3 (FILE *fp, OtfChn3Ptr otf)
+{
+ int i;
+
+ fprintf (fp, " - Chained Context Coverage-based\n");
+ fprintf (fp, "\t backtrackGlyphCount: %d\n", otf->backtrackGlyphCount);
+ for (i = 0; i < otf->backtrackGlyphCount; i++) {
+ fprintf (fp, "\t %2d. backtrack", i);
+ otfPrintCoverage (fp, otf->backtrack[i]);
+ }
+ fprintf (fp, "\t inputGlyphCount: %d\n", otf->inputGlyphCount);
+ for (i = 0; i < otf->inputGlyphCount; i++) {
+ fprintf (fp, "\t %2d. input", i);
+ otfPrintCoverage (fp, otf->input[i]);
+ }
+ fprintf (fp, "\t lookaheadGlyphCount: %d\n", otf->lookaheadGlyphCount);
+ for (i = 0; i < otf->lookaheadGlyphCount; i++) {
+ fprintf (fp, "\t %2d. lookahead", i);
+ otfPrintCoverage (fp, otf->lookahead[i]);
+ }
+ printOtfLookupRecord (fp, " ", otf->otfCount, otf->otf);
+}
+
+void freeOTFChn3 (OtfChn3Ptr otf)
+{
+ int i;
+
+ for (i = 0; i < otf->backtrackGlyphCount; i++)
+ otfFreeCoverage (otf->backtrack[i]);
+ free (otf->backtrack);
+ for (i = 0; i < otf->inputGlyphCount; i++)
+ otfFreeCoverage (otf->input[i]);
+ free (otf->input);
+ for (i = 0; i < otf->lookaheadGlyphCount; i++)
+ otfFreeCoverage (otf->lookahead[i]);
+ free (otf->lookahead);
+ free (otf->otf);
+}
+
diff --git a/Build/source/texk/ttfdump/libttf/ttfutil.c b/Build/source/texk/ttfdump/libttf/ttfutil.c
index 96a1bd3eb53..a31478002a5 100644
--- a/Build/source/texk/ttfdump/libttf/ttfutil.c
+++ b/Build/source/texk/ttfdump/libttf/ttfutil.c
@@ -32,12 +32,22 @@ void ttfError(const char * msg)
}
/* Functions copied or adapted from kpathsea. */
+long
+xftell (FILE *fp, const char *funcname)
+{
+ long where = ftell (fp);
+
+ if (where < 0)
+ FATAL_PERROR(funcname);
+
+ return where;
+}
+
void
xfseek (FILE *f, long offset, int wherefrom, const char *funcname)
{
- if (fseek (f, offset, wherefrom) < 0) {
+ if (fseek (f, offset, wherefrom) < 0)
FATAL_PERROR(funcname);
- }
}
void *
@@ -55,7 +65,7 @@ xmalloc (size_t size)
}
void *
-xcalloc (size_t nelem, size_t elsize)
+xcalloc (size_t nelem, size_t elsize)
{
void *new_mem = (void*)calloc(nelem ? nelem : 1, elsize ? elsize : 1);
diff --git a/Build/source/texk/ttfdump/src/ttfdump.c b/Build/source/texk/ttfdump/src/ttfdump.c
index d603483dc28..0726b3b0e5f 100644
--- a/Build/source/texk/ttfdump/src/ttfdump.c
+++ b/Build/source/texk/ttfdump/src/ttfdump.c
@@ -52,6 +52,9 @@ static void print_vdmx(FILE *out);
static void print_vhea(FILE *out);
static void print_vmtx(FILE *out);
+static void print_gpos(FILE *out);
+static void print_gsub(FILE *out);
+
static void usage (void);
@@ -157,6 +160,9 @@ main(int argc, char *argv[])
print_offset(dp_file);
print_dir(dp_file);
+ if (font->loca == NULL)
+ glyphnum = NO_GLYF;
+
if (tablename == NULL)
{
/* no table specified */
@@ -236,6 +242,10 @@ print_table(FILE *out, char *tablename)
print_vhea(out);
if (!strcmp(tablename, "vmtx"))
print_vmtx(out);
+ if (!strcmp(tablename, "GPOS"))
+ print_gpos(out);
+ if (!strcmp(tablename, "GSUB"))
+ print_gsub(out);
}
@@ -262,6 +272,10 @@ print_all_tables(FILE *dp_file)
print_vdmx(dp_file);
print_vhea(dp_file);
print_vmtx(dp_file);
+
+ /* Additional OpenType Tables */
+ print_gpos(dp_file);
+ print_gsub(dp_file);
}
@@ -270,7 +284,6 @@ print_ttc(TTCHeaderPtr ttc, FILE *out)
{
int i, b[2];
-
FixedSplit(ttc->version, b);
fprintf(out, "TrueType Collection Header\n");
@@ -295,9 +308,17 @@ print_prologue(FILE *out)
static void
print_offset(FILE *out)
{
+ int b[2];
+
+ FixedSplit(font->version, b);
+
fprintf(out, "Offset Table\n");
fprintf(out, "------------\n");
- fprintf(out, "\t sfnt version:\n");
+ fprintf(out, "\t sfnt version: ");
+ if (b[1] & 0xff00)
+ fprintf(out, "'%s'\n", TagToStr (font->version));
+ else
+ fprintf(out, "\t\t %d.%d\n", b[1], b[0]);
fprintf(out, "\t number of tables: %d\n", font->numTables);
}
@@ -505,6 +526,22 @@ print_vmtx(FILE *out)
static void
+print_gpos(FILE *out)
+{
+ if (font->gpos != NULL)
+ ttfPrintGPOS(out, font->gpos);
+}
+
+
+static void
+print_gsub(FILE *out)
+{
+ if (font->gsub != NULL)
+ ttfPrintGSUB(out, font->gsub);
+}
+
+
+static void
usage(void)
{
fprintf(stderr, "Usage: ttfdump ttfname dumpname [options]\n");
diff --git a/Build/source/texk/ttfdump/tests/ttfdump.glyf b/Build/source/texk/ttfdump/tests/ttfdump.glyf
index be977900774..b2754800ff4 100644
--- a/Build/source/texk/ttfdump/tests/ttfdump.glyf
+++ b/Build/source/texk/ttfdump/tests/ttfdump.glyf
@@ -1,29 +1,29 @@
True Type Font File Dumper: v 0.5.5
-Copyright 1996-1998 ollie@ms1.hinet.net
+Copyright 1996-1998 ollie@ms1.hinet.net
Dumping File:FonetikaDaniaIwonaeRegular.ttf
-Offset Table
-------------
- sfnt version:
+Offset Table
+------------
+ sfnt version: 1.0
number of tables: 14
- 0. 'GPOS' - checksum = 0xd7f8e75c, offset = 0x00001cd0, len = 80
- 1. 'GSUB' - checksum = 0x6c91748f, offset = 0x00001cb0, len = 32
- 2. 'OS/2' - checksum = 0x55d6fec3, offset = 0x00000168, len = 86
- 3. 'cmap' - checksum = 0x987c2758, offset = 0x0000028c, len = 482
- 4. 'cvt ' - checksum = 0x00210279, offset = 0x00000470, len = 4
- 5. 'gasp' - checksum = 0xffff0003, offset = 0x00001ca8, len = 8
- 6. 'glyf' - checksum = 0xd071d50c, offset = 0x000004dc, len = 4946
- 7. 'head' - checksum = 0xe43df9fb, offset = 0x000000ec, len = 54
- 8. 'hhea' - checksum = 0x05e9014f, offset = 0x00000124, len = 36
- 9. 'hmtx' - checksum = 0x4ca30981, offset = 0x000001c0, len = 202
- 10. 'loca' - checksum = 0x6c437107, offset = 0x00000474, len = 104
- 11. 'maxp' - checksum = 0x0079007b, offset = 0x00000148, len = 32
- 12. 'name' - checksum = 0x31984665, offset = 0x00001830, len = 1002
- 13. 'post' - checksum = 0x0aef76ec, offset = 0x00001c1c, len = 140
+ 0. 'GPOS' - checksum = 0xd7f8e75c, offset = 0x00001cd0, len = 80
+ 1. 'GSUB' - checksum = 0x6c91748f, offset = 0x00001cb0, len = 32
+ 2. 'OS/2' - checksum = 0x55d6fec3, offset = 0x00000168, len = 86
+ 3. 'cmap' - checksum = 0x987c2758, offset = 0x0000028c, len = 482
+ 4. 'cvt ' - checksum = 0x00210279, offset = 0x00000470, len = 4
+ 5. 'gasp' - checksum = 0xffff0003, offset = 0x00001ca8, len = 8
+ 6. 'glyf' - checksum = 0xd071d50c, offset = 0x000004dc, len = 4946
+ 7. 'head' - checksum = 0xe43df9fb, offset = 0x000000ec, len = 54
+ 8. 'hhea' - checksum = 0x05e9014f, offset = 0x00000124, len = 36
+ 9. 'hmtx' - checksum = 0x4ca30981, offset = 0x000001c0, len = 202
+ 10. 'loca' - checksum = 0x6c437107, offset = 0x00000474, len = 104
+ 11. 'maxp' - checksum = 0x0079007b, offset = 0x00000148, len = 32
+ 12. 'name' - checksum = 0x31984665, offset = 0x00001830, len = 1002
+ 13. 'post' - checksum = 0x0aef76ec, offset = 0x00001c1c, len = 140
Glyph 1.
- numberOfContours: 2
+ numberOfContours: 2
xMin: 33
yMin: 0
xMax: 366
@@ -38,14 +38,14 @@ Glyph 1.
Flags
-----
- 0: YDual XDual X-Short On
- 1: XDual On
- 2: YDual On
- 3: XDual On
- 4: YDual Y-Short On
- 5: YDual On
- 6: XDual On
- 7: YDual On
+ 0: YDual XDual X-Short On
+ 1: XDual On
+ 2: YDual On
+ 3: XDual On
+ 4: YDual Y-Short On
+ 5: YDual On
+ 6: XDual On
+ 7: YDual On
Coordinates
-----------
diff --git a/Build/source/texk/ttfdump/tests/ttfdump.gpos b/Build/source/texk/ttfdump/tests/ttfdump.gpos
new file mode 100644
index 00000000000..9a07bda4a02
--- /dev/null
+++ b/Build/source/texk/ttfdump/tests/ttfdump.gpos
@@ -0,0 +1,47 @@
+True Type Font File Dumper: v 0.5.5
+Copyright 1996-1998 ollie@ms1.hinet.net
+Dumping File:FonetikaDaniaIwonaeRegular.ttf
+
+
+Offset Table
+------------
+ sfnt version: 1.0
+ number of tables: 14
+ 0. 'GPOS' - checksum = 0xd7f8e75c, offset = 0x00001cd0, len = 80
+ 1. 'GSUB' - checksum = 0x6c91748f, offset = 0x00001cb0, len = 32
+ 2. 'OS/2' - checksum = 0x55d6fec3, offset = 0x00000168, len = 86
+ 3. 'cmap' - checksum = 0x987c2758, offset = 0x0000028c, len = 482
+ 4. 'cvt ' - checksum = 0x00210279, offset = 0x00000470, len = 4
+ 5. 'gasp' - checksum = 0xffff0003, offset = 0x00001ca8, len = 8
+ 6. 'glyf' - checksum = 0xd071d50c, offset = 0x000004dc, len = 4946
+ 7. 'head' - checksum = 0xe43df9fb, offset = 0x000000ec, len = 54
+ 8. 'hhea' - checksum = 0x05e9014f, offset = 0x00000124, len = 36
+ 9. 'hmtx' - checksum = 0x4ca30981, offset = 0x000001c0, len = 202
+ 10. 'loca' - checksum = 0x6c437107, offset = 0x00000474, len = 104
+ 11. 'maxp' - checksum = 0x0079007b, offset = 0x00000148, len = 32
+ 12. 'name' - checksum = 0x31984665, offset = 0x00001830, len = 1002
+ 13. 'post' - checksum = 0x0aef76ec, offset = 0x00001c1c, len = 140
+
+'GPOS' Table - Glyph Positioning Data
+-------------------------------------
+ 'GPOS' Version: 1.0
+ scriptCount: 1
+ 0. 'latn' script - langSysCount: 0
+ default lang - featureCount: 1
+ featureIndex: 0
+
+ featureCount: 1
+ 0. 'kern' feature - lookupCount: 1
+ lookupListIndex: 0
+
+ lookupCount: 1
+ 0. lookupType: 2, lookupFlag: 0x0000
+ subTableCount: 1
+ 0. lookupFormat: 1 - Pair Adjustment List
+ Coverage - glyphCount: 1
+ glyphArray: 34
+ valueFormat1: 0x0004, valueFormat2: 0x0000, pairSetCount: 1
+ 0. pairValueCount: 1
+ 0. secondGlyph: 14
+ value1: XAdvance = -33
+
diff --git a/Build/source/texk/ttfdump/tests/ttfdump.gsub b/Build/source/texk/ttfdump/tests/ttfdump.gsub
new file mode 100644
index 00000000000..574556947f6
--- /dev/null
+++ b/Build/source/texk/ttfdump/tests/ttfdump.gsub
@@ -0,0 +1,35 @@
+True Type Font File Dumper: v 0.5.5
+Copyright 1996-1998 ollie@ms1.hinet.net
+Dumping File:FonetikaDaniaIwonaeRegular.ttf
+
+
+Offset Table
+------------
+ sfnt version: 1.0
+ number of tables: 14
+ 0. 'GPOS' - checksum = 0xd7f8e75c, offset = 0x00001cd0, len = 80
+ 1. 'GSUB' - checksum = 0x6c91748f, offset = 0x00001cb0, len = 32
+ 2. 'OS/2' - checksum = 0x55d6fec3, offset = 0x00000168, len = 86
+ 3. 'cmap' - checksum = 0x987c2758, offset = 0x0000028c, len = 482
+ 4. 'cvt ' - checksum = 0x00210279, offset = 0x00000470, len = 4
+ 5. 'gasp' - checksum = 0xffff0003, offset = 0x00001ca8, len = 8
+ 6. 'glyf' - checksum = 0xd071d50c, offset = 0x000004dc, len = 4946
+ 7. 'head' - checksum = 0xe43df9fb, offset = 0x000000ec, len = 54
+ 8. 'hhea' - checksum = 0x05e9014f, offset = 0x00000124, len = 36
+ 9. 'hmtx' - checksum = 0x4ca30981, offset = 0x000001c0, len = 202
+ 10. 'loca' - checksum = 0x6c437107, offset = 0x00000474, len = 104
+ 11. 'maxp' - checksum = 0x0079007b, offset = 0x00000148, len = 32
+ 12. 'name' - checksum = 0x31984665, offset = 0x00001830, len = 1002
+ 13. 'post' - checksum = 0x0aef76ec, offset = 0x00001c1c, len = 140
+
+'GSUB' Table - Glyph Substitution Data
+--------------------------------------
+ 'GSUB' Version: 1.0
+ scriptCount: 1
+ 0. 'latn' script - langSysCount: 0
+ default lang - featureCount: 0
+
+ featureCount: 0
+
+ lookupCount: 0
+
diff --git a/Build/source/texk/ttfdump/tests/ttfdump.head b/Build/source/texk/ttfdump/tests/ttfdump.head
index 4e626afd6f1..d960f69b4c2 100644
--- a/Build/source/texk/ttfdump/tests/ttfdump.head
+++ b/Build/source/texk/ttfdump/tests/ttfdump.head
@@ -1,37 +1,37 @@
True Type Font File Dumper: v 0.5.5
-Copyright 1996-1998 ollie@ms1.hinet.net
+Copyright 1996-1998 ollie@ms1.hinet.net
Dumping File:FonetikaDaniaIwonaeRegular.ttf
-Offset Table
-------------
- sfnt version:
+Offset Table
+------------
+ sfnt version: 1.0
number of tables: 14
- 0. 'GPOS' - checksum = 0xd7f8e75c, offset = 0x00001cd0, len = 80
- 1. 'GSUB' - checksum = 0x6c91748f, offset = 0x00001cb0, len = 32
- 2. 'OS/2' - checksum = 0x55d6fec3, offset = 0x00000168, len = 86
- 3. 'cmap' - checksum = 0x987c2758, offset = 0x0000028c, len = 482
- 4. 'cvt ' - checksum = 0x00210279, offset = 0x00000470, len = 4
- 5. 'gasp' - checksum = 0xffff0003, offset = 0x00001ca8, len = 8
- 6. 'glyf' - checksum = 0xd071d50c, offset = 0x000004dc, len = 4946
- 7. 'head' - checksum = 0xe43df9fb, offset = 0x000000ec, len = 54
- 8. 'hhea' - checksum = 0x05e9014f, offset = 0x00000124, len = 36
- 9. 'hmtx' - checksum = 0x4ca30981, offset = 0x000001c0, len = 202
- 10. 'loca' - checksum = 0x6c437107, offset = 0x00000474, len = 104
- 11. 'maxp' - checksum = 0x0079007b, offset = 0x00000148, len = 32
- 12. 'name' - checksum = 0x31984665, offset = 0x00001830, len = 1002
- 13. 'post' - checksum = 0x0aef76ec, offset = 0x00001c1c, len = 140
+ 0. 'GPOS' - checksum = 0xd7f8e75c, offset = 0x00001cd0, len = 80
+ 1. 'GSUB' - checksum = 0x6c91748f, offset = 0x00001cb0, len = 32
+ 2. 'OS/2' - checksum = 0x55d6fec3, offset = 0x00000168, len = 86
+ 3. 'cmap' - checksum = 0x987c2758, offset = 0x0000028c, len = 482
+ 4. 'cvt ' - checksum = 0x00210279, offset = 0x00000470, len = 4
+ 5. 'gasp' - checksum = 0xffff0003, offset = 0x00001ca8, len = 8
+ 6. 'glyf' - checksum = 0xd071d50c, offset = 0x000004dc, len = 4946
+ 7. 'head' - checksum = 0xe43df9fb, offset = 0x000000ec, len = 54
+ 8. 'hhea' - checksum = 0x05e9014f, offset = 0x00000124, len = 36
+ 9. 'hmtx' - checksum = 0x4ca30981, offset = 0x000001c0, len = 202
+ 10. 'loca' - checksum = 0x6c437107, offset = 0x00000474, len = 104
+ 11. 'maxp' - checksum = 0x0079007b, offset = 0x00000148, len = 32
+ 12. 'name' - checksum = 0x31984665, offset = 0x00001830, len = 1002
+ 13. 'post' - checksum = 0x0aef76ec, offset = 0x00001c1c, len = 140
'head' Table - Font Header
--------------------------
- 'head' version: 1. 0
- fontReversion: 1. 0
+ 'head' version: 1.0
+ fontReversion: 1.0
checkSumAdjustment: 0x851d4906
magicNumber: 0x5f0f3cf5
flags: 0x000b
unitsPerEm: 1000
- created:
- modified:
+ created: 0x00000000c1405b91
+ modified: 0x00000000c1405b91
xMin: -63
yMin: -250
xMax: 733
diff --git a/Build/source/texk/ttfdump/tests/ttfdump.test b/Build/source/texk/ttfdump/tests/ttfdump.test
index deddc589804..0196bea97a1 100755
--- a/Build/source/texk/ttfdump/tests/ttfdump.test
+++ b/Build/source/texk/ttfdump/tests/ttfdump.test
@@ -3,12 +3,32 @@
# Copyright (C) 2011 Peter Breitenlohner <tex-live@tug.org>
# You may freely use, modify and/or distribute this file.
-rm -rf FonetikaDaniaIwonaeRegular.ttf ttfdump.glyf ttfdump.head
+failed=
+
+rm -rf FonetikaDaniaIwonaeRegular.ttf ttftest.*
cp $srcdir/tests/FonetikaDaniaIwonaeRegular.ttf .
-./ttfdump -t head -o ttfdump.head FonetikaDaniaIwonaeRegular.ttf || exit 1
-diff -b $srcdir/tests/ttfdump.head ttfdump.head || exit 1
+./ttfdump -t glyf -g 1 -o ttftest.glyf FonetikaDaniaIwonaeRegular.ttf \
+ && diff -b $srcdir/tests/ttfdump.glyf ttftest.glyf \
+ && echo "ttfdump.glyf tests OK" \
+ || failed="$failed ttfdump.glyf"
+
+./ttfdump -t GPOS -o ttftest.gpos FonetikaDaniaIwonaeRegular.ttf \
+ && diff -b $srcdir/tests/ttfdump.gpos ttftest.gpos \
+ && echo "ttfdump.gpos tests OK" \
+ || failed="$failed ttfdump.gpos"
+
+./ttfdump -t GSUB -o ttftest.gsub FonetikaDaniaIwonaeRegular.ttf \
+ && diff -b $srcdir/tests/ttfdump.gsub ttftest.gsub \
+ && echo "ttfdump.gsub tests OK" \
+ || failed="$failed ttfdump.gsub"
+
+./ttfdump -t head -o ttftest.head FonetikaDaniaIwonaeRegular.ttf \
+ && diff -b $srcdir/tests/ttfdump.head ttftest.head \
+ && echo "ttfdump.head tests OK" \
+ || failed="$failed ttfdump.head"
-./ttfdump -t glyf -g 1 -o ttfdump.glyf FonetikaDaniaIwonaeRegular.ttf || exit 1
-diff -b $srcdir/tests/ttfdump.glyf ttfdump.glyf || exit 1
+test -z "$failed" && exit 0
+echo "failed tests:$failed"
+exit 1