aboutsummaryrefslogtreecommitdiff
path: root/nx-X11/extras/ttf2pt1/ttf.c
diff options
context:
space:
mode:
authorMike Gabriel <mike.gabriel@das-netzwerkteam.de>2015-02-02 15:02:49 +0100
committerMike Gabriel <mike.gabriel@das-netzwerkteam.de>2015-02-02 15:02:49 +0100
commitb16b9e4656e7199c2aec74a4c8ebc7a875d3ba73 (patch)
tree4361edef0d42d5bf5ac984ef72b4fac35426eae7 /nx-X11/extras/ttf2pt1/ttf.c
parent0d5a83e986f39982c0924652a3662e60b1f23162 (diff)
downloadnx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.tar.gz
nx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.tar.bz2
nx-libs-b16b9e4656e7199c2aec74a4c8ebc7a875d3ba73.zip
massive reduction of unneeded files
Diffstat (limited to 'nx-X11/extras/ttf2pt1/ttf.c')
-rw-r--r--nx-X11/extras/ttf2pt1/ttf.c1480
1 files changed, 0 insertions, 1480 deletions
diff --git a/nx-X11/extras/ttf2pt1/ttf.c b/nx-X11/extras/ttf2pt1/ttf.c
deleted file mode 100644
index b5cc5bdf8..000000000
--- a/nx-X11/extras/ttf2pt1/ttf.c
+++ /dev/null
@@ -1,1480 +0,0 @@
-/*
- * True Type Font to Adobe Type 1 font converter
- * By Mark Heath <mheath@netspace.net.au>
- * Based on ttf2pfa by Andrew Weeks <ccsaw@bath.ac.uk>
- * With help from Frank M. Siegert <fms@this.net>
- *
- * see COPYRIGHT
- *
- */
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <time.h>
-#include <ctype.h>
-#include <math.h>
-
-#ifndef WINDOWS
-# include <unistd.h>
-# include <netinet/in.h>
-#else
-# include "windows.h"
-#endif
-
-#include "ttf.h"
-#include "pt1.h"
-#include "global.h"
-
-/* prototypes of call entries */
-static void openfont(char *fname, char *arg);
-static void closefont( void);
-static int getnglyphs ( void);
-static int glnames( GLYPH *glyph_list);
-static void glmetrics( GLYPH *glyph_list);
-static int glenc( GLYPH *glyph_list, int *encoding, int *unimap);
-static void fnmetrics( struct font_metrics *fm);
-static void glpath( int glyphno, GLYPH *glyph_list);
-static void kerning( GLYPH *glyph_list);
-
-/* globals */
-
-/* front-end descriptor */
-struct frontsw ttf_sw = {
- /*name*/ "ttf",
- /*descr*/ "built-in TTF support",
- /*suffix*/ { "ttf" },
- /*open*/ openfont,
- /*close*/ closefont,
- /*nglyphs*/ getnglyphs,
- /*glnames*/ glnames,
- /*glmetrics*/ glmetrics,
- /*glenc*/ glenc,
- /*fnmetrics*/ fnmetrics,
- /*glpath*/ glpath,
- /*kerning*/ kerning,
-};
-
-/* statics */
-
-static FILE *ttf_file;
-static int ttf_nglyphs, long_offsets;
-
-static TTF_DIRECTORY *directory;
-static TTF_DIR_ENTRY *dir_entry;
-static char *filebuffer;
-static char *filebuffer_end;
-static TTF_NAME *name_table = NULL;
-static TTF_NAME_REC *name_record;
-static TTF_HEAD *head_table = NULL;
-static TTF_HHEA *hhea_table = NULL;
-static TTF_KERN *kern_table = NULL;
-static TTF_CMAP *cmap_table = NULL;
-static LONGHORMETRIC *hmtx_table = NULL;
-static TTF_GLYF *glyf_table;
-static BYTE *glyf_start = NULL;
-static TTF_MAXP *maxp_table = NULL;
-static TTF_POST_HEAD *post_table = NULL;
-static union {
- USHORT *sp;
- ULONG *lp;
-} loca_table;
-#define short_loca_table loca_table.sp
-#define long_loca_table loca_table.lp
-
-static short cmap_n_segs;
-static USHORT *cmap_seg_start, *cmap_seg_end;
-static short *cmap_idDelta, *cmap_idRangeOffset;
-static TTF_CMAP_FMT0 *encoding0;
-static int enc_type;
-
-static char name_buffer[2000];
-static char *name_fields[8];
-
-static int enc_found_ms, enc_found_mac;
-
-static char *mac_glyph_names[258] = {
- ".notdef", ".null", "CR",
- "space", "exclam", "quotedbl", "numbersign",
- "dollar", "percent", "ampersand", "quotesingle",
- "parenleft", "parenright", "asterisk", "plus",
- "comma", "hyphen", "period", "slash",
- "zero", "one", "two", "three",
- "four", "five", "six", "seven",
- "eight", "nine", "colon", "semicolon",
- "less", "equal", "greater", "question",
- "at", "A", "B", "C",
- "D", "E", "F", "G",
- "H", "I", "J", "K",
- "L", "M", "N", "O",
- "P", "Q", "R", "S",
- "T", "U", "V", "W",
- "X", "Y", "Z", "bracketleft",
- "backslash", "bracketright", "asciicircum", "underscore",
- "grave", "a", "b", "c",
- "d", "e", "f", "g",
- "h", "i", "j", "k",
- "l", "m", "n", "o",
- "p", "q", "r", "s",
- "t", "u", "v", "w",
- "x", "y", "z", "braceleft",
- "bar", "braceright", "asciitilde", "Adieresis",
- "Aring", "Ccedilla", "Eacute", "Ntilde",
- "Odieresis", "Udieresis", "aacute", "agrave",
- "acircumflex", "adieresis", "atilde", "aring",
- "ccedilla", "eacute", "egrave", "ecircumflex",
- "edieresis", "iacute", "igrave", "icircumflex",
- "idieresis", "ntilde", "oacute", "ograve",
- "ocircumflex", "odieresis", "otilde", "uacute",
- "ugrave", "ucircumflex", "udieresis", "dagger",
- "degree", "cent", "sterling", "section",
- "bullet", "paragraph", "germandbls", "registered",
- "copyright", "trademark", "acute", "dieresis",
- "notequal", "AE", "Oslash", "infinity",
- "plusminus", "lessequal", "greaterequal", "yen",
- "mu", "partialdiff", "summation", "product",
- "pi", "integral", "ordfeminine", "ordmasculine",
- "Omega", "ae", "oslash", "questiondown",
- "exclamdown", "logicalnot", "radical", "florin",
- "approxequal", "increment", "guillemotleft", "guillemotright",
- "ellipsis", "nbspace", "Agrave", "Atilde",
- "Otilde", "OE", "oe", "endash",
- "emdash", "quotedblleft", "quotedblright", "quoteleft",
- "quoteright", "divide", "lozenge", "ydieresis",
- "Ydieresis", "fraction", "currency", "guilsinglleft",
- "guilsinglright", "fi", "fl", "daggerdbl",
- "periodcentered", "quotesinglbase", "quotedblbase", "perthousand",
- "Acircumflex", "Ecircumflex", "Aacute", "Edieresis",
- "Egrave", "Iacute", "Icircumflex", "Idieresis",
- "Igrave", "Oacute", "Ocircumflex", "applelogo",
- "Ograve", "Uacute", "Ucircumflex", "Ugrave",
- "dotlessi", "circumflex", "tilde", "macron",
- "breve", "dotaccent", "ring", "cedilla",
- "hungarumlaut", "ogonek", "caron", "Lslash",
- "lslash", "Scaron", "scaron", "Zcaron",
- "zcaron", "brokenbar", "Eth", "eth",
- "Yacute", "yacute", "Thorn", "thorn",
- "minus", "multiply", "onesuperior", "twosuperior",
- "threesuperior", "onehalf", "onequarter", "threequarters",
- "franc", "Gbreve", "gbreve", "Idot",
- "Scedilla", "scedilla", "Cacute", "cacute",
- "Ccaron", "ccaron", "dmacron"
-};
-
-/* other prototypes */
-static void draw_composite_glyf( GLYPH *g, GLYPH *glyph_list, int glyphno,
- double *matrix, int level);
-static void draw_simple_glyf( GLYPH *g, GLYPH *glyph_list, int glyphno,
- double *matrix);
-static double f2dot14( short x);
-
-/* get the TTF description table address and length for this index */
-
-static void
-get_glyf_table(
- int glyphno,
- TTF_GLYF **tab,
- int *len
-)
-{
- if(tab!=NULL) {
- if (long_offsets) {
- *tab = (TTF_GLYF *) (glyf_start + ntohl(long_loca_table[glyphno]));
- } else {
- *tab = (TTF_GLYF *) (glyf_start + (ntohs(short_loca_table[glyphno]) << 1));
- }
- }
- if(len!=NULL) {
- if (long_offsets) {
- *len = ntohl(long_loca_table[glyphno + 1]) - ntohl(long_loca_table[glyphno]);
- } else {
- *len = (ntohs(short_loca_table[glyphno + 1]) - ntohs(short_loca_table[glyphno])) << 1;
- }
- }
-}
-
-static void
-handle_name(void)
-{
- int j, k, lang, len, platform;
- char *p, *string_area;
- char *nbp = name_buffer;
- int found3 = 0;
-
- string_area = (char *) name_table + ntohs(name_table->offset);
- name_record = &(name_table->nameRecords);
-
- for (j = 0; j < 8; j++) {
- name_fields[j] = "";
- }
-
- for (j = 0; j < ntohs(name_table->numberOfNameRecords); j++) {
-
- platform = ntohs(name_record->platformID);
-
- if (platform == 3) {
-
- found3 = 1;
- lang = ntohs(name_record->languageID) & 0xff;
- len = ntohs(name_record->stringLength);
- if (lang == 0 || lang == 9) {
- k = ntohs(name_record->nameID);
- if (k < 8) {
- name_fields[k] = nbp;
-
- p = string_area + ntohs(name_record->stringOffset);
- for (k = 0; k < len; k++) {
- if (p[k] != '\0') {
- if (p[k] == '(') {
- *nbp = '[';
- } else if (p[k] == ')') {
- *nbp = ']';
- } else {
- *nbp = p[k];
- }
- nbp++;
- }
- }
- *nbp = '\0';
- nbp++;
- }
- }
- }
- name_record++;
- }
-
- string_area = (char *) name_table + ntohs(name_table->offset);
- name_record = &(name_table->nameRecords);
-
- if (!found3) {
- for (j = 0; j < ntohs(name_table->numberOfNameRecords); j++) {
-
- platform = ntohs(name_record->platformID);
-
- if (platform == 1) {
-
- found3 = 1;
- lang = ntohs(name_record->languageID) & 0xff;
- len = ntohs(name_record->stringLength);
- if (lang == 0 || lang == 9) {
- k = ntohs(name_record->nameID);
- if (k < 8) {
- name_fields[k] = nbp;
-
- p = string_area + ntohs(name_record->stringOffset);
- for (k = 0; k < len; k++) {
- if (p[k] != '\0') {
- if (p[k] == '(') {
- *nbp = '[';
- } else if (p[k] == ')') {
- *nbp = ']';
- } else {
- *nbp = p[k];
- }
- nbp++;
- }
- }
- *nbp = '\0';
- nbp++;
- }
- }
- }
- name_record++;
- }
- }
- if (!found3) {
- fprintf(stderr, "**** Cannot decode font name fields ****\n");
- exit(1);
- }
- if (name_fields[4][0] == 0) { /* Full Name empty, use Family Name */
- name_fields[4] = name_fields[1];
- }
- if (name_fields[6][0] == 0) { /* Font Name empty, use Full Name */
- name_fields[6] = name_fields[4];
- if (name_fields[6][0] == 0) { /* oops, empty again */
- WARNING_1 fprintf(stderr, "Font name is unknown, setting to \"Unknown\"\n");
- name_fields[6] = "Unknown";
- }
- }
- p = name_fields[6];
- /* must not start with a digit */
- if(isdigit(*p))
- *p+= 'A'-'0'; /* change to a letter */
- while (*p != '\0') {
- if (!isalnum(*p) || *p=='_') {
- *p = '-';
- }
- p++;
- }
-}
-
-static void
-handle_head(void)
-{
- long_offsets = ntohs(head_table->indexToLocFormat);
- if (long_offsets != 0 && long_offsets != 1) {
- fprintf(stderr, "**** indexToLocFormat wrong ****\n");
- exit(1);
- }
-}
-
-/* limit the recursion level to avoid cycles */
-#define MAX_COMPOSITE_LEVEL 20
-
-static void
-draw_composite_glyf(
- GLYPH *g,
- GLYPH *glyph_list,
- int glyphno,
- double *orgmatrix,
- int level
-)
-{
- int len;
- short ncontours;
- USHORT flagbyte, glyphindex;
- double arg1, arg2;
- BYTE *ptr;
- char *bptr;
- SHORT *sptr;
- double matrix[6], newmatrix[6];
-
- get_glyf_table(glyphno, &glyf_table, &len);
-
- if(len<=0) /* nothing to do */
- return;
-
- ncontours = ntohs(glyf_table->numberOfContours);
- if (ncontours >= 0) { /* simple case */
- draw_simple_glyf(g, glyph_list, glyphno, orgmatrix);
- return;
- }
-
- if(ISDBG(COMPOSITE) && level ==0)
- fprintf(stderr, "* %s [ %.2f %.2f %.2f %.2f %.2f %.2f ]\n", g->name,
- orgmatrix[0], orgmatrix[1], orgmatrix[2], orgmatrix[3],
- orgmatrix[4], orgmatrix[5]);
-
- /* complex case */
- if(level >= MAX_COMPOSITE_LEVEL) {
- WARNING_1 fprintf(stderr,
- "*** Glyph %s: stopped (possibly infinite) recursion at depth %d\n",
- g->name, level);
- return;
- }
-
- ptr = ((BYTE *) glyf_table + sizeof(TTF_GLYF));
- sptr = (SHORT *) ptr;
- do {
- flagbyte = ntohs(*sptr);
- sptr++;
- glyphindex = ntohs(*sptr);
- sptr++;
-
- if (flagbyte & ARG_1_AND_2_ARE_WORDS) {
- arg1 = (short)ntohs(*sptr);
- sptr++;
- arg2 = (short)ntohs(*sptr);
- sptr++;
- } else {
- bptr = (char *) sptr;
- arg1 = (signed char) bptr[0];
- arg2 = (signed char) bptr[1];
- sptr++;
- }
- matrix[1] = matrix[2] = 0.0;
-
- if (flagbyte & WE_HAVE_A_SCALE) {
- matrix[0] = matrix[3] = f2dot14(*sptr);
- sptr++;
- } else if (flagbyte & WE_HAVE_AN_X_AND_Y_SCALE) {
- matrix[0] = f2dot14(*sptr);
- sptr++;
- matrix[3] = f2dot14(*sptr);
- sptr++;
- } else if (flagbyte & WE_HAVE_A_TWO_BY_TWO) {
- matrix[0] = f2dot14(*sptr);
- sptr++;
- matrix[2] = f2dot14(*sptr);
- sptr++;
- matrix[1] = f2dot14(*sptr);
- sptr++;
- matrix[3] = f2dot14(*sptr);
- sptr++;
- } else {
- matrix[0] = matrix[3] = 1.0;
- }
-
- /*
- * See *
- * http://fonts.apple.com/TTRefMan/RM06/Chap6g
- * lyf.html * matrix[0,1,2,3,4,5]=a,b,c,d,m,n
- */
-
- if (fabs(matrix[0]) > fabs(matrix[1]))
- matrix[4] = fabs(matrix[0]);
- else
- matrix[4] = fabs(matrix[1]);
- if (fabs(fabs(matrix[0]) - fabs(matrix[2])) <= 33. / 65536.)
- matrix[4] *= 2.0;
-
- if (fabs(matrix[2]) > fabs(matrix[3]))
- matrix[5] = fabs(matrix[2]);
- else
- matrix[5] = fabs(matrix[3]);
- if (fabs(fabs(matrix[2]) - fabs(matrix[3])) <= 33. / 65536.)
- matrix[5] *= 2.0;
-
- /*
- * fprintf (stderr,"Matrix Opp %hd
- * %hd\n",arg1,arg2);
- */
-#if 0
- fprintf(stderr, "Matrix: %f %f %f %f %f %f\n",
- matrix[0], matrix[1], matrix[2], matrix[3],
- matrix[4], matrix[5]);
- fprintf(stderr, "Offset: %f %f (%s)\n",
- arg1, arg2,
- ((flagbyte & ARGS_ARE_XY_VALUES) ? "XY" : "index"));
-#endif
-
- if (flagbyte & ARGS_ARE_XY_VALUES) {
- matrix[4] *= arg1;
- matrix[5] *= arg2;
- } else {
- WARNING_1 fprintf(stderr,
- "*** Glyph %s: reusing scale from another glyph is unsupported\n",
- g->name);
- /*
- * must extract values from a glyph
- * but it seems to be too much pain
- * and it's not clear now that it
- * would be really used in any
- * interesting font
- */
- }
-
- /* at this point arg1,arg2 contain what logically should be matrix[4,5] */
-
- /* combine matrices */
-
- newmatrix[0] = orgmatrix[0]*matrix[0] + orgmatrix[2]*matrix[1];
- newmatrix[1] = orgmatrix[0]*matrix[2] + orgmatrix[2]*matrix[3];
-
- newmatrix[2] = orgmatrix[1]*matrix[0] + orgmatrix[3]*matrix[1];
- newmatrix[3] = orgmatrix[1]*matrix[2] + orgmatrix[3]*matrix[3];
-
- newmatrix[4] = orgmatrix[0]*matrix[4] + orgmatrix[2]*matrix[5] + orgmatrix[4];
- newmatrix[5] = orgmatrix[1]*matrix[4] + orgmatrix[3]*matrix[5] + orgmatrix[5];
-
- if(ISDBG(COMPOSITE)) {
- fprintf(stderr, "%*c+-> %2d %s [ %.2f %.2f %.2f %.2f %.2f %.2f ]\n",
- level+1, ' ', level, glyph_list[glyphindex].name,
- matrix[0], matrix[1], matrix[2], matrix[3],
- matrix[4], matrix[5]);
- fprintf(stderr, "%*c = [ %.2f %.2f %.2f %.2f %.2f %.2f ]\n",
- level+1, ' ',
- newmatrix[0], newmatrix[1], newmatrix[2], newmatrix[3],
- newmatrix[4], newmatrix[5]);
- }
- draw_composite_glyf(g, glyph_list, glyphindex, newmatrix, level+1);
-
- } while (flagbyte & MORE_COMPONENTS);
-}
-
-static void
-draw_simple_glyf(
- GLYPH *g,
- GLYPH *glyph_list,
- int glyphno,
- double *matrix
-)
-{
- int i, j, k, k1, len, first, cs, ce;
- /* We assume that hsbw always sets to(0, 0) */
- double xlast = 0, ylast = 0;
- int finished, nguide, contour_start, contour_end;
- short ncontours, n_inst, last_point;
- USHORT *contour_end_pt;
- BYTE *ptr;
-#define GLYFSZ 2000
- short xabs[GLYFSZ], yabs[GLYFSZ], xrel[GLYFSZ], yrel[GLYFSZ];
- double xcoord[GLYFSZ], ycoord[GLYFSZ];
- BYTE flags[GLYFSZ];
- double tx, ty;
- int needreverse = 0; /* transformation may require
- * that */
- GENTRY *lge;
-
- lge = g->lastentry;
-
- get_glyf_table(glyphno, &glyf_table, &len);
-
- if (len <= 0) {
- WARNING_1 fprintf(stderr,
- "**** Composite glyph %s refers to non-existent glyph %s, ignored\n",
- g->name,
- glyph_list[glyphno].name);
- return;
- }
- ncontours = ntohs(glyf_table->numberOfContours);
- if (ncontours < 0) {
- WARNING_1 fprintf(stderr,
- "**** Composite glyph %s refers to composite glyph %s, ignored\n",
- g->name,
- glyph_list[glyphno].name);
- return;
- }
- contour_end_pt = (USHORT *) ((char *) glyf_table + sizeof(TTF_GLYF));
-
- last_point = ntohs(contour_end_pt[ncontours - 1]);
- n_inst = ntohs(contour_end_pt[ncontours]);
-
- ptr = ((BYTE *) contour_end_pt) + (ncontours << 1) + n_inst + 2;
- j = k = 0;
- while (k <= last_point) {
- flags[k] = ptr[j];
-
- if (ptr[j] & REPEAT) {
- for (k1 = 0; k1 < ptr[j + 1]; k1++) {
- k++;
- flags[k] = ptr[j];
- }
- j++;
- }
- j++;
- k++;
- }
-
- for (k = 0; k <= last_point; k++) {
- if (flags[k] & XSHORT) {
- if (flags[k] & XSAME) {
- xrel[k] = ptr[j];
- } else {
- xrel[k] = -ptr[j];
- }
- j++;
- } else if (flags[k] & XSAME) {
- xrel[k] = 0.0;
- } else {
- xrel[k] = (short)( ptr[j] * 256 + ptr[j + 1] );
- j += 2;
- }
- if (k == 0) {
- xabs[k] = xrel[k];
- } else {
- xabs[k] = xrel[k] + xabs[k - 1];
- }
-
- }
-
- for (k = 0; k <= last_point; k++) {
- if (flags[k] & YSHORT) {
- if (flags[k] & YSAME) {
- yrel[k] = ptr[j];
- } else {
- yrel[k] = -ptr[j];
- }
- j++;
- } else if (flags[k] & YSAME) {
- yrel[k] = 0;
- } else {
- yrel[k] = ptr[j] * 256 + ptr[j + 1];
- j += 2;
- }
- if (k == 0) {
- yabs[k] = yrel[k];
- } else {
- yabs[k] = yrel[k] + yabs[k - 1];
- }
- }
-
- if (matrix) {
- for (i = 0; i <= last_point; i++) {
- tx = xabs[i];
- ty = yabs[i];
- xcoord[i] = fscale(matrix[0] * tx + matrix[2] * ty + matrix[4]);
- ycoord[i] = fscale(matrix[1] * tx + matrix[3] * ty + matrix[5]);
- }
- } else {
- for (i = 0; i <= last_point; i++) {
- xcoord[i] = fscale(xabs[i]);
- ycoord[i] = fscale(yabs[i]);
- }
- }
-
- i = j = 0;
- first = 1;
-
- while (i <= ntohs(contour_end_pt[ncontours - 1])) {
- contour_end = ntohs(contour_end_pt[j]);
-
- if (first) {
- fg_rmoveto(g, xcoord[i], ycoord[i]);
- xlast = xcoord[i];
- ylast = ycoord[i];
- contour_start = i;
- first = 0;
- } else if (flags[i] & ONOROFF) {
- fg_rlineto(g, xcoord[i], ycoord[i]);
- xlast = xcoord[i];
- ylast = ycoord[i];
- } else {
- cs = i - 1;
- finished = nguide = 0;
- while (!finished) {
- if (i == contour_end + 1) {
- ce = contour_start;
- finished = 1;
- } else if (flags[i] & ONOROFF) {
- ce = i;
- finished = 1;
- } else {
- i++;
- nguide++;
- }
- }
-
- switch (nguide) {
- case 0:
- fg_rlineto(g, xcoord[ce], ycoord[ce]);
- xlast = xcoord[ce];
- ylast = ycoord[ce];
- break;
-
- case 1:
- fg_rrcurveto(g,
- (xcoord[cs] + 2.0 * xcoord[cs + 1]) / 3.0,
- (ycoord[cs] + 2.0 * ycoord[cs + 1]) / 3.0,
- (2.0 * xcoord[cs + 1] + xcoord[ce]) / 3.0,
- (2.0 * ycoord[cs + 1] + ycoord[ce]) / 3.0,
- xcoord[ce],
- ycoord[ce]
- );
- xlast = xcoord[ce];
- ylast = ycoord[ce];
-
- break;
-
- case 2:
- fg_rrcurveto(g,
- (-xcoord[cs] + 4.0 * xcoord[cs + 1]) / 3.0,
- (-ycoord[cs] + 4.0 * ycoord[cs + 1]) / 3.0,
- (4.0 * xcoord[cs + 2] - xcoord[ce]) / 3.0,
- (4.0 * ycoord[cs + 2] - ycoord[ce]) / 3.0,
- xcoord[ce],
- ycoord[ce]
- );
- xlast = xcoord[ce];
- ylast = ycoord[ce];
- break;
-
- case 3:
- fg_rrcurveto(g,
- (xcoord[cs] + 2.0 * xcoord[cs + 1]) / 3.0,
- (ycoord[cs] + 2.0 * ycoord[cs + 1]) / 3.0,
- (5.0 * xcoord[cs + 1] + xcoord[cs + 2]) / 6.0,
- (5.0 * ycoord[cs + 1] + ycoord[cs + 2]) / 6.0,
- (xcoord[cs + 1] + xcoord[cs + 2]) / 2.0,
- (ycoord[cs + 1] + ycoord[cs + 2]) / 2.0
- );
-
- fg_rrcurveto(g,
- (xcoord[cs + 1] + 5.0 * xcoord[cs + 2]) / 6.0,
- (ycoord[cs + 1] + 5.0 * ycoord[cs + 2]) / 6.0,
- (5.0 * xcoord[cs + 2] + xcoord[cs + 3]) / 6.0,
- (5.0 * ycoord[cs + 2] + ycoord[cs + 3]) / 6.0,
- (xcoord[cs + 3] + xcoord[cs + 2]) / 2.0,
- (ycoord[cs + 3] + ycoord[cs + 2]) / 2.0
- );
-
- fg_rrcurveto(g,
- (xcoord[cs + 2] + 5.0 * xcoord[cs + 3]) / 6.0,
- (ycoord[cs + 2] + 5.0 * ycoord[cs + 3]) / 6.0,
- (2.0 * xcoord[cs + 3] + xcoord[ce]) / 3.0,
- (2.0 * ycoord[cs + 3] + ycoord[ce]) / 3.0,
- xcoord[ce],
- ycoord[ce]
- );
- ylast = ycoord[ce];
- xlast = xcoord[ce];
-
- break;
-
- default:
- k1 = cs + nguide;
- fg_rrcurveto(g,
- (xcoord[cs] + 2.0 * xcoord[cs + 1]) / 3.0,
- (ycoord[cs] + 2.0 * ycoord[cs + 1]) / 3.0,
- (5.0 * xcoord[cs + 1] + xcoord[cs + 2]) / 6.0,
- (5.0 * ycoord[cs + 1] + ycoord[cs + 2]) / 6.0,
- (xcoord[cs + 1] + xcoord[cs + 2]) / 2.0,
- (ycoord[cs + 1] + ycoord[cs + 2]) / 2.0
- );
-
- for (k = cs + 2; k <= k1 - 1; k++) {
- fg_rrcurveto(g,
- (xcoord[k - 1] + 5.0 * xcoord[k]) / 6.0,
- (ycoord[k - 1] + 5.0 * ycoord[k]) / 6.0,
- (5.0 * xcoord[k] + xcoord[k + 1]) / 6.0,
- (5.0 * ycoord[k] + ycoord[k + 1]) / 6.0,
- (xcoord[k] + xcoord[k + 1]) / 2.0,
- (ycoord[k] + ycoord[k + 1]) / 2.0
- );
-
- }
-
- fg_rrcurveto(g,
- (xcoord[k1 - 1] + 5.0 * xcoord[k1]) / 6.0,
- (ycoord[k1 - 1] + 5.0 * ycoord[k1]) / 6.0,
- (2.0 * xcoord[k1] + xcoord[ce]) / 3.0,
- (2.0 * ycoord[k1] + ycoord[ce]) / 3.0,
- xcoord[ce],
- ycoord[ce]
- );
- xlast = xcoord[ce];
- ylast = ycoord[ce];
-
- break;
- }
- }
- if (i >= contour_end) {
- g_closepath(g);
- first = 1;
- i = contour_end + 1;
- j++;
- } else {
- i++;
- }
- }
-
- if (matrix) {
- /* guess whether do we need to reverse the results */
-
- double x[3], y[3];
- int max = 0, from, to;
-
- /* transform a triangle going in proper direction */
- /*
- * the origin of triangle is in (0,0) so we know it in
- * advance
- */
-
- x[0] = y[0] = 0;
- x[1] = matrix[0] * 0 + matrix[2] * 300;
- y[1] = matrix[1] * 0 + matrix[3] * 300;
- x[2] = matrix[0] * 300 + matrix[2] * 0;
- y[2] = matrix[1] * 300 + matrix[3] * 0;
-
- /* then find the topmost point */
- for (i = 0; i < 3; i++)
- if (y[i] > y[max])
- max = i;
- from = (max + 3 - 1) % 3;
- to = (max + 1) % 3;
-
- needreverse = 0;
-
- /* special cases for horizontal lines */
- if (y[max] == y[from]) {
- if (x[max] < y[from])
- needreverse = 1;
- } else if (y[to] == y[from]) {
- if (x[to] < x[max])
- needreverse = 1;
- } else { /* generic case */
- if ((x[to] - x[max]) * (y[max] - y[from])
- > (x[max] - x[from]) * (y[to] - y[max]))
- needreverse = 1;
- }
-
- if (needreverse) {
- if (lge) {
- assertpath(lge->next, __FILE__, __LINE__, g->name);
- reversepathsfromto(lge->next, NULL);
- } else {
- assertpath(g->entries, __FILE__, __LINE__, g->name);
- reversepaths(g);
- }
- }
- }
-}
-
-static double
-f2dot14(
- short x
-)
-{
- short y = ntohs(x);
- return (y >> 14) + ((y & 0x3fff) / 16384.0);
-}
-
-
-/* check that the pointer points within the file */
-/* returns 0 if pointer is good, 1 if bad */
-static int
-badpointer(
- void *ptr
-)
-{
- return (ptr < (void *)filebuffer || ptr >= (void *)filebuffer_end);
-}
-
-/*
- * Externally accessible methods
- */
-
-/*
- * Open font and prepare to return information to the main driver.
- * May print error and warning messages.
- * Exit on error.
- */
-
-static void
-openfont(
- char *fname,
- char *arg /* unused now */
-)
-{
- int i, j;
- struct stat statbuf;
- static struct {
- void **tbpp; /* pointer to pointer to the table */
- char name[5]; /* table name */
- char optional; /* flag: table may be missing */
- } tables[] = {
- { (void **)&name_table, "name", 0 },
- { (void **)&head_table, "head", 0 },
- { (void **)&hhea_table, "hhea", 0 },
- { (void **)&post_table, "post", 0 },
- { (void **)&glyf_start, "glyf", 0 },
- { (void **)&cmap_table, "cmap", 0 },
- { (void **)&kern_table, "kern", 1 },
- { (void **)&maxp_table, "maxp", 0 },
- { (void **)&hmtx_table, "hmtx", 0 },
- { (void **)&long_loca_table, "loca", 0 },
- { NULL, "", 0 } /* end of table */
- };
-
- if (stat(fname, &statbuf) == -1) {
- fprintf(stderr, "**** Cannot access %s ****\n", fname);
- exit(1);
- }
- if ((filebuffer = malloc(statbuf.st_size)) == NULL) {
- fprintf(stderr, "**** Cannot malloc space for file ****\n");
- exit(1);
- }
-
- filebuffer_end = filebuffer + statbuf.st_size;
-
- if ((ttf_file = fopen(fname, "rb")) == NULL) {
- fprintf(stderr, "**** Cannot open file '%s'\n", fname);
- exit(1);
- } else {
- WARNING_2 fprintf(stderr, "Processing file %s\n", fname);
- }
-
- if (fread(filebuffer, 1, statbuf.st_size, ttf_file) != statbuf.st_size) {
- fprintf(stderr, "**** Could not read whole file \n");
- exit(1);
- }
- fclose(ttf_file);
-
- directory = (TTF_DIRECTORY *) filebuffer;
-
- if (ntohl(directory->sfntVersion) != 0x00010000) {
- fprintf(stderr,
- "**** Unknown File Version number [%x], or not a TrueType file\n",
- directory->sfntVersion);
- exit(1);
- }
-
- /* clear the tables */
- for(j=0; tables[j].tbpp != NULL; j++)
- *(tables[j].tbpp) = NULL;
-
- dir_entry = &(directory->list);
-
- for (i = 0; i < ntohs(directory->numTables); i++) {
-
- for(j=0; tables[j].tbpp != NULL; j++)
- if (memcmp(dir_entry->tag, tables[j].name, 4) == 0) {
- *(tables[j].tbpp) = (void *) (filebuffer + ntohl(dir_entry->offset));
- break;
- }
-
- if (memcmp(dir_entry->tag, "EBDT", 4) == 0 ||
- memcmp(dir_entry->tag, "EBLC", 4) == 0 ||
- memcmp(dir_entry->tag, "EBSC", 4) == 0) {
- WARNING_1 fprintf(stderr, "Font contains bitmaps\n");
- }
- dir_entry++;
- }
-
- for(j=0; tables[j].tbpp != NULL; j++)
- if(!tables[j].optional && badpointer( *(tables[j].tbpp) )) {
- fprintf(stderr, "**** File contains no required table '%s'\n", tables[j].name);
- exit(1);
- }
-
- handle_name();
-
- handle_head();
-
- ttf_nglyphs = ntohs(maxp_table->numGlyphs);
-
- enc_found_ms = enc_found_mac = 0;
-}
-
-/*
- * Close font.
- * Exit on error.
- */
-
-static void
-closefont(
- void
-)
-{
- return; /* empty operation */
-}
-
-/*
- * Get the number of glyphs in font.
- */
-
-static int
-getnglyphs (
- void
-)
-{
- return ttf_nglyphs;
-}
-
-/*
- * Get the names of the glyphs.
- * Returns 0 if the names were assigned, non-zero if the font
- * provides no glyph names.
- */
-
-static int
-glnames(
- GLYPH *glyph_list
-)
-{
- int i, len, n, npost;
- unsigned int format;
- USHORT *name_index;
- char *ptr, *p;
- char **ps_name_ptr = (char **) malloc(ttf_nglyphs * sizeof(char *));
- int n_ps_names;
- int ps_fmt_3 = 0;
-
- format = ntohl(post_table->formatType);
-
- if (format == 0x00010000) {
- for (i = 0; i < 258 && i < ttf_nglyphs; i++) {
- glyph_list[i].name = mac_glyph_names[i];
- }
- } else if (format == 0x00020000) {
- npost = ntohs(post_table->numGlyphs);
- if (ttf_nglyphs != npost) {
- /* This is an error in the font, but we can now cope */
- WARNING_1 fprintf(stderr, "**** Postscript table size mismatch %d/%d ****\n",
- npost, ttf_nglyphs);
- }
- n_ps_names = 0;
- name_index = &(post_table->glyphNameIndex);
-
- /* This checks the integrity of the post table */
- for (i=0; i<npost; i++) {
- n = ntohs(name_index[i]);
- if (n > n_ps_names + 257) {
- n_ps_names = n - 257;
- }
- }
-
- ptr = (char *) post_table + 34 + (ttf_nglyphs << 1);
- i = 0;
- while (*ptr > 0 && i < n_ps_names) {
- len = *ptr;
- /* previously the program wrote nulls into the table. If the table
- was corrupt, this could put zeroes anywhere, leading to obscure bugs,
- so now I malloc space for the names. Yes it is much less efficient */
-
- if ((p = malloc(len+1)) == NULL) {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
-
- ps_name_ptr[i] = p;
- strncpy(p, ptr+1, len);
- p[len] = '\0';
- i ++;
- ptr += len + 1;
- }
-
- if (i != n_ps_names)
- {
- WARNING_2 fprintf (stderr, "** Postscript Name mismatch %d != %d **\n",
- i, n_ps_names);
- n_ps_names = i;
- }
-
- /*
- * for (i=0; i<n_ps_names; i++) { fprintf(stderr, "i=%d,
- * len=%d, name=%s\n", i, ps_name_len[i], ps_name_ptr[i]); }
- */
-
- for (i = 0; i < npost; i++) {
- n = ntohs(name_index[i]);
- if (n < 258) {
- glyph_list[i].name = mac_glyph_names[n];
- } else if (n < 258 + n_ps_names) {
- glyph_list[i].name = ps_name_ptr[n - 258];
- } else {
- glyph_list[i].name = malloc(16);
- sprintf(glyph_list[i].name, "_g_%d", i);
- WARNING_2 fprintf(stderr,
- "Glyph No. %d has no postscript name, becomes %s\n",
- i, glyph_list[i].name);
- }
- }
- /* Now fake postscript names for all those beyond the end of the table */
- if (npost < ttf_nglyphs) {
- for (i=npost; i<ttf_nglyphs; i++) {
- if ((glyph_list[i].name = malloc(16)) == NULL)
- {
- fprintf (stderr, "****malloc failed %s line %d\n", __FILE__, __LINE__);
- exit(255);
- }
- sprintf(glyph_list[i].name, "_g_%d", i);
- WARNING_2 fprintf(stderr,
- "Glyph No. %d has no postscript name, becomes %s\n",
- i, glyph_list[i].name);
- }
- }
- } else if (format == 0x00030000) {
- WARNING_3 fputs("No postscript table, using default\n", stderr);
- ps_fmt_3 = 1;
- } else if (format == 0x00028000) {
- ptr = (char *) &(post_table->numGlyphs);
- for (i = 0; i < ttf_nglyphs; i++) {
- glyph_list[i].name = mac_glyph_names[i + ptr[i]];
- }
- } else {
- fprintf(stderr,
- "**** Postscript table in wrong format %x ****\n",
- format);
- exit(1);
- }
-
- return ps_fmt_3;
-}
-
-/*
- * Get the metrics of the glyphs.
- */
-
-static void
-glmetrics(
- GLYPH *glyph_list
-)
-{
- int i;
- int n_hmetrics = ntohs(hhea_table->numberOfHMetrics);
- GLYPH *g;
- LONGHORMETRIC *hmtx_entry = hmtx_table;
- FWORD *lsblist;
-
- for (i = 0; i < n_hmetrics; i++) {
- g = &(glyph_list[i]);
- g->width = ntohs(hmtx_entry->advanceWidth);
- g->lsb = ntohs(hmtx_entry->lsb);
- hmtx_entry++;
- }
-
- lsblist = (FWORD *) hmtx_entry;
- hmtx_entry--;
-
- for (i = n_hmetrics; i < ttf_nglyphs; i++) {
- g = &(glyph_list[i]);
- g->width = ntohs(hmtx_entry->advanceWidth);
- g->lsb = ntohs(lsblist[i - n_hmetrics]);
- }
-
- for (i = 0; i < ttf_nglyphs; i++) {
- g = &(glyph_list[i]);
- get_glyf_table(i, &glyf_table, &g->ttf_pathlen);
-
- g->xMin = (short)ntohs(glyf_table->xMin);
- g->xMax = (short)ntohs(glyf_table->xMax);
- g->yMin = (short)ntohs(glyf_table->yMin);
- g->yMax = (short)ntohs(glyf_table->yMax);
- }
-
-}
-
-
-static void
-handle_ms_encoding(
- GLYPH *glyph_list,
- int *encoding,
- int *unimap
-)
-{
- int j, k, kk, set_ok;
- USHORT start, end, ro;
- short delta, n;
-
- for (j = 0; j < cmap_n_segs - 1; j++) {
- start = ntohs(cmap_seg_start[j]);
- end = ntohs(cmap_seg_end[j]);
- delta = ntohs(cmap_idDelta[j]);
- ro = ntohs(cmap_idRangeOffset[j]);
-
- for (k = start; k <= end; k++) {
- if (ro == 0) {
- n = k + delta;
- } else {
- n = ntohs(*((ro >> 1) + (k - start) +
- &(cmap_idRangeOffset[j])));
- if (delta != 0)
- {
- /* Not exactly sure how to deal with this circumstance,
- I suspect it never occurs */
- n += delta;
- fprintf (stderr,
- "rangeoffset and delta both non-zero - %d/%d",
- ro, delta);
- }
- }
- if(n<0 || n>=ttf_nglyphs) {
- WARNING_1 fprintf(stderr, "Font contains a broken glyph code mapping, ignored\n");
- continue;
- }
- if (glyph_list[n].orig_code != -1) {
-#if 0
- if (strcmp(glyph_list[n].name, ".notdef") != 0) {
- WARNING_2 fprintf(stderr,
- "Glyph %s has >= two encodings (A), %4.4x & %4.4x\n",
- glyph_list[n].name,
- glyph_list[n].orig_code,
- k);
- }
-#endif
- set_ok = 0;
- } else {
- set_ok = 1;
- }
- if (enc_type==1 || forcemap) {
- kk = unicode_rev_lookup(k);
- if(ISDBG(UNICODE))
- fprintf(stderr, "Unicode %s - 0x%04x\n",glyph_list[n].name,k);
- if (set_ok) {
- glyph_list[n].orig_code = k;
- /* glyph_list[n].char_no = kk; */
- }
- if (kk >= 0 && kk < ENCTABSZ && encoding[kk] == -1)
- encoding[kk] = n;
- } else {
- if ((k & 0xff00) == 0xf000) {
- if( encoding[k & 0x00ff] == -1 ) {
- encoding[k & 0x00ff] = n;
- if (set_ok) {
- /* glyph_list[n].char_no = k & 0x00ff; */
- glyph_list[n].orig_code = k;
- }
- }
- } else {
- if (set_ok) {
- /* glyph_list[n].char_no = k; */
- glyph_list[n].orig_code = k;
- }
- WARNING_2 fprintf(stderr,
- "Glyph %s has non-symbol encoding %4.4x\n",
- glyph_list[n].name,
- k & 0xffff);
- /*
- * just use the code
- * as it is
- */
- if ((k & ~0xff) == 0 && encoding[k] == -1 )
- encoding[k] = n;
- }
- }
- }
- }
-}
-
-static void
-handle_mac_encoding(
- GLYPH *glyph_list,
- int *encoding,
- int *unimap
-)
-{
- short n;
- int j, size;
-
- size = ntohs(encoding0->length) - 6;
- for (j = 0; j < size; j++) {
- n = encoding0->glyphIdArray[j];
- if (glyph_list[n].char_no != -1) {
- WARNING_2 fprintf(stderr,
- "Glyph %s has >= two encodings (B), %4.4x & %4.4x\n",
- glyph_list[n].name,
- glyph_list[n].char_no,
- j);
- } else {
- if (j < ENCTABSZ) {
- if(encoding[j] == -1) {
- glyph_list[n].char_no = j;
- encoding[j] = n;
- }
- }
- }
- }
-}
-
-/*
- * Get the original encoding of the font.
- * Returns 1 for if the original encoding is Unicode, 2 if the
- * original encoding is other 16-bit, 0 if 8-bit.
- */
-
-static int
-glenc(
- GLYPH *glyph_list,
- int *encoding,
- int *unimap
-)
-{
- int num_tables = ntohs(cmap_table->numberOfEncodingTables);
- BYTE *ptr;
- int i, format, offset, seg_c2, found;
- int platform, encoding_id;
- TTF_CMAP_ENTRY *table_entry;
- TTF_CMAP_FMT4 *encoding4;
-
- if(enc_found_ms) {
- handle_ms_encoding(glyph_list, encoding, unimap);
- return enc_type;
- } else if(enc_found_mac) {
- handle_mac_encoding(glyph_list, encoding, unimap);
- return 0;
- }
-
- if(force_pid != -1 && force_pid != 3) {
- fputs("*** Only platform ID == 3 is supported\n", stderr);
- exit(1);
- }
-
- enc_type = 0;
- found = 0;
-
- for (i = 0; i < num_tables && !found; i++) {
- table_entry = &(cmap_table->encodingTable[i]);
- offset = ntohl(table_entry->offset);
- encoding4 = (TTF_CMAP_FMT4 *) ((BYTE *) cmap_table + offset);
- format = ntohs(encoding4->format);
- platform = ntohs(table_entry->platformID);
- encoding_id = ntohs(table_entry->encodingID);
-
- if (platform == 3 && format == 4) {
- if(force_pid == 3) {
- if(encoding_id != force_eid)
- continue;
- WARNING_1 fprintf(stderr, "Found Encoding PID=%d/EID=%d\n",
- force_pid, force_eid);
- enc_type = 1;
- } else {
- switch (encoding_id) {
- case 0:
- WARNING_1 fputs("Found Symbol Encoding\n", stderr);
- break;
- case 1:
- WARNING_1 fputs("Found Unicode Encoding\n", stderr);
- enc_type = 1;
- break;
- default:
- WARNING_1 {
- fprintf(stderr,
- "****MS Encoding ID %d not supported****\n",
- encoding_id);
- fputs("Treating it like Symbol encoding\n", stderr);
- }
- break;
- }
- }
-
- found = 1;
- seg_c2 = ntohs(encoding4->segCountX2);
- cmap_n_segs = seg_c2 >> 1;
- ptr = (BYTE *) encoding4 + 14;
- cmap_seg_end = (USHORT *) ptr;
- cmap_seg_start = (USHORT *) (ptr + seg_c2 + 2);
- cmap_idDelta = (short *) (ptr + (seg_c2 * 2) + 2);
- cmap_idRangeOffset = (short *) (ptr + (seg_c2 * 3) + 2);
- enc_found_ms = 1;
-
- handle_ms_encoding(glyph_list, encoding, unimap);
- }
- }
-
- if (!found) {
- if(force_pid != -1) {
- fprintf(stderr, "*** TTF encoding table PID=%d/EID=%d not found\n",
- force_pid, force_eid);
- exit(1);
- }
-
- WARNING_1 fputs("No Microsoft encoding, looking for MAC encoding\n", stderr);
- for (i = 0; i < num_tables && !found; i++) {
- table_entry = &(cmap_table->encodingTable[i]);
- offset = ntohl(table_entry->offset);
- encoding0 = (TTF_CMAP_FMT0 *) ((BYTE *) cmap_table + offset);
- format = ntohs(encoding0->format);
- platform = ntohs(table_entry->platformID);
- encoding_id = ntohs(table_entry->encodingID);
-
- if (format == 0) {
- found = 1;
- enc_found_mac = 1;
-
- handle_mac_encoding(glyph_list, encoding, unimap);
- }
- }
- }
- if (!found) {
- fprintf(stderr, "**** No Recognised Encoding Table ****\n");
- exit(1);
- }
-
- return enc_type;
-}
-
-/*
- * Get the font metrics
- */
-static void
-fnmetrics(
- struct font_metrics *fm
-)
-{
- char *str;
- static int fieldstocheck[]= {2,4,6};
- int i, j, len;
-
- fm->italic_angle = (short) (ntohs(post_table->italicAngle.upper)) +
- ((short) ntohs(post_table->italicAngle.lower) / 65536.0);
- fm->underline_position = (short) ntohs(post_table->underlinePosition);
- fm->underline_thickness = (short) ntohs(post_table->underlineThickness);
- fm->is_fixed_pitch = ntohl(post_table->isFixedPitch);
-
- fm->ascender = (short)ntohs(hhea_table->ascender);
- fm->descender = (short)ntohs(hhea_table->descender);
-
- fm->units_per_em = ntohs(head_table->unitsPerEm);
-
- fm->bbox[0] = (short) ntohs(head_table->xMin);
- fm->bbox[1] = (short) ntohs(head_table->yMin);
- fm->bbox[2] = (short) ntohs(head_table->xMax);
- fm->bbox[3] = (short) ntohs(head_table->yMax);
-
- fm->name_copyright = name_fields[0];
- fm->name_family = name_fields[1];
- fm->name_style = name_fields[2];
- fm->name_full = name_fields[4];
- fm->name_version = name_fields[5];
- fm->name_ps = name_fields[6];
-
- /* guess the boldness from the font names */
- fm->force_bold=0;
-
- for(i=0; !fm->force_bold && i<sizeof fieldstocheck /sizeof(int); i++) {
- str = name_fields[fieldstocheck[i]];
- len = strlen(str);
- for(j=0; j<len; j++) {
- if( (str[j]=='B'
- || str[j]=='b'
- && ( j==0 || !isalpha(str[j-1]) )
- )
- && !strncmp("old",&str[j+1],3)
- && (j+4 >= len || !islower(str[j+4]))
- ) {
- fm->force_bold=1;
- break;
- }
- }
- }
-}
-
-/*
- * Get the path of contrours for a glyph.
- */
-
-static void
-glpath(
- int glyphno,
- GLYPH *glyf_list
-)
-{
- double matrix[6];
- GLYPH *g;
-
- g = &glyph_list[glyphno];
-
- matrix[0] = matrix[3] = 1.0;
- matrix[1] = matrix[2] = matrix[4] = matrix[5] = 0.0;
- draw_composite_glyf(g, glyf_list, glyphno, matrix, 0 /*level*/);
-}
-
-/*
- * Get the kerning data.
- */
-
-static void
-kerning(
- GLYPH *glyph_list
-)
-{
- TTF_KERN_SUB *subtable;
- TTF_KERN_ENTRY *kern_entry;
- int i, j;
- int ntables;
- int npairs;
- char *ptr;
-
- if(kern_table == NULL) {
- WARNING_1 fputs("No Kerning data\n", stderr);
- return;
- }
- if(badpointer(kern_table)) {
- fputs("**** Defective Kerning table, ignored\n", stderr);
- return;
- }
-
- ntables = ntohs(kern_table->nTables);
- ptr = (char *) kern_table + 4;
-
- for (i = 0; i < ntables; i++) {
- subtable = (TTF_KERN_SUB *) ptr;
- if ((ntohs(subtable->coverage) & 0xff00) == 0) {
- npairs = (short) ntohs(subtable->nPairs);
- kern_entry = (TTF_KERN_ENTRY *) (ptr + sizeof(TTF_KERN_SUB));
-
- kern_entry = (TTF_KERN_ENTRY *) (ptr + sizeof(TTF_KERN_SUB));
- for (j = 0; j < npairs; j++) {
- if( kern_entry->value != 0)
- addkernpair(ntohs(kern_entry->left),
- ntohs(kern_entry->right), (short)ntohs(kern_entry->value));
- kern_entry++;
- }
- }
- ptr += subtable->length;
- }
-}
-