diff options
author | Peter Breitenlohner <peb@mppmu.mpg.de> | 2013-06-24 09:42:47 +0000 |
---|---|---|
committer | Peter Breitenlohner <peb@mppmu.mpg.de> | 2013-06-24 09:42:47 +0000 |
commit | e82a4ec6e8f06840867512112128041581c022e7 (patch) | |
tree | 19f7ea4fe44f1ae5f9c7b1dd349b7e2ba1cb9ba1 | |
parent | d8ee324e03e46ef3361a8ade3062034bc45795af (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/ChangeLog | 4 | ||||
-rw-r--r-- | Build/source/texk/ttf2pk/ac/withenable.ac | 4 | ||||
-rw-r--r-- | Build/source/texk/ttf2pk2/ChangeLog | 11 | ||||
-rw-r--r-- | Build/source/texk/ttf2pk2/ac/withenable.ac | 4 | ||||
-rw-r--r-- | Build/source/texk/ttf2pk2/configure.ac | 4 | ||||
-rw-r--r-- | Build/source/texk/ttf2pk2/ftlib.c | 805 | ||||
-rw-r--r-- | Build/source/texk/ttf2pk2/newobj.c | 16 | ||||
-rw-r--r-- | Build/source/texk/ttf2pk2/newobj.h | 10 | ||||
-rw-r--r-- | Build/source/texk/ttf2pk2/ttf2pk.c | 6 | ||||
-rw-r--r-- | Build/source/texk/ttf2pk2/ttf2tfm.c | 5 |
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\ |