summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2013-06-24 09:42:47 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2013-06-24 09:42:47 +0000
commite82a4ec6e8f06840867512112128041581c022e7 (patch)
tree19f7ea4fe44f1ae5f9c7b1dd349b7e2ba1cb9ba1
parentd8ee324e03e46ef3361a8ade3062034bc45795af (diff)
ttf2pk (with libttf) now disabled by default
ttf2pk2 (with libfreetype) completed and now enabled by default git-svn-id: svn://tug.org/texlive/trunk@30893 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Build/source/texk/ttf2pk/ChangeLog4
-rw-r--r--Build/source/texk/ttf2pk/ac/withenable.ac4
-rw-r--r--Build/source/texk/ttf2pk2/ChangeLog11
-rw-r--r--Build/source/texk/ttf2pk2/ac/withenable.ac4
-rw-r--r--Build/source/texk/ttf2pk2/configure.ac4
-rw-r--r--Build/source/texk/ttf2pk2/ftlib.c805
-rw-r--r--Build/source/texk/ttf2pk2/newobj.c16
-rw-r--r--Build/source/texk/ttf2pk2/newobj.h10
-rw-r--r--Build/source/texk/ttf2pk2/ttf2pk.c6
-rw-r--r--Build/source/texk/ttf2pk2/ttf2tfm.c5
10 files changed, 654 insertions, 215 deletions
diff --git a/Build/source/texk/ttf2pk/ChangeLog b/Build/source/texk/ttf2pk/ChangeLog
index 51dead75ef8..a6ae0f58b89 100644
--- a/Build/source/texk/ttf2pk/ChangeLog
+++ b/Build/source/texk/ttf2pk/ChangeLog
@@ -1,3 +1,7 @@
+2013-06-10 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * ac/withenable.ac: Disabled by default.
+
2013-02-08 Peter Breitenlohner <peb@mppmu.mpg.de>
* Makefile.am ({cfg,enc}datadir): Change texmf => texmf-dist.
diff --git a/Build/source/texk/ttf2pk/ac/withenable.ac b/Build/source/texk/ttf2pk/ac/withenable.ac
index fcebeff82bd..6c09fca78f9 100644
--- a/Build/source/texk/ttf2pk/ac/withenable.ac
+++ b/Build/source/texk/ttf2pk/ac/withenable.ac
@@ -1,7 +1,7 @@
## texk/ttf2pk/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ttf2pk/
dnl
-dnl Copyright (C) 2009 Peter Breitenlohner <tex-live@tug.org>
+dnl Copyright (C) 2009-2013 Peter Breitenlohner <tex-live@tug.org>
dnl You may freely use, modify and/or distribute this file.
dnl
## configure options and TL libraries required for ttf2pk
-KPSE_ENABLE_PROG([ttf2pk], [kpathsea freetype])
+KPSE_ENABLE_PROG([ttf2pk], [kpathsea freetype], [disable])
diff --git a/Build/source/texk/ttf2pk2/ChangeLog b/Build/source/texk/ttf2pk2/ChangeLog
index 25777b62063..81fa877068d 100644
--- a/Build/source/texk/ttf2pk2/ChangeLog
+++ b/Build/source/texk/ttf2pk2/ChangeLog
@@ -1,3 +1,14 @@
+2013-06-10 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * ftlib.c: Apply 'vert'/'vrt2' substitutions for rotated fonts.
+ * newobj.[ch]: Replace my{m,c,re}alloc() => x{m,c,re}alloc().
+
+ * ac/withenable.ac: Enabled by default.
+
+2013-06-04 Peter Breitenlohner <peb@mppmu.mpg.de>
+
+ * newobj.c: Define mycalloc(), already declared in newobj.c.
+
2013-02-08 Peter Breitenlohner <peb@mppmu.mpg.de>
* Makefile.am ({cfg,enc}datadir): Change texmf => texmf-dist.
diff --git a/Build/source/texk/ttf2pk2/ac/withenable.ac b/Build/source/texk/ttf2pk2/ac/withenable.ac
index 5d176721554..9893f6c69b9 100644
--- a/Build/source/texk/ttf2pk2/ac/withenable.ac
+++ b/Build/source/texk/ttf2pk2/ac/withenable.ac
@@ -1,7 +1,7 @@
## texk/ttf2pk2/ac/withenable.ac: configure.ac fragment for the TeX Live subdirectory texk/ttf2pk2/
dnl
-dnl Copyright (C) 2011 Peter Breitenlohner <tex-live@tug.org>
+dnl Copyright (C) 2011-2013 Peter Breitenlohner <tex-live@tug.org>
dnl You may freely use, modify and/or distribute this file.
dnl
## configure options and TL libraries required for ttf2pk
-KPSE_ENABLE_PROG([ttf2pk2], [kpathsea freetype2], [disable])
+KPSE_ENABLE_PROG([ttf2pk2], [kpathsea freetype2])
diff --git a/Build/source/texk/ttf2pk2/configure.ac b/Build/source/texk/ttf2pk2/configure.ac
index 849eb797e07..a3d6feda68a 100644
--- a/Build/source/texk/ttf2pk2/configure.ac
+++ b/Build/source/texk/ttf2pk2/configure.ac
@@ -1,12 +1,12 @@
dnl Process this file with autoconf to produce a configure script.
dnl
-dnl Copyright (C) 2011 Peter Breitenlohner <tex-live@tug.org>
+dnl Copyright (C) 2011-2013 Peter Breitenlohner <tex-live@tug.org>
dnl
dnl This file is free software; the copyright holder
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl
-AC_INIT([ttf2pk2 for TeX Live], [1.5], [tex-k@tug.org])
+AC_INIT([ttf2pk2 for TeX Live], [2.0], [tex-k@tug.org])
AC_PREREQ([2.65])
AC_CONFIG_SRCDIR([ttf2pk.c])
AC_CONFIG_AUX_DIR([../../build-aux])
diff --git a/Build/source/texk/ttf2pk2/ftlib.c b/Build/source/texk/ttf2pk2/ftlib.c
index ffe3827b7ff..e1011876c5c 100644
--- a/Build/source/texk/ttf2pk2/ftlib.c
+++ b/Build/source/texk/ttf2pk2/ftlib.c
@@ -7,7 +7,7 @@
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
*
- * Copyright (C) 2012 by
+ * Copyright (C) 2012, 2013 by
* Peter Breitenlohner <tex-live@tug.org>
*/
@@ -34,18 +34,6 @@
#define Microsoft_Symbol_encoding 0
#define Microsoft_Unicode_encoding 1
-#define TTAG_GSUB FT_MAKE_TAG('G', 'S', 'U', 'B')
-
-#define SCRIPT_kana FT_MAKE_TAG('k', 'a', 'n', 'a')
-#define SCRIPT_hani FT_MAKE_TAG('h', 'a', 'n', 'i')
-#define SCRIPT_hang FT_MAKE_TAG('h', 'a', 'n', 'g')
-
-#define LANGUAGE_JAN FT_MAKE_TAG('J', 'A', 'N', ' ')
-#define LANGUAGE_CHN FT_MAKE_TAG('C', 'H', 'N', ' ')
-#define LANGUAGE_KOR FT_MAKE_TAG('K', 'O', 'R', ' ')
-
-#define FEATURE_vert FT_MAKE_TAG('v', 'e', 'r', 't')
-
FT_Library engine;
FT_Face face;
@@ -61,9 +49,6 @@ TT_Postscript *postscript;
FT_Byte *GSUB_table;
FT_ULong GSUB_length;
FT_ULong GSUB_ptr;
-FT_ULong Script_List_ptr;
-FT_ULong Feature_List_ptr;
-FT_ULong Lookup_List_ptr;
static inline void
need (FT_ULong needed)
@@ -93,7 +78,6 @@ get_UShort(void)
return (FT_UShort) cc;
}
-#if 0 /* unised */
static FT_Short
get_Short(void)
{
@@ -102,7 +86,6 @@ get_Short(void)
cc |= get_Byte();
return (FT_Short) cc;
}
-#endif
static FT_ULong
get_ULong(void)
@@ -115,7 +98,7 @@ get_ULong(void)
return (FT_ULong) cc;
}
-#if 0 /* unised */
+#if 0 /* unused */
static FT_Long
get_Long(void)
{
@@ -128,13 +111,548 @@ get_Long(void)
}
#endif
-#if 0
-FT_UShort in_string[2];
+typedef struct {
+ FT_UShort start;
+ FT_UShort end;
+ FT_UShort start_Index;
+} Range_Record;
+
+typedef struct {
+ FT_ULong ptr;
+ FT_UShort format;
+ FT_UShort count;
+ union {
+ FT_UShort *glyphs; /* format = 1 */
+ Range_Record *ranges; /* format = 2 */
+ } data;
+} Coverage_Item;
-TTO_GSUBHeader gsub_;
-TTO_GSUBHeader *gsub;
-TTO_GSUB_String in, out;
+static inline void
+fetch_Glyphs (FT_UShort count, FT_UShort *glyphs)
+{
+ int i;
+
+ need(2 * count);
+ for (i = 0; i < count; i++)
+ glyphs[i] = get_UShort();
+ for (i = 1; i < count; i++)
+ if (glyphs[i] <= glyphs[i - 1])
+ oops("Glyph[%d]=%d and Glyph[%d]=%d: out of order.", i - 1, glyphs[i - 1], i, glyphs[i]);
+}
+
+static inline FT_UShort
+fetch_Ranges (FT_UShort count, Range_Record *ranges)
+{
+ int i;
+ FT_UShort ndx = 0;
+
+ need(6 * count);
+ for (i = 0; i < count; i++)
+ {
+ ranges[i].start = get_UShort();
+ ranges[i].end = get_UShort();
+ if (ranges[i].start > ranges[i].end)
+ oops("Range[%d]: bad range=%d..%d.", i, ranges[i].start, ranges[i].end);
+ ranges[i].start_Index = get_UShort();
+ if (ranges[i].start_Index != ndx)
+ oops("Range[%d]: bad start_Index=%d (should be %d).", i, ranges[i].start_Index, ndx);
+ ndx += (ranges[i].end - ranges[i].start) + 1;
+ }
+ for (i = 1; i < count; i++)
+ if (ranges[i].start <= ranges[i-1].end)
+ oops("Range[%d]=%d..%d and Range[%d]=%d..%d: out of order.",
+ i - 1, ranges[i - 1].start, ranges[i - 1].end, i, ranges[i].start, ranges[i].end);
+ return ndx;
+}
+
+static inline FT_UShort
+fetch_Coverage (Coverage_Item *coverage)
+{
+ FT_UShort res = 0;
+ GSUB_ptr = coverage->ptr;
+ need(4);
+ coverage->format = get_UShort();
+ coverage->count = res = get_UShort();
+ switch (coverage->format)
+ {
+ case 1:
+ coverage->data.glyphs = mymalloc (res * sizeof(FT_UShort));
+#ifdef DEBUG
+ warning("Coverage Format=1 with %d Glyphs at 0x%04x.", res, coverage->ptr);
+#endif
+ fetch_Glyphs (res, coverage->data.glyphs);
+ break;
+ case 2:
+ coverage->data.ranges = mymalloc (res * sizeof(Range_Record));
+#ifdef DEBUG
+ warning("Coverage Format=1 with %d Ranges at 0x%04x.", res, coverage->ptr);
#endif
+ res = fetch_Ranges (res, coverage->data.ranges);
+ break;
+ default:
+ oops("Coverage at 0x%04x: bad Format=%d.", coverage->ptr, coverage->format);
+ }
+ return res;
+}
+
+/*
+ * We only accept Single Substitutions (and Extensions)
+ */
+
+typedef struct {
+ FT_UShort count;
+ FT_UShort *glyphs;
+} Glyph_Array;
+
+typedef struct {
+ FT_ULong ptr;
+ FT_UShort format;
+ Coverage_Item *coverage;
+ union {
+ FT_Short *delta; /* format = 1 */
+ Glyph_Array *array; /* format = 2 */
+ } data;
+} Single_Item;
+
+typedef struct _Subst_Item {
+ Single_Item *item;
+ struct _Subst_Item *next;
+} Subst_Item;
+
+Subst_Item *Subst_list, *Subst_last;
+
+static inline void
+add_Single (Single_Item *item)
+{
+ Subst_Item *entry = mycalloc (1, sizeof(Subst_Item));
+ entry->item = item;
+ if (Subst_last)
+ Subst_last->next = entry;
+ else
+ Subst_list = entry;
+ Subst_last = entry;
+ has_gsub = True;
+}
+
+static inline void
+fetch_Single (Single_Item *item)
+{
+ int i;
+ FT_UShort val;
+
+ item->coverage = mycalloc (1, sizeof(Coverage_Item));
+ GSUB_ptr = item->ptr;
+ need(6);
+ item->format = get_UShort();
+ item->coverage->ptr = item->ptr + get_UShort();
+ switch (item->format)
+ {
+ case 1:
+ val = get_Short();
+ item->data.delta = mycalloc (1, sizeof(FT_UShort));
+ *item->data.delta = val;
+#ifdef DEBUG
+ warning("Single Substitution Format=1 with Delta=%d at 0x%04x.", val, item->ptr);
+#endif
+ fetch_Coverage (item->coverage);
+ break;
+ case 2:
+ val = get_UShort();
+ need(2 * val);
+ item->data.array = mycalloc (1, sizeof(Glyph_Array));
+ item->data.array->count = val;
+ item->data.array->glyphs = mycalloc (val, sizeof(FT_UShort));
+ for (i = 0; i < val; i++)
+ item->data.array->glyphs[i] = get_UShort();
+#ifdef DEBUG
+ warning("Single Substitution Format=2 with %d Glyphs at 0x%04x.", val, item->ptr);
+#endif
+ val = fetch_Coverage (item->coverage);
+ if (val != item->data.array->count)
+ oops("Coverage at 0x%04x: covers %d glyphs (should be %d).", item->ptr, val, item->data.array->count);
+ break;
+ default:
+ oops("Single Substitution at 0x%04x: bad Format=%d.", item->ptr, item->format);
+ }
+
+ add_Single (item);
+}
+
+typedef struct {
+ FT_UShort count;
+ Single_Item *list;
+} Lookup_Item;
+
+typedef struct {
+ FT_ULong ptr;
+ Lookup_Item *entry;
+} Lookup_Record;
+
+Lookup_Record *Lookup_List;
+FT_UShort Lookup_Count;
+
+static inline void
+fetch_Lookup (int i)
+{
+ FT_ULong Lookup_ptr = Lookup_List[i].ptr;
+
+ if (Lookup_ptr && !Lookup_List[i].entry)
+ {
+ Lookup_Item *entry = Lookup_List[i].entry = mycalloc (1, sizeof(Lookup_Item));
+ Boolean is_ext = False;
+ FT_UShort val;
+ int j;
+
+#ifdef DEBUG
+ warning("Lookup[%d] at 0x%04x.", i, Lookup_ptr);
+#endif
+ GSUB_ptr = Lookup_ptr;
+
+ /*
+ * Read Lookup Item
+ */
+ need(6);
+ val = get_UShort();
+ if (val == 7)
+ is_ext = True;
+ else if (val != 1)
+ oops("Lookup[%d] at 0x%04x: bad Type=%d.", i, Lookup_ptr, val);
+ get_UShort(); /* Ignore Lookup Flag */
+ entry->count = get_UShort();
+ entry->list = mycalloc (entry->count, sizeof(Single_Item));
+
+ need(2 * entry->count);
+ for (j = 0; j < entry->count; j++)
+ entry->list[j].ptr = Lookup_ptr + get_UShort();
+
+ if (is_ext)
+ for (j = 0; j < entry->count; j++)
+ {
+ GSUB_ptr = entry->list[j].ptr;
+ need(8);
+ val = get_UShort();
+ if (val != 1)
+ oops("Lookup[%d] Extension[%d] at 0x%04x: bad Format=%d.", i, j, entry->list[j].ptr, val);
+ val = get_UShort();
+ if (val != 1)
+ oops("Lookup[%d] Extension[%d] at 0x%04x: bad Type=%d.", i, j, entry->list[j].ptr, val);
+ entry->list[j].ptr += get_ULong();
+ }
+
+ for (j = 0; j < entry->count; j++)
+ fetch_Single (&entry->list[j]);
+ }
+}
+
+typedef struct {
+ FT_UShort count;
+ FT_UShort *list;
+} Feature_Item;
+
+typedef struct {
+ FT_Tag tag;
+ FT_ULong ptr;
+ Feature_Item *entry;
+} Feature_Record;
+
+Feature_Record *Feature_List;
+FT_UShort Feature_Count;
+
+/*
+ * We check for the `vert' or `vrt2' feature in Chinese, Japanese, and Korean
+ */
+#define FEATURE_vert FT_MAKE_TAG('v', 'e', 'r', 't')
+#define FEATURE_vrt2 FT_MAKE_TAG('v', 'r', 't', '2')
+
+#define print_Tag(t) t >> 24, (t >> 16) & 0xff, (t >> 8) & 0xff, t & 0xff
+
+static inline void
+fetch_Feature (int i)
+{
+ FT_ULong Feature_ptr = Feature_List[i].ptr;
+
+ if (Feature_ptr && !Feature_List[i].entry)
+ {
+ Feature_Item *entry = Feature_List[i].entry = mycalloc (1, sizeof(Feature_Item));
+ FT_UShort val;
+ int j;
+
+#ifdef DEBUG
+ warning("Feature[%d] '%c%c%c%c' at 0x%04x.", i, print_Tag(Feature_List[i].tag), Feature_ptr);
+#endif
+ GSUB_ptr = Feature_ptr;
+
+ /*
+ * Read Feature Item
+ */
+ need(4);
+ val = get_UShort();
+ if (val)
+ oops("Feature[%d] at 0x%04x: bad FeaturParams 0x%04x.", Feature_ptr, i, val);
+ entry->count = get_UShort();
+ entry->list = mycalloc (entry->count, sizeof(FT_UShort));
+
+ need(2*entry->count);
+ for (j = 0; j < entry->count; j++) {
+ entry->list[j] = get_UShort();
+ if (entry->list[j] >= Lookup_Count)
+ oops("Feature[%d] at 0x%04x: bad Lookup Index[%d]=%d.", i, Feature_ptr, j, entry->list[j]);
+ }
+
+ for (j = 0; j < entry->count; j++)
+ fetch_Lookup (entry->list[j]);
+ }
+}
+
+#define SCRIPT_kana FT_MAKE_TAG('k', 'a', 'n', 'a')
+#define SCRIPT_hani FT_MAKE_TAG('h', 'a', 'n', 'i')
+#define SCRIPT_hang FT_MAKE_TAG('h', 'a', 'n', 'g')
+
+#define LANGUAGE_JAN FT_MAKE_TAG('J', 'A', 'N', ' ')
+#define LANGUAGE_CHN FT_MAKE_TAG('C', 'H', 'N', ' ')
+#define LANGUAGE_KOR FT_MAKE_TAG('K', 'O', 'R', ' ')
+
+struct _Script_Lang
+{
+ FT_Tag script;
+ FT_Tag language;
+};
+
+static const struct _Script_Lang Script_Lang[] = {
+ { SCRIPT_kana, LANGUAGE_JAN },
+ { SCRIPT_hani, LANGUAGE_CHN },
+ { SCRIPT_hang, LANGUAGE_KOR }
+};
+#define num_Script_Lang (sizeof(Script_Lang) / sizeof(Script_Lang[0]))
+
+typedef struct {
+ FT_UShort req;
+ FT_UShort count;
+ FT_UShort *list;
+} LangSys_Item;
+
+typedef struct {
+ FT_Tag tag;
+ FT_ULong ptr;
+ LangSys_Item *entry;
+} LangSys_Record;
+
+typedef struct {
+ FT_ULong ptr;
+ LangSys_Item *entry;
+ FT_UShort count;
+ LangSys_Record *list;
+} Script_Item;
+
+typedef struct {
+ FT_Tag tag, ltag;
+ FT_ULong ptr;
+ Script_Item *entry;
+} Script_Record;
+
+Script_Record *Script_List;
+FT_UShort Script_Count;
+
+static inline void
+fetch_LangSys (FT_ULong ptr, LangSys_Item **entry)
+{
+ LangSys_Item * item;
+ FT_UShort val;
+ int i;
+
+ *entry = item = mycalloc (1, sizeof(LangSys_Item));
+ GSUB_ptr = ptr;
+
+ /*
+ * Read LangSys Item
+ */
+ need(6);
+ val = get_UShort();
+ if (val)
+ oops("LangSys at 0x%04x: bad LookupOrder 0x%04x.", ptr, val);
+ item->req = get_UShort();
+ if (item->req != 0xffff && item->req >= Feature_Count)
+ oops("LangSys at 0x%04x: bad required Feature Index=%d.", ptr, item->req);
+ item->count = get_UShort();
+ item->list = mycalloc (item->count, sizeof(FT_UShort));
+
+ need(2 * item->count);
+ for (i = 0; i < item->count; i++) {
+ item->list[i] = get_UShort();
+ if (item->list[i] >= Feature_Count)
+ oops("LangSys at 0x%04x: bad Feature Index[%d]=%d.", ptr, i, item->list[i]);
+ }
+
+ if (item->req != 0xffff)
+ fetch_Feature (item->req);
+ for (i = 0; i < item->count; i++)
+ fetch_Feature (item->list[i]);
+}
+
+static inline void
+fetch_Script (int i)
+{
+ FT_ULong Script_ptr = Script_List[i].ptr;
+
+ if (Script_ptr)
+ {
+ Script_Item *entry = Script_List[i].entry = mycalloc (1, sizeof(Script_Item));
+ int j;
+
+#ifdef DEBUG
+ warning("Script[%d] '%c%c%c%c' at 0x%04x.", i, print_Tag(Script_List[i].tag), Script_ptr);
+#endif
+ GSUB_ptr = Script_ptr;
+
+ /*
+ * Read Script Item
+ */
+ need(4);
+ if ((entry->ptr = get_UShort()))
+ entry->ptr += Script_ptr;
+ entry->count = get_UShort();
+ entry->list = mycalloc (entry->count, sizeof(LangSys_Record));
+
+ need(6 * entry->count);
+ for (j = 0; j < entry->count; j++) {
+ FT_Tag tag = Script_List[i].tag;
+ FT_ULong ptr = Script_ptr + get_UShort();
+
+ entry->list[j].tag = tag;
+ if (tag == Script_List[i].ltag)
+ entry->list[j].ptr = ptr;
+ }
+
+ /*
+ * Read Default LangSys entriy
+ */
+ if (entry->ptr) {
+#ifdef DEBUG
+ warning("Script[%d] Default LangSys at 0x%04x.", i, entry->ptr);
+#endif
+ fetch_LangSys (entry->ptr, &entry->entry);
+ }
+
+ /*
+ * Read language LangSys entries
+ */
+ for (j = 0; j < entry->count; j++)
+ if (entry->list[j].ptr) {
+#ifdef DEBUG
+ warning("Script[%d] LangSys[%d] '%c%c%c%c' at 0x%04x.", i, j,
+ print_Tag(entry->list[j].tag), entry->list[j].ptr);
+#endif
+ fetch_LangSys (entry->list[j].ptr, &entry->list[j].entry);
+ }
+ }
+}
+
+#define TTAG_GSUB FT_MAKE_TAG('G', 'S', 'U', 'B')
+
+static inline void
+fetch_GSUB (void)
+{
+ FT_Error error;
+ int i, j;
+
+ FT_ULong Script_List_ptr, Feature_List_ptr, Lookup_List_ptr;
+
+ /*
+ * Fetch GSUB table
+ */
+ if ((error = FT_Load_Sfnt_Table(face, TTAG_GSUB, 0, NULL, &GSUB_length)))
+ {
+#ifdef DEBUG
+ warning("No GSUB data available for vertical glyph presentation forms.");
+#endif
+ return;
+ }
+ GSUB_table = mymalloc(GSUB_length);
+ if ((error = FT_Load_Sfnt_Table(face, TTAG_GSUB, 0, GSUB_table, &GSUB_length)))
+ {
+ warning("Cannot load GSUB table (error code = 0x%x).", error);
+ return;
+ }
+
+ /*
+ * Read GSUB header
+ */
+ need(10);
+ if (get_ULong() != 0x00010000)
+ oops("GSUB: Bad version.");
+ Script_List_ptr = get_UShort();
+ Feature_List_ptr = get_UShort();
+ Lookup_List_ptr = get_UShort();
+
+ /*
+ * Read Script_List
+ */
+ GSUB_ptr = Script_List_ptr;
+ need(2);
+ Script_Count = get_UShort();
+#ifdef DEBUG
+ warning("GSUB: Script List with %d entries at 0x%04x.", Script_Count, Script_List_ptr);
+#endif
+ Script_List = mycalloc (Script_Count, sizeof(Script_Record));
+
+ need (6 * Script_Count);
+ for (i = 0; i < Script_Count; i++)
+ {
+ FT_Tag tag = get_ULong();
+ FT_ULong ptr = Script_List_ptr + get_UShort();
+ for (j = 0; j < num_Script_Lang; j++)
+ if (tag == Script_Lang[j].script)
+ {
+ Script_List[i].tag = tag;
+ Script_List[i].ltag = Script_Lang[j].language;
+ Script_List[i].ptr = ptr;
+ }
+ }
+
+ /*
+ * Read Feature_List
+ */
+ GSUB_ptr = Feature_List_ptr;
+ need(2);
+ Feature_Count = get_UShort();
+#ifdef DEBUG
+ warning("GSUB: Feature List with %d entries at 0x%04x.", Feature_Count, Feature_List_ptr);
+#endif
+ Feature_List = mycalloc (Feature_Count, sizeof(Feature_Record));
+
+ need (6 * Feature_Count);
+ for (i = 0; i < Feature_Count; i++)
+ {
+ FT_Tag tag = get_ULong();
+ FT_ULong ptr = Feature_List_ptr + get_UShort();
+ if (tag == FEATURE_vert || tag == FEATURE_vrt2)
+ {
+ Feature_List[i].tag = tag;
+ Feature_List[i].ptr = ptr;
+ }
+ }
+
+ /*
+ * Read Lookup_List
+ */
+ GSUB_ptr = Lookup_List_ptr;
+ need(2);
+ Lookup_Count = get_UShort();
+#ifdef DEBUG
+ warning("GSUB: Lookup List with %d entries at 0x%04x.", Lookup_Count, Lookup_List_ptr);
+#endif
+ Lookup_List = mycalloc (Lookup_Count, sizeof(Lookup_Record));
+
+ need (2 * Lookup_Count);
+ for (i = 0; i < Lookup_Count; i++)
+ Lookup_List[i].ptr = Lookup_List_ptr + get_UShort();
+
+ /*
+ * Read Script_List entries
+ */
+ for (i = 0; i < Script_Count && !has_gsub; i++)
+ fetch_Script (i);
+}
void
FTopen (char *filename, Font *fnt, Boolean do_tfm, Boolean quiet)
@@ -143,20 +661,9 @@ FTopen (char *filename, Font *fnt, Boolean do_tfm, Boolean quiet)
int i;
unsigned short num_cmap, cmap_plat=0, cmap_enc=0;
-#if 0
- FT_UShort script_index, language_index, feature_index;
- FT_UShort req_feature_index = 0xFFFF;
-#endif
-
if ((error = FT_Init_FreeType(&engine)))
oops("Cannot initialize FreeType engine (error code = 0x%x).", error);
-#if 0
- if (fnt->rotate)
- if ((error = FT_Init_GSUB_Extension(engine)))
- oops("Cannot initialize GSUB support (error code = 0x%x).", error);
-#endif
-
/*
* Load face.
*/
@@ -273,186 +780,76 @@ FTopen (char *filename, Font *fnt, Boolean do_tfm, Boolean quiet)
set_encoding_scheme(encFontSpecific, fnt);
if (fnt->rotate)
+ fetch_GSUB();
+}
+
+static inline int
+find_ndx (int Num, Coverage_Item *coverage)
+{
+ int i;
+
+ switch (coverage->format)
{
- if ((error = FT_Load_Sfnt_Table(face, TTAG_GSUB, 0, NULL, &GSUB_length)))
- {
- warning("No GSUB data available "
- "for vertical glyph presentation forms.");
- return;
- }
- GSUB_table = mymalloc(GSUB_length);
- if ((error = FT_Load_Sfnt_Table(face, TTAG_GSUB, 0, GSUB_table, &GSUB_length)))
- {
- warning("Cannot load GSUB table (error code = 0x%x).", error);
- return;
- }
- need(10);
- if (get_ULong() != 0x00010000)
- oops("GSUB: Bad version.");
- Script_List_ptr = get_UShort();
- warning("GSUB: Script List at 0x%04x.", Script_List_ptr);
- Feature_List_ptr = get_UShort();
- warning("GSUB: Feature List at 0x%04x.", Feature_List_ptr);
- Lookup_List_ptr = get_UShort();
- warning("GSUB: Lookup List at 0x%04x.", Lookup_List_ptr);
- GSUB_ptr = Script_List_ptr;
- need(2);
- {
- FT_UShort Script_Count = get_UShort();
- need (6 * Script_Count);
- for (i = 0; i < Script_Count; i++)
+ case 1:
+ for (i = 0; i < coverage->count; i++)
{
- FT_Tag tag = get_ULong();
- FT_ULong Script_ptr = Script_List_ptr + get_UShort();
- warning("Script[%d] '%c%c%c%c' at 0x%04x.", i,
- tag >> 24, (tag >> 16) & 0xff, (tag >> 8) & 0xff, tag & 0xff,
- Script_ptr);
+ FT_UShort glyph = coverage->data.glyphs[i];
+ if (Num < glyph)
+ break;
+ else if (Num == glyph)
+ return i;
}
- }
- has_gsub = True;
-// exit(1);
-#if 0
- gsub = &gsub_;
-
- error = FT_Load_GSUB_Table(face, gsub, NULL);
- if (!error)
- has_gsub = True;
- else if (error != FT_Err_Table_Missing)
- warning("Cannot load GSUB table (error code = 0x%x).", error);
- else
- warning("No GSUB data available "
- "for vertical glyph presentation forms.");
-
- /* we check for the `vert' feature in Chinese, Japanese, and Korean */
-
- error = FT_GSUB_Select_Script(gsub,
- SCRIPT_kana,
- &script_index);
- if (error)
- goto check_hani;
- error = FT_GSUB_Select_Feature(gsub,
- FEATURE_vert,
- script_index,
- 0xFFFF,
- &feature_index);
- if (error)
- {
- error = FT_GSUB_Select_Language(gsub,
- LANGUAGE_JAN,
- script_index,
- &language_index,
- &req_feature_index);
- if (error)
- goto check_hani;
- error = FT_GSUB_Select_Feature(gsub,
- FEATURE_vert,
- script_index,
- language_index,
- &feature_index);
- if (error)
- goto check_hani;
- else
- goto Done;
- }
- else
- goto Done;
-
- check_hani:
- error = FT_GSUB_Select_Script(gsub,
- SCRIPT_hani,
- &script_index);
- if (error)
- goto check_hang;
- error = FT_GSUB_Select_Feature(gsub,
- FEATURE_vert,
- script_index,
- 0xFFFF,
- &feature_index);
- if (error)
- {
- error = FT_GSUB_Select_Language(gsub,
- LANGUAGE_CHN,
- script_index,
- &language_index,
- &req_feature_index);
- if (error)
- goto check_hang;
- error = FT_GSUB_Select_Feature(gsub,
- FEATURE_vert,
- script_index,
- language_index,
- &feature_index);
- if (error)
- goto check_hang;
- else
- goto Done;
- }
- else
- goto Done;
-
- check_hang:
- error = FT_GSUB_Select_Script(gsub,
- SCRIPT_hang,
- &script_index);
- if (error)
- goto Done;
- error = FT_GSUB_Select_Feature(gsub,
- FEATURE_vert,
- script_index,
- 0xFFFF,
- &feature_index);
- if (error)
- {
- error = FT_GSUB_Select_Language(gsub,
- LANGUAGE_KOR,
- script_index,
- &language_index,
- &req_feature_index);
- if (error)
- goto Done;
- error = FT_GSUB_Select_Feature(gsub,
- FEATURE_vert,
- script_index,
- language_index,
- &feature_index);
- }
-
- Done:
- if (error)
- {
- warning("There is no data for vertical typesetting in GSUB table.");
- has_gsub = False;
- }
-
- if (req_feature_index != 0xFFFF)
- FT_GSUB_Add_Feature(gsub, req_feature_index, ALL_GLYPHS);
- FT_GSUB_Add_Feature(gsub, feature_index, ALL_GLYPHS);
-
- in.length = 1;
- in.pos = 0;
- in.string = in_string;
- in.properties = NULL;
+ break;
+ case 2:
+ for (i = 0; i < coverage->count; i++)
+ {
+ Range_Record *range = &coverage->data.ranges[i];
- out.pos = 0;
- out.allocated = 0;
- out.string = NULL;
- out.properties = NULL;
-#endif
+ if (Num < range->start)
+ break;
+ else if (Num <= range->end)
+ return (Num - range->start) + range->start_Index;
+ }
+ break;
+ default:
+ oops("Internal error: Invalid Coverage Format=%d.", coverage->format);
}
+ return -1;
}
int
Get_Vert (int Num)
{
+ Subst_Item *entry;
+
+#ifdef DEBUG
warning("GSUB: Looking for vertical form of glyph %d.", Num);
-#if 0
- in_string[0] = Num;
- error = FT_GSUB_Apply_String(gsub, &in, &out);
- if (error && error != OTL_Err_Not_Covered)
- warning("Cannot get the vertical glyph form for glyph index %d.",
- Num);
- else
- Num = out.string[0];
#endif
+ for (entry = Subst_list; entry; entry = entry->next)
+ {
+ Single_Item *item = entry->item;
+ int ndx = find_ndx (Num, item->coverage);
+
+ if (ndx >= 0)
+ {
+#ifdef DEBUG
+ warning("Covered at position %d.", ndx);
+#endif
+ switch (item->format)
+ {
+ case 1:
+ Num += *item->data.delta;
+ break;
+ case 2:
+ Num = item->data.array->glyphs[ndx];
+ break;
+ default:
+ oops("Internal error: Invalid Single Format=%d.", item->format);
+ }
+#ifdef DEBUG
+ warning("Substituted by glyph %d.", Num);
+#endif
+ }
+ }
return Num;
}
diff --git a/Build/source/texk/ttf2pk2/newobj.c b/Build/source/texk/ttf2pk2/newobj.c
index 3639961c8cd..fc0f5836900 100644
--- a/Build/source/texk/ttf2pk2/newobj.c
+++ b/Build/source/texk/ttf2pk2/newobj.c
@@ -18,6 +18,7 @@
#include "texenc.h"
+#if !defined(HAVE_LIBKPATHSEA)
void *
mymalloc(size_t len)
{
@@ -42,6 +43,20 @@ mymalloc(size_t len)
void *
+mycalloc(size_t nmemb, size_t len)
+{
+ void *p;
+
+ p = calloc(nmemb ? nmemb : 1, len ? len : 1);
+
+ if (p == NULL)
+ oops("Out of memory.");
+
+ return p;
+}
+
+
+void *
myrealloc(void *oldp, size_t len)
{
void *p;
@@ -62,6 +77,7 @@ myrealloc(void *oldp, size_t len)
return p;
}
+#endif
/*
diff --git a/Build/source/texk/ttf2pk2/newobj.h b/Build/source/texk/ttf2pk2/newobj.h
index 52beb0737ea..7fe4c2c72c1 100644
--- a/Build/source/texk/ttf2pk2/newobj.h
+++ b/Build/source/texk/ttf2pk2/newobj.h
@@ -15,15 +15,21 @@
#include "ttf2tfm.h"
+#if defined(HAVE_LIBKPATHSEA)
+#include <kpathsea/config.h>
+#define mymalloc xmalloc
+#define mycalloc xcalloc
+#define myrealloc xrealloc
+#else
#if (defined(MSDOS) && defined(__TURBOC__)) || \
(defined(OS2) && defined(_MSC_VER))
#define SMALLMALLOC
#endif
-
void *mymalloc(size_t len);
-void *mycalloc(size_t len);
+void *mycalloc(size_t nmemb, size_t len);
void *myrealloc(void *oldp, size_t len);
+#endif
char *get_line(FILE *f);
Boolean texlive_getline(char **bufferp, FILE *f);
diff --git a/Build/source/texk/ttf2pk2/ttf2pk.c b/Build/source/texk/ttf2pk2/ttf2pk.c
index 40c81083bc6..e2a62017450 100644
--- a/Build/source/texk/ttf2pk2/ttf2pk.c
+++ b/Build/source/texk/ttf2pk2/ttf2pk.c
@@ -7,7 +7,8 @@
* Copyright 1997-1999, 2000, 2002 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>
- * Copyright 2009 Peter Breitenlohner
+ * Copyright 2009-2013 by
+ * Peter Breitenlohner <tex-live@tug.org>
*/
#include <stdio.h>
@@ -32,7 +33,7 @@
#include "subfont.h"
-char ident[] = "ttf2pk version 1.5";
+char ident[] = "ttf2pk version 2.0";
const char *progname = "ttf2pk"; /* for error/warning messages */
static const char *cfg_filename = "ttf2pk.cfg";
@@ -85,6 +86,7 @@ usage(void)
#define VERSION "\
Copyright (C) 1997-1999, 2000, 2002, 2009 Frederic Loyer and Werner Lemberg.\n\
+ 2009-2013 Peter Breitenlohner\n\
There is NO warranty. You may redistribute this software\n\
under the terms of the GNU General Public License\n\
and the gsftopk copyright.\n\
diff --git a/Build/source/texk/ttf2pk2/ttf2tfm.c b/Build/source/texk/ttf2pk2/ttf2tfm.c
index ebc92a10df9..116fa128cb6 100644
--- a/Build/source/texk/ttf2pk2/ttf2tfm.c
+++ b/Build/source/texk/ttf2pk2/ttf2tfm.c
@@ -6,6 +6,8 @@
* Copyright 1997-1999, 2000, 2002 by
* Frederic Loyer <loyer@ensta.fr>
* Werner Lemberg <wl@gnu.org>.
+ * Copyright 2009-2013 by
+ * Peter Breitenlohner <tex-live@tug.org>
*/
/*
@@ -42,7 +44,7 @@
#include "subfont.h"
-char ident[] = "ttf2tfm version 1.5";
+char ident[] = "ttf2tfm version 2.0";
const char *progname = "ttf2tfm"; /* for error/warning messages */
/* command line options */
@@ -268,6 +270,7 @@ release_subfont_list(Font *fnt)
#define VERSION "\
Copyright (C) 1997-1999, 2000, 2002 Frederic Loyer and Werner Lemberg.\n\
+ 2009-2013 Peter Breitenlohner\n\
There is NO warranty. You may redistribute this software\n\
under the terms of the GNU General Public License\n\
and the Dvips copyright.\n\