summaryrefslogtreecommitdiff
path: root/Build/source/texk/ttf2pk2/ftlib.c
diff options
context:
space:
mode:
authorPeter Breitenlohner <peb@mppmu.mpg.de>2012-09-18 17:56:42 +0000
committerPeter Breitenlohner <peb@mppmu.mpg.de>2012-09-18 17:56:42 +0000
commitbcf4f5c089878ad822ed4073e7de63b12344b978 (patch)
tree7947195be8a18a343b2b238bd4d6b758203dc17a /Build/source/texk/ttf2pk2/ftlib.c
parente3167f2329da4174fd1332e069788693de96b72a (diff)
ttf2pk: Adapt to W32TeX (from Akira)
Start handling the GSUB table Extend the test to cover vert feature from GSUB table git-svn-id: svn://tug.org/texlive/trunk@27716 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/ttf2pk2/ftlib.c')
-rw-r--r--Build/source/texk/ttf2pk2/ftlib.c454
1 files changed, 454 insertions, 0 deletions
diff --git a/Build/source/texk/ttf2pk2/ftlib.c b/Build/source/texk/ttf2pk2/ftlib.c
new file mode 100644
index 00000000000..5a45d7b15ef
--- /dev/null
+++ b/Build/source/texk/ttf2pk2/ftlib.c
@@ -0,0 +1,454 @@
+/*
+ * ftlib.c
+ *
+ * This file is part of the ttf2pk package.
+ *
+ * Copyright 1997-1999, 2000, 2002, 2003 by
+ * Frederic Loyer <loyer@ensta.fr>
+ * Werner Lemberg <wl@gnu.org>
+ *
+ * Copyright (C) 2012 by
+ * Peter Breitenlohner <tex-live@tug.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+#include FT_TRUETYPE_TABLES_H
+#include FT_OPENTYPE_VALIDATE_H
+
+#include "ttf2tfm.h"
+#include "ttfenc.h"
+#include "errormsg.h"
+#include "newobj.h"
+#include "ftlib.h"
+
+#define Macintosh_platform 1
+#define Macintosh_encoding 0
+
+#define Microsoft_platform 3
+#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;
+
+FT_Matrix matrix1, matrix2;
+
+int dpi, ptsize;
+
+Boolean has_gsub;
+
+TT_OS2 *os2;
+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)
+{
+ if (GSUB_ptr + needed > GSUB_length)
+ oops("GSUB: Unexpected end of table.");
+}
+
+static inline FT_Byte
+get_Byte(void)
+{
+ return GSUB_table[GSUB_ptr++];
+}
+
+static inline signed char
+get_SByte(void)
+{
+ return (signed char) GSUB_table[GSUB_ptr++];
+}
+
+static FT_UShort
+get_UShort(void)
+{
+ unsigned int cc;
+ cc = get_Byte() << 8;
+ cc |= get_Byte();
+ return (FT_UShort) cc;
+}
+
+static FT_Short
+get_Short(void)
+{
+ int cc;
+ cc = get_SByte() << 8;
+ cc |= get_Byte();
+ return (FT_Short) cc;
+}
+
+static FT_ULong
+get_ULong(void)
+{
+ unsigned int cc;
+ cc = get_Byte() << 24;
+ cc |= get_Byte() << 16;
+ cc |= get_Byte() << 8;
+ cc |= get_Byte();
+ return (FT_ULong) cc;
+}
+
+static FT_Long
+get_Long(void)
+{
+ int cc;
+ cc = get_SByte() << 24;
+ cc |= get_Byte() << 16;
+ cc |= get_Byte() << 8;
+ cc |= get_Byte();
+ return (FT_Long) cc;
+}
+
+#if 0
+FT_UShort in_string[2];
+
+TTO_GSUBHeader gsub_;
+TTO_GSUBHeader *gsub;
+TTO_GSUB_String in, out;
+#endif
+
+void
+FTopen (char *filename, Font *fnt, Boolean do_tfm, Boolean quiet)
+{
+ FT_Error error;
+ 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.
+ */
+ if ((error = FT_New_Face(engine, filename, 0, &face)))
+ oops("Cannot open `%s'.", filename);
+
+ if (face->num_faces == 1)
+ {
+ if (fnt->fontindex != 0)
+ {
+ warning("This isn't a TrueType collection.\n"
+ "Parameter `%s' is ignored.", do_tfm ? "-f" : "Fontindex");
+ fnt->fontindex = 0;
+ }
+ fnt->fontindexparam = NULL;
+ }
+ else
+ {
+ if (fnt->fontindex != 0)
+ {
+ /*
+ * Now we try to open the proper font in a collection.
+ */
+ FT_Done_Face(face);
+ if ((error = FT_New_Face(engine, filename, (FT_Long)fnt->fontindex, &face)))
+ oops("Cannot open font %lu in TrueType Collection `%s'.",
+ fnt->fontindex, filename);
+ }
+ }
+
+ if (do_tfm)
+ {
+ /*
+ * Get the OS/2 table.
+ */
+ if ((os2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2)) == NULL)
+ oops("Cannot find OS/2 table for `%s'.", filename);
+
+ /*
+ * Get the Postscript table.
+ */
+ if ((postscript = FT_Get_Sfnt_Table(face, ft_sfnt_post)) == NULL)
+ oops("Cannot find Postscript table for `%s'.", filename);
+ }
+
+ if ((error = FT_Set_Char_Size(face, ptsize * 64, ptsize * 64, dpi, dpi)))
+ oops("Cannot set character size (error code = 0x%x).", error);
+
+ matrix1.xx = (FT_Fixed)(floor(fnt->efactor * 1024) * (1<<16)/1024);
+ matrix1.xy = (FT_Fixed)(floor(fnt->slant * 1024) * (1<<16)/1024);
+ matrix1.yx = (FT_Fixed)0;
+ matrix1.yy = (FT_Fixed)(1<<16);
+
+ if (fnt->rotate)
+ {
+ matrix2.xx = 0;
+ matrix2.yx = 1L << 16;
+ matrix2.xy = -matrix2.yx;
+ matrix2.yy = matrix2.xx;
+ }
+
+ if (do_tfm)
+ {
+ fnt->units_per_em = face->units_per_EM;
+ fnt->fixedpitch = postscript->isFixedPitch;
+ fnt->italicangle = postscript->italicAngle / 65536.0;
+ fnt->xheight = os2->sxHeight * 1000 / fnt->units_per_em;
+ }
+
+ if (fnt->PSnames != Only)
+ {
+ num_cmap = face->num_charmaps;
+ for (i = 0; i < num_cmap; i++)
+ {
+ cmap_plat=face->charmaps[i]->platform_id;
+ cmap_enc=face->charmaps[i]->encoding_id;
+ if (cmap_plat == fnt->pid && cmap_enc == fnt->eid)
+ break;
+ }
+ if (i == num_cmap)
+ {
+ fprintf(stderr, "%s: ERROR: Invalid platform and/or encoding ID.\n",
+ progname);
+ if (num_cmap == 1)
+ fprintf(stderr, " The only valid PID/EID pair is");
+ else
+ fprintf(stderr, " Valid PID/EID pairs are:\n");
+ for (i = 0; i < num_cmap; i++)
+ {
+ cmap_plat=face->charmaps[i]->platform_id;
+ cmap_enc=face->charmaps[i]->encoding_id;
+ fprintf(stderr, " (%i,%i)\n", cmap_plat, cmap_enc);
+ }
+ fprintf(stderr, "\n");
+ exit(1);
+ }
+
+ if ((error = FT_Set_Charmap(face, face->charmaps[i])))
+ oops("Cannot load cmap (error code = 0x%x).", error);
+ }
+
+ if (fnt->PSnames)
+ {
+ if (!FT_HAS_GLYPH_NAMES(face))
+ oops("This font does not support PS names.");
+ }
+ else if (cmap_plat == Microsoft_platform &&
+ cmap_enc == Microsoft_Unicode_encoding)
+ set_encoding_scheme(encUnicode, fnt);
+ else if (cmap_plat == Macintosh_platform &&
+ cmap_enc == Macintosh_encoding)
+ set_encoding_scheme(encMac, fnt);
+ else
+ set_encoding_scheme(encFontSpecific, fnt);
+
+ if (fnt->rotate)
+ {
+ 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++)
+ {
+ 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);
+ }
+ }
+ 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;
+
+ out.pos = 0;
+ out.allocated = 0;
+ out.string = NULL;
+ out.properties = NULL;
+#endif
+ }
+}
+
+int
+Get_Vert (int Num)
+{
+ 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
+ return Num;
+}