summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/mpdir
diff options
context:
space:
mode:
authorTaco Hoekwater <taco@elvenkind.com>2006-11-20 14:43:48 +0000
committerTaco Hoekwater <taco@elvenkind.com>2006-11-20 14:43:48 +0000
commit5952e40b396499c0cd62bdbcf1853538873b76c1 (patch)
tree968b37e966ba1825e2de091a071774af1a7ffa9b /Build/source/texk/web2c/mpdir
parent9fcf4d90b8b3a11712287d4ddf3fd47614a7ea68 (diff)
Metapost 0.99 sources, except dmp
git-svn-id: svn://tug.org/texlive/trunk@2470 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/mpdir')
-rw-r--r--Build/source/texk/web2c/mpdir/Makefile.in40
-rw-r--r--Build/source/texk/web2c/mpdir/avl.c792
-rw-r--r--Build/source/texk/web2c/mpdir/avl.h118
-rw-r--r--Build/source/texk/web2c/mpdir/avlstuff.c50
-rw-r--r--Build/source/texk/web2c/mpdir/avlstuff.h29
-rw-r--r--Build/source/texk/web2c/mpdir/makecpool.c58
-rw-r--r--Build/source/texk/web2c/mpdir/mapfile.c993
-rw-r--r--Build/source/texk/web2c/mpdir/mp.defines54
-rw-r--r--Build/source/texk/web2c/mpdir/mplib.h300
-rw-r--r--Build/source/texk/web2c/mpdir/mpmac.h218
-rw-r--r--Build/source/texk/web2c/mpdir/mpostlib.mk29
-rw-r--r--Build/source/texk/web2c/mpdir/utils.c719
-rw-r--r--Build/source/texk/web2c/mpdir/writeenc.c142
-rw-r--r--Build/source/texk/web2c/mpdir/writefont.c244
-rw-r--r--Build/source/texk/web2c/mpdir/writet1.c1736
15 files changed, 5522 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/mpdir/Makefile.in b/Build/source/texk/web2c/mpdir/Makefile.in
new file mode 100644
index 00000000000..c6abb102f2d
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/Makefile.in
@@ -0,0 +1,40 @@
+# Makefile for libmpost - taco@elvenkind.com, but
+# mostly ripped off from Makefile.in from pdftex
+# $Id $
+
+kpse_include ../make/common.mk
+kpse_include ../make/programs.mk
+kpse_include ../make/library.mk
+
+kpathsea_srcdir_parent = $(srcdir)/../..
+kpathsea_dir_parent = ../..
+
+ALL_CXXFLAGS = @CXXFLAGS@ @DEFS@ $(XXCFLAGS) -I. -I$(srcdir) -I$(kpathsea_dir_parent) -I$(kpathsea_srcdir_parent)
+CXX = @CXX@
+
+XCPPFLAGS=-I.. -I$(srcdir)/.. -I../.. -I$(srcdir)/../..
+
+OBJS = mapfile.o avl.o avlstuff.o utils.o writeenc.o writet1.o writefont.o
+
+all: libmpost.a makecpool
+
+libmpost.a: $(OBJS)
+ rm -f $@
+ $(AR) $(ARFLAGS) $@ $(OBJS)
+ $(RANLIB) $@
+
+makecpool: makecpool.o
+ $(link_command) makecpool.o
+
+kpse_include ../make/clean.mk
+
+clean::
+ rm -f libmpost.a makecpool
+
+depend:
+ rm -f $(OBJS)
+ XXCFLAGS=-MM XCFLAGS=-MM $(MAKE) -k $(OBJS) | \
+ grep -v "^$(CC)\|$(CXX)\|$(AR)\|make\|klibtool" | \
+ sed 's: [^ ]*/\.\./libs/[^ ]*::g' > $(srcdir)/depend.mk
+
+kpse_include mpdir/depend.mk
diff --git a/Build/source/texk/web2c/mpdir/avl.c b/Build/source/texk/web2c/mpdir/avl.c
new file mode 100644
index 00000000000..703c4b2e72d
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/avl.c
@@ -0,0 +1,792 @@
+/* Produced by texiweb from libavl.w on 2003/01/06 at 18:07. */
+
+/* libavl - library for manipulation of binary trees.
+ Copyright (C) 1998-2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The author may be contacted at <blp@gnu.org> on the Internet, or
+ write to Ben Pfaff, Stanford University, Computer Science Dept., 353
+ Serra Mall, Stanford CA 94305, USA.
+*/
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "avl.h"
+
+/* Creates and returns a new table
+ with comparison function |compare| using parameter |param|
+ and memory allocator |allocator|.
+ Returns |NULL| if memory allocation failed. */
+struct avl_table *avl_create (avl_comparison_func * compare, void *param,
+ struct libavl_allocator *allocator)
+{
+ struct avl_table *tree;
+
+ assert (compare != NULL);
+
+ if (allocator == NULL)
+ allocator = &avl_allocator_default;
+
+ tree = allocator->libavl_malloc (allocator, sizeof *tree);
+ if (tree == NULL)
+ return NULL;
+
+ tree->avl_root = NULL;
+ tree->avl_compare = compare;
+ tree->avl_param = param;
+ tree->avl_alloc = allocator;
+ tree->avl_count = 0;
+ tree->avl_generation = 0;
+
+ return tree;
+}
+
+/* Search |tree| for an item matching |item|, and return it if found.
+ Otherwise return |NULL|. */
+void *avl_find (const struct avl_table *tree, const void *item)
+{
+ const struct avl_node *p;
+
+ assert (tree != NULL && item != NULL);
+ for (p = tree->avl_root; p != NULL;) {
+ int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
+
+ if (cmp < 0)
+ p = p->avl_link[0];
+ else if (cmp > 0)
+ p = p->avl_link[1];
+ else /* |cmp == 0| */
+ return p->avl_data;
+ }
+
+ return NULL;
+}
+
+/* Inserts |item| into |tree| and returns a pointer to |item|'s address.
+ If a duplicate item is found in the tree,
+ returns a pointer to the duplicate without inserting |item|.
+ Returns |NULL| in case of memory allocation failure. */
+void **avl_probe (struct avl_table *tree, void *item)
+{
+ struct avl_node *y, *z; /* Top node to update balance factor, and parent. */
+ struct avl_node *p, *q; /* Iterator, and parent. */
+ struct avl_node *n; /* Newly inserted node. */
+ struct avl_node *w; /* New root of rebalanced subtree. */
+ int dir; /* Direction to descend. */
+
+ unsigned char da[AVL_MAX_HEIGHT]; /* Cached comparison results. */
+ int k = 0; /* Number of cached results. */
+
+ assert (tree != NULL && item != NULL);
+
+ z = (struct avl_node *) &tree->avl_root;
+ y = tree->avl_root;
+ dir = 0;
+ for (q = z, p = y; p != NULL; q = p, p = p->avl_link[dir]) {
+ int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
+ if (cmp == 0)
+ return &p->avl_data;
+
+ if (p->avl_balance != 0)
+ z = q, y = p, k = 0;
+ da[k++] = dir = cmp > 0;
+ }
+
+ n = q->avl_link[dir] =
+ tree->avl_alloc->libavl_malloc (tree->avl_alloc, sizeof *n);
+ if (n == NULL)
+ return NULL;
+
+ tree->avl_count++;
+ n->avl_data = item;
+ n->avl_link[0] = n->avl_link[1] = NULL;
+ n->avl_balance = 0;
+ if (y == NULL)
+ return &n->avl_data;
+
+ for (p = y, k = 0; p != n; p = p->avl_link[da[k]], k++)
+ if (da[k] == 0)
+ p->avl_balance--;
+ else
+ p->avl_balance++;
+
+ if (y->avl_balance == -2) {
+ struct avl_node *x = y->avl_link[0];
+ if (x->avl_balance == -1) {
+ w = x;
+ y->avl_link[0] = x->avl_link[1];
+ x->avl_link[1] = y;
+ x->avl_balance = y->avl_balance = 0;
+ } else {
+ assert (x->avl_balance == +1);
+ w = x->avl_link[1];
+ x->avl_link[1] = w->avl_link[0];
+ w->avl_link[0] = x;
+ y->avl_link[0] = w->avl_link[1];
+ w->avl_link[1] = y;
+ if (w->avl_balance == -1)
+ x->avl_balance = 0, y->avl_balance = +1;
+ else if (w->avl_balance == 0)
+ x->avl_balance = y->avl_balance = 0;
+ else /* |w->avl_balance == +1| */
+ x->avl_balance = -1, y->avl_balance = 0;
+ w->avl_balance = 0;
+ }
+ } else if (y->avl_balance == +2) {
+ struct avl_node *x = y->avl_link[1];
+ if (x->avl_balance == +1) {
+ w = x;
+ y->avl_link[1] = x->avl_link[0];
+ x->avl_link[0] = y;
+ x->avl_balance = y->avl_balance = 0;
+ } else {
+ assert (x->avl_balance == -1);
+ w = x->avl_link[0];
+ x->avl_link[0] = w->avl_link[1];
+ w->avl_link[1] = x;
+ y->avl_link[1] = w->avl_link[0];
+ w->avl_link[0] = y;
+ if (w->avl_balance == +1)
+ x->avl_balance = 0, y->avl_balance = -1;
+ else if (w->avl_balance == 0)
+ x->avl_balance = y->avl_balance = 0;
+ else /* |w->avl_balance == -1| */
+ x->avl_balance = +1, y->avl_balance = 0;
+ w->avl_balance = 0;
+ }
+ } else
+ return &n->avl_data;
+ z->avl_link[y != z->avl_link[0]] = w;
+
+ tree->avl_generation++;
+ return &n->avl_data;
+}
+
+/* Inserts |item| into |table|.
+ Returns |NULL| if |item| was successfully inserted
+ or if a memory allocation error occurred.
+ Otherwise, returns the duplicate item. */
+void *avl_insert (struct avl_table *table, void *item)
+{
+ void **p = avl_probe (table, item);
+ return p == NULL || *p == item ? NULL : *p;
+}
+
+/* Inserts |item| into |table|, replacing any duplicate item.
+ Returns |NULL| if |item| was inserted without replacing a duplicate,
+ or if a memory allocation error occurred.
+ Otherwise, returns the item that was replaced. */
+void *avl_replace (struct avl_table *table, void *item)
+{
+ void **p = avl_probe (table, item);
+ if (p == NULL || *p == item)
+ return NULL;
+ else {
+ void *r = *p;
+ *p = item;
+ return r;
+ }
+}
+
+/* Deletes from |tree| and returns an item matching |item|.
+ Returns a null pointer if no matching item found. */
+void *avl_delete (struct avl_table *tree, const void *item)
+{
+ /* Stack of nodes. */
+ struct avl_node *pa[AVL_MAX_HEIGHT]; /* Nodes. */
+ unsigned char da[AVL_MAX_HEIGHT]; /* |avl_link[]| indexes. */
+ int k; /* Stack pointer. */
+
+ struct avl_node *p; /* Traverses tree to find node to delete. */
+ int cmp; /* Result of comparison between |item| and |p|. */
+
+ assert (tree != NULL && item != NULL);
+
+ k = 0;
+ p = (struct avl_node *) &tree->avl_root;
+ for (cmp = -1; cmp != 0;
+ cmp = tree->avl_compare (item, p->avl_data, tree->avl_param)) {
+ int dir = cmp > 0;
+
+ pa[k] = p;
+ da[k++] = dir;
+
+ p = p->avl_link[dir];
+ if (p == NULL)
+ return NULL;
+ }
+ item = p->avl_data;
+
+ if (p->avl_link[1] == NULL)
+ pa[k - 1]->avl_link[da[k - 1]] = p->avl_link[0];
+ else {
+ struct avl_node *r = p->avl_link[1];
+ if (r->avl_link[0] == NULL) {
+ r->avl_link[0] = p->avl_link[0];
+ r->avl_balance = p->avl_balance;
+ pa[k - 1]->avl_link[da[k - 1]] = r;
+ da[k] = 1;
+ pa[k++] = r;
+ } else {
+ struct avl_node *s;
+ int j = k++;
+
+ for (;;) {
+ da[k] = 0;
+ pa[k++] = r;
+ s = r->avl_link[0];
+ if (s->avl_link[0] == NULL)
+ break;
+
+ r = s;
+ }
+
+ s->avl_link[0] = p->avl_link[0];
+ r->avl_link[0] = s->avl_link[1];
+ s->avl_link[1] = p->avl_link[1];
+ s->avl_balance = p->avl_balance;
+
+ pa[j - 1]->avl_link[da[j - 1]] = s;
+ da[j] = 1;
+ pa[j] = s;
+ }
+ }
+
+ tree->avl_alloc->libavl_free (tree->avl_alloc, p);
+
+ assert (k > 0);
+ while (--k > 0) {
+ struct avl_node *y = pa[k];
+
+ if (da[k] == 0) {
+ y->avl_balance++;
+ if (y->avl_balance == +1)
+ break;
+ else if (y->avl_balance == +2) {
+ struct avl_node *x = y->avl_link[1];
+ if (x->avl_balance == -1) {
+ struct avl_node *w;
+ assert (x->avl_balance == -1);
+ w = x->avl_link[0];
+ x->avl_link[0] = w->avl_link[1];
+ w->avl_link[1] = x;
+ y->avl_link[1] = w->avl_link[0];
+ w->avl_link[0] = y;
+ if (w->avl_balance == +1)
+ x->avl_balance = 0, y->avl_balance = -1;
+ else if (w->avl_balance == 0)
+ x->avl_balance = y->avl_balance = 0;
+ else /* |w->avl_balance == -1| */
+ x->avl_balance = +1, y->avl_balance = 0;
+ w->avl_balance = 0;
+ pa[k - 1]->avl_link[da[k - 1]] = w;
+ } else {
+ y->avl_link[1] = x->avl_link[0];
+ x->avl_link[0] = y;
+ pa[k - 1]->avl_link[da[k - 1]] = x;
+ if (x->avl_balance == 0) {
+ x->avl_balance = -1;
+ y->avl_balance = +1;
+ break;
+ } else
+ x->avl_balance = y->avl_balance = 0;
+ }
+ }
+ } else {
+ y->avl_balance--;
+ if (y->avl_balance == -1)
+ break;
+ else if (y->avl_balance == -2) {
+ struct avl_node *x = y->avl_link[0];
+ if (x->avl_balance == +1) {
+ struct avl_node *w;
+ assert (x->avl_balance == +1);
+ w = x->avl_link[1];
+ x->avl_link[1] = w->avl_link[0];
+ w->avl_link[0] = x;
+ y->avl_link[0] = w->avl_link[1];
+ w->avl_link[1] = y;
+ if (w->avl_balance == -1)
+ x->avl_balance = 0, y->avl_balance = +1;
+ else if (w->avl_balance == 0)
+ x->avl_balance = y->avl_balance = 0;
+ else /* |w->avl_balance == +1| */
+ x->avl_balance = -1, y->avl_balance = 0;
+ w->avl_balance = 0;
+ pa[k - 1]->avl_link[da[k - 1]] = w;
+ } else {
+ y->avl_link[0] = x->avl_link[1];
+ x->avl_link[1] = y;
+ pa[k - 1]->avl_link[da[k - 1]] = x;
+ if (x->avl_balance == 0) {
+ x->avl_balance = +1;
+ y->avl_balance = -1;
+ break;
+ } else
+ x->avl_balance = y->avl_balance = 0;
+ }
+ }
+ }
+ }
+
+ tree->avl_count--;
+ tree->avl_generation++;
+ return (void *) item;
+}
+
+/* Refreshes the stack of parent pointers in |trav|
+ and updates its generation number. */
+static void trav_refresh (struct avl_traverser *trav)
+{
+ assert (trav != NULL);
+
+ trav->avl_generation = trav->avl_table->avl_generation;
+
+ if (trav->avl_node != NULL) {
+ avl_comparison_func *cmp = trav->avl_table->avl_compare;
+ void *param = trav->avl_table->avl_param;
+ struct avl_node *node = trav->avl_node;
+ struct avl_node *i;
+
+ trav->avl_height = 0;
+ for (i = trav->avl_table->avl_root; i != node;) {
+ assert (trav->avl_height < AVL_MAX_HEIGHT);
+ assert (i != NULL);
+
+ trav->avl_stack[trav->avl_height++] = i;
+ i = i->avl_link[cmp (node->avl_data, i->avl_data, param) > 0];
+ }
+ }
+}
+
+/* Initializes |trav| for use with |tree|
+ and selects the null node. */
+void avl_t_init (struct avl_traverser *trav, struct avl_table *tree)
+{
+ trav->avl_table = tree;
+ trav->avl_node = NULL;
+ trav->avl_height = 0;
+ trav->avl_generation = tree->avl_generation;
+}
+
+/* Initializes |trav| for |tree|
+ and selects and returns a pointer to its least-valued item.
+ Returns |NULL| if |tree| contains no nodes. */
+void *avl_t_first (struct avl_traverser *trav, struct avl_table *tree)
+{
+ struct avl_node *x;
+
+ assert (tree != NULL && trav != NULL);
+
+ trav->avl_table = tree;
+ trav->avl_height = 0;
+ trav->avl_generation = tree->avl_generation;
+
+ x = tree->avl_root;
+ if (x != NULL)
+ while (x->avl_link[0] != NULL) {
+ assert (trav->avl_height < AVL_MAX_HEIGHT);
+ trav->avl_stack[trav->avl_height++] = x;
+ x = x->avl_link[0];
+ }
+ trav->avl_node = x;
+
+ return x != NULL ? x->avl_data : NULL;
+}
+
+/* Initializes |trav| for |tree|
+ and selects and returns a pointer to its greatest-valued item.
+ Returns |NULL| if |tree| contains no nodes. */
+void *avl_t_last (struct avl_traverser *trav, struct avl_table *tree)
+{
+ struct avl_node *x;
+
+ assert (tree != NULL && trav != NULL);
+
+ trav->avl_table = tree;
+ trav->avl_height = 0;
+ trav->avl_generation = tree->avl_generation;
+
+ x = tree->avl_root;
+ if (x != NULL)
+ while (x->avl_link[1] != NULL) {
+ assert (trav->avl_height < AVL_MAX_HEIGHT);
+ trav->avl_stack[trav->avl_height++] = x;
+ x = x->avl_link[1];
+ }
+ trav->avl_node = x;
+
+ return x != NULL ? x->avl_data : NULL;
+}
+
+/* Searches for |item| in |tree|.
+ If found, initializes |trav| to the item found and returns the item
+ as well.
+ If there is no matching item, initializes |trav| to the null item
+ and returns |NULL|. */
+void *avl_t_find (struct avl_traverser *trav, struct avl_table *tree,
+ void *item)
+{
+ struct avl_node *p, *q;
+
+ assert (trav != NULL && tree != NULL && item != NULL);
+ trav->avl_table = tree;
+ trav->avl_height = 0;
+ trav->avl_generation = tree->avl_generation;
+ for (p = tree->avl_root; p != NULL; p = q) {
+ int cmp = tree->avl_compare (item, p->avl_data, tree->avl_param);
+
+ if (cmp < 0)
+ q = p->avl_link[0];
+ else if (cmp > 0)
+ q = p->avl_link[1];
+ else { /* |cmp == 0| */
+
+ trav->avl_node = p;
+ return p->avl_data;
+ }
+
+ assert (trav->avl_height < AVL_MAX_HEIGHT);
+ trav->avl_stack[trav->avl_height++] = p;
+ }
+
+ trav->avl_height = 0;
+ trav->avl_node = NULL;
+ return NULL;
+}
+
+/* Attempts to insert |item| into |tree|.
+ If |item| is inserted successfully, it is returned and |trav| is
+ initialized to its location.
+ If a duplicate is found, it is returned and |trav| is initialized to
+ its location. No replacement of the item occurs.
+ If a memory allocation failure occurs, |NULL| is returned and |trav|
+ is initialized to the null item. */
+void *avl_t_insert (struct avl_traverser *trav, struct avl_table *tree,
+ void *item)
+{
+ void **p;
+
+ assert (trav != NULL && tree != NULL && item != NULL);
+
+ p = avl_probe (tree, item);
+ if (p != NULL) {
+ trav->avl_table = tree;
+ trav->avl_node = ((struct avl_node *)
+ ((char *) p - offsetof (struct avl_node, avl_data)));
+ trav->avl_generation = tree->avl_generation - 1;
+ return *p;
+ } else {
+ avl_t_init (trav, tree);
+ return NULL;
+ }
+}
+
+/* Initializes |trav| to have the same current node as |src|. */
+void *avl_t_copy (struct avl_traverser *trav, const struct avl_traverser *src)
+{
+ assert (trav != NULL && src != NULL);
+
+ if (trav != src) {
+ trav->avl_table = src->avl_table;
+ trav->avl_node = src->avl_node;
+ trav->avl_generation = src->avl_generation;
+ if (trav->avl_generation == trav->avl_table->avl_generation) {
+ trav->avl_height = src->avl_height;
+ memcpy (trav->avl_stack, (const void *) src->avl_stack,
+ sizeof *trav->avl_stack * trav->avl_height);
+ }
+ }
+
+ return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL;
+}
+
+/* Returns the next data item in inorder
+ within the tree being traversed with |trav|,
+ or if there are no more data items returns |NULL|. */
+void *avl_t_next (struct avl_traverser *trav)
+{
+ struct avl_node *x;
+
+ assert (trav != NULL);
+
+ if (trav->avl_generation != trav->avl_table->avl_generation)
+ trav_refresh (trav);
+
+ x = trav->avl_node;
+ if (x == NULL) {
+ return avl_t_first (trav, trav->avl_table);
+ } else if (x->avl_link[1] != NULL) {
+ assert (trav->avl_height < AVL_MAX_HEIGHT);
+ trav->avl_stack[trav->avl_height++] = x;
+ x = x->avl_link[1];
+
+ while (x->avl_link[0] != NULL) {
+ assert (trav->avl_height < AVL_MAX_HEIGHT);
+ trav->avl_stack[trav->avl_height++] = x;
+ x = x->avl_link[0];
+ }
+ } else {
+ struct avl_node *y;
+
+ do {
+ if (trav->avl_height == 0) {
+ trav->avl_node = NULL;
+ return NULL;
+ }
+
+ y = x;
+ x = trav->avl_stack[--trav->avl_height];
+ }
+ while (y == x->avl_link[1]);
+ }
+ trav->avl_node = x;
+
+ return x->avl_data;
+}
+
+/* Returns the previous data item in inorder
+ within the tree being traversed with |trav|,
+ or if there are no more data items returns |NULL|. */
+void *avl_t_prev (struct avl_traverser *trav)
+{
+ struct avl_node *x;
+
+ assert (trav != NULL);
+
+ if (trav->avl_generation != trav->avl_table->avl_generation)
+ trav_refresh (trav);
+
+ x = trav->avl_node;
+ if (x == NULL) {
+ return avl_t_last (trav, trav->avl_table);
+ } else if (x->avl_link[0] != NULL) {
+ assert (trav->avl_height < AVL_MAX_HEIGHT);
+ trav->avl_stack[trav->avl_height++] = x;
+ x = x->avl_link[0];
+
+ while (x->avl_link[1] != NULL) {
+ assert (trav->avl_height < AVL_MAX_HEIGHT);
+ trav->avl_stack[trav->avl_height++] = x;
+ x = x->avl_link[1];
+ }
+ } else {
+ struct avl_node *y;
+
+ do {
+ if (trav->avl_height == 0) {
+ trav->avl_node = NULL;
+ return NULL;
+ }
+
+ y = x;
+ x = trav->avl_stack[--trav->avl_height];
+ }
+ while (y == x->avl_link[0]);
+ }
+ trav->avl_node = x;
+
+ return x->avl_data;
+}
+
+/* Returns |trav|'s current item. */
+void *avl_t_cur (struct avl_traverser *trav)
+{
+ assert (trav != NULL);
+
+ return trav->avl_node != NULL ? trav->avl_node->avl_data : NULL;
+}
+
+/* Replaces the current item in |trav| by |new| and returns the item replaced.
+ |trav| must not have the null item selected.
+ The new item must not upset the ordering of the tree. */
+void *avl_t_replace (struct avl_traverser *trav, void *new)
+{
+ void *old;
+
+ assert (trav != NULL && trav->avl_node != NULL && new != NULL);
+ old = trav->avl_node->avl_data;
+ trav->avl_node->avl_data = new;
+ return old;
+}
+
+static void
+copy_error_recovery (struct avl_node **stack, int height,
+ struct avl_table *new, avl_item_func * destroy)
+{
+ assert (stack != NULL && height >= 0 && new != NULL);
+
+ for (; height > 2; height -= 2)
+ stack[height - 1]->avl_link[1] = NULL;
+ avl_destroy (new, destroy);
+}
+
+/* Copies |org| to a newly created tree, which is returned.
+ If |copy != NULL|, each data item in |org| is first passed to |copy|,
+ and the return values are inserted into the tree,
+ with |NULL| return values taken as indications of failure.
+ On failure, destroys the partially created new tree,
+ applying |destroy|, if non-null, to each item in the new tree so far,
+ and returns |NULL|.
+ If |allocator != NULL|, it is used for allocation in the new tree.
+ Otherwise, the same allocator used for |org| is used. */
+struct avl_table *avl_copy (const struct avl_table *org, avl_copy_func * copy,
+ avl_item_func * destroy,
+ struct libavl_allocator *allocator)
+{
+ struct avl_node *stack[2 * (AVL_MAX_HEIGHT + 1)];
+ int height = 0;
+
+ struct avl_table *new;
+ const struct avl_node *x;
+ struct avl_node *y;
+
+ assert (org != NULL);
+ new = avl_create (org->avl_compare, org->avl_param,
+ allocator != NULL ? allocator : org->avl_alloc);
+ if (new == NULL)
+ return NULL;
+ new->avl_count = org->avl_count;
+ if (new->avl_count == 0)
+ return new;
+
+ x = (const struct avl_node *) &org->avl_root;
+ y = (struct avl_node *) &new->avl_root;
+ for (;;) {
+ while (x->avl_link[0] != NULL) {
+ assert (height < 2 * (AVL_MAX_HEIGHT + 1));
+
+ y->avl_link[0] =
+ new->avl_alloc->libavl_malloc (new->avl_alloc,
+ sizeof *y->avl_link[0]);
+ if (y->avl_link[0] == NULL) {
+ if (y != (struct avl_node *) &new->avl_root) {
+ y->avl_data = NULL;
+ y->avl_link[1] = NULL;
+ }
+
+ copy_error_recovery (stack, height, new, destroy);
+ return NULL;
+ }
+
+ stack[height++] = (struct avl_node *) x;
+ stack[height++] = y;
+ x = x->avl_link[0];
+ y = y->avl_link[0];
+ }
+ y->avl_link[0] = NULL;
+
+ for (;;) {
+ y->avl_balance = x->avl_balance;
+ if (copy == NULL)
+ y->avl_data = x->avl_data;
+ else {
+ y->avl_data = copy (x->avl_data, org->avl_param);
+ if (y->avl_data == NULL) {
+ y->avl_link[1] = NULL;
+ copy_error_recovery (stack, height, new, destroy);
+ return NULL;
+ }
+ }
+
+ if (x->avl_link[1] != NULL) {
+ y->avl_link[1] =
+ new->avl_alloc->libavl_malloc (new->avl_alloc,
+ sizeof *y->avl_link[1]);
+ if (y->avl_link[1] == NULL) {
+ copy_error_recovery (stack, height, new, destroy);
+ return NULL;
+ }
+
+ x = x->avl_link[1];
+ y = y->avl_link[1];
+ break;
+ } else
+ y->avl_link[1] = NULL;
+
+ if (height <= 2)
+ return new;
+
+ y = stack[--height];
+ x = stack[--height];
+ }
+ }
+}
+
+/* Frees storage allocated for |tree|.
+ If |destroy != NULL|, applies it to each data item in inorder. */
+void avl_destroy (struct avl_table *tree, avl_item_func * destroy)
+{
+ struct avl_node *p, *q;
+
+ assert (tree != NULL);
+
+ for (p = tree->avl_root; p != NULL; p = q)
+ if (p->avl_link[0] == NULL) {
+ q = p->avl_link[1];
+ if (destroy != NULL && p->avl_data != NULL)
+ destroy (p->avl_data, tree->avl_param);
+ tree->avl_alloc->libavl_free (tree->avl_alloc, p);
+ } else {
+ q = p->avl_link[0];
+ p->avl_link[0] = q->avl_link[1];
+ q->avl_link[1] = p;
+ }
+
+ tree->avl_alloc->libavl_free (tree->avl_alloc, tree);
+}
+
+/* Allocates |size| bytes of space using |malloc()|.
+ Returns a null pointer if allocation fails. */
+void *avl_malloc (struct libavl_allocator *allocator, size_t size)
+{
+ assert (allocator != NULL && size > 0);
+ return malloc (size);
+}
+
+/* Frees |block|. */
+void avl_free (struct libavl_allocator *allocator, void *block)
+{
+ assert (allocator != NULL && block != NULL);
+ free (block);
+}
+
+/* Default memory allocator that uses |malloc()| and |free()|. */
+struct libavl_allocator avl_allocator_default = {
+ avl_malloc,
+ avl_free
+};
+
+#undef NDEBUG
+#include <assert.h>
+
+/* Asserts that |avl_insert()| succeeds at inserting |item| into |table|. */
+void
+ (avl_assert_insert) (struct avl_table * table, void *item) {
+ void **p = avl_probe (table, item);
+ assert (p != NULL && *p == item);
+}
+
+/* Asserts that |avl_delete()| really removes |item| from |table|,
+ and returns the removed item. */
+void *(avl_assert_delete) (struct avl_table * table, void *item) {
+ void *p = avl_delete (table, item);
+ assert (p != NULL);
+ return p;
+}
diff --git a/Build/source/texk/web2c/mpdir/avl.h b/Build/source/texk/web2c/mpdir/avl.h
new file mode 100644
index 00000000000..acdf8bacc53
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/avl.h
@@ -0,0 +1,118 @@
+/* Produced by texiweb from libavl.w on 2003/01/06 at 18:07. */
+
+/* libavl - library for manipulation of binary trees.
+ Copyright (C) 1998-2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA.
+
+ The author may be contacted at <blp@gnu.org> on the Internet, or
+ write to Ben Pfaff, Stanford University, Computer Science Dept., 353
+ Serra Mall, Stanford CA 94305, USA.
+*/
+
+#ifndef AVL_H
+# define AVL_H 1
+
+# include <stddef.h>
+# if defined(__cplusplus)
+extern "C" {
+# endif
+
+
+/* Function types. */
+ typedef int avl_comparison_func (const void *avl_a, const void *avl_b,
+ void *avl_param);
+ typedef void avl_item_func (void *avl_item, void *avl_param);
+ typedef void *avl_copy_func (void *avl_item, void *avl_param);
+
+# ifndef LIBAVL_ALLOCATOR
+# define LIBAVL_ALLOCATOR
+/* Memory allocator. */
+ struct libavl_allocator {
+ void *(*libavl_malloc) (struct libavl_allocator *, size_t libavl_size);
+ void (*libavl_free) (struct libavl_allocator *, void *libavl_block);
+ };
+# endif
+
+/* Default memory allocator. */
+ extern struct libavl_allocator avl_allocator_default;
+ void *avl_malloc (struct libavl_allocator *, size_t);
+ void avl_free (struct libavl_allocator *, void *);
+
+/* Maximum AVL height. */
+# ifndef AVL_MAX_HEIGHT
+# define AVL_MAX_HEIGHT 32
+# endif
+
+/* Tree data structure. */
+ struct avl_table {
+ struct avl_node *avl_root; /* Tree's root. */
+ avl_comparison_func *avl_compare; /* Comparison function. */
+ void *avl_param; /* Extra argument to |avl_compare|. */
+ struct libavl_allocator *avl_alloc; /* Memory allocator. */
+ size_t avl_count; /* Number of items in tree. */
+ unsigned long avl_generation; /* Generation number. */
+ };
+
+/* An AVL tree node. */
+ struct avl_node {
+ struct avl_node *avl_link[2]; /* Subtrees. */
+ void *avl_data; /* Pointer to data. */
+ signed char avl_balance; /* Balance factor. */
+ };
+
+/* AVL traverser structure. */
+ struct avl_traverser {
+ struct avl_table *avl_table; /* Tree being traversed. */
+ struct avl_node *avl_node; /* Current node in tree. */
+ struct avl_node *avl_stack[AVL_MAX_HEIGHT];
+ /* All the nodes above |avl_node|. */
+ size_t avl_height; /* Number of nodes in |avl_parent|. */
+ unsigned long avl_generation; /* Generation number. */
+ };
+
+/* Table functions. */
+ struct avl_table *avl_create (avl_comparison_func *, void *,
+ struct libavl_allocator *);
+ struct avl_table *avl_copy (const struct avl_table *, avl_copy_func *,
+ avl_item_func *, struct libavl_allocator *);
+ void avl_destroy (struct avl_table *, avl_item_func *);
+ void **avl_probe (struct avl_table *, void *);
+ void *avl_insert (struct avl_table *, void *);
+ void *avl_replace (struct avl_table *, void *);
+ void *avl_delete (struct avl_table *, const void *);
+ void *avl_find (const struct avl_table *, const void *);
+ void avl_assert_insert (struct avl_table *, void *);
+ void *avl_assert_delete (struct avl_table *, void *);
+
+# define avl_count(table) ((size_t) (table)->avl_count)
+
+/* Table traverser functions. */
+ void avl_t_init (struct avl_traverser *, struct avl_table *);
+ void *avl_t_first (struct avl_traverser *, struct avl_table *);
+ void *avl_t_last (struct avl_traverser *, struct avl_table *);
+ void *avl_t_find (struct avl_traverser *, struct avl_table *, void *);
+ void *avl_t_insert (struct avl_traverser *, struct avl_table *, void *);
+ void *avl_t_copy (struct avl_traverser *, const struct avl_traverser *);
+ void *avl_t_next (struct avl_traverser *);
+ void *avl_t_prev (struct avl_traverser *);
+ void *avl_t_cur (struct avl_traverser *);
+ void *avl_t_replace (struct avl_traverser *, void *);
+
+# if defined(__cplusplus)
+}
+# endif
+#endif /* avl.h */
diff --git a/Build/source/texk/web2c/mpdir/avlstuff.c b/Build/source/texk/web2c/mpdir/avlstuff.c
new file mode 100644
index 00000000000..300cd2c5218
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/avlstuff.c
@@ -0,0 +1,50 @@
+/*
+Copyright (c) 2004-2005 Han The Thanh, <thanh@pdftex.org>
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+This file is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with this file; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id: avlstuff.c,v 1.12 2005/07/11 20:27:39 hahe Exp hahe $
+
+*/
+
+#include "mplib.h"
+#include <kpathsea/c-vararg.h>
+#include <kpathsea/c-proto.h>
+#include "avl.h"
+
+static const char perforce_id[] =
+ "$Id: avlstuff.c,v 1.12 2005/07/11 20:27:39 hahe Exp hahe $";
+
+/* memory management functions for avl */
+
+void *avl_xmalloc (struct libavl_allocator *allocator, size_t size)
+{
+ assert (allocator != NULL && size > 0);
+ return xmalloc (size);
+}
+
+void avl_xfree (struct libavl_allocator *allocator, void *block)
+{
+ assert (allocator != NULL && block != NULL);
+ xfree (block);
+}
+
+struct libavl_allocator avl_xallocator = {
+ avl_xmalloc,
+ avl_xfree
+};
+
+
+/**********************************************************************/
diff --git a/Build/source/texk/web2c/mpdir/avlstuff.h b/Build/source/texk/web2c/mpdir/avlstuff.h
new file mode 100644
index 00000000000..2ffa57b627d
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/avlstuff.h
@@ -0,0 +1,29 @@
+/*
+Copyright (c) 2004 Han The Thanh, <thanh@pdftex.org>
+
+This file is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by Free
+Software Foundation; either version 2 of the License, or (at your option)
+any later version.
+
+This file is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License along
+with this file; if not, write to the Free Software Foundation, Inc.,
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/avlstuff.h#5 $
+
+formatted by indent -kr
+*/
+
+#include "avl.h"
+
+/* memory management functions for avl */
+
+extern struct libavl_allocator avl_xallocator;
+
+/* end of file avlstuff.h */
diff --git a/Build/source/texk/web2c/mpdir/makecpool.c b/Build/source/texk/web2c/mpdir/makecpool.c
new file mode 100644
index 00000000000..02ce0f94bea
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/makecpool.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main(int argc, char *argv[]) {
+ if (argc!=3) {
+ puts("Need exactly two arguments: pool_name and header_name");
+ exit(1);
+ }
+ char *filename = argv[1];
+ char *headername = argv[2];
+ FILE *fh = fopen(filename,"r");
+ char data[1024];
+ printf(
+ "/* This file is auto-generated by makecpool */\n"
+ "\n"
+ "#include <stdio.h>\n"
+ "#include \"%s\"\n"
+ "\n"
+ "static char *poolfilearr[] = {\n",headername);
+ while (fgets(data,1024,fh)) {
+ int len = strlen(data);
+ int o = 0; // skip first o characters
+ int i;
+ if (data[len-1]=='\n') { // chomp;
+ data[len-1] = 0;
+ len--;
+ }
+ if (data[0]=='*') break; // last if /^\*/;
+ if (data[0]>='0' && data[0]<='9' && data[1]>='0' && data[1]<='9') {
+ o=2; // $data =~ s/^\d\d//;
+ }
+ printf(" \"");
+ for (i=o; i<len; i++) {
+ if (data[i]=='"' || data[i]=='\\') putchar('\\');
+ if (data[i]=='?') printf("\" \""); /* suppress trigraphs */
+ putchar(data[i]);
+ } // $data =~ s/(["\\])/\\$1/g;
+ printf("\",\n");
+ }
+ fclose(fh);
+ printf(" NULL };\n"
+ "int loadpoolstrings (integer spare_size) {\n"
+ " strnumber g=0;\n"
+ " int i=0,j=0;\n"
+ " char *s;\n"
+ " while ((s = poolfilearr[j++])) {\n"
+ " int l = strlen (s);\n"
+ " i += l;\n"
+ " if (i>=spare_size) return 0;\n"
+ " while (l-- > 0) strpool[poolptr++] = *s++;\n"
+ " g = makestring();\n"
+ " strref[g]= 127;\n"
+ " }\n"
+ " return g;\n"
+ "}\n");
+ return 0;
+}
diff --git a/Build/source/texk/web2c/mpdir/mapfile.c b/Build/source/texk/web2c/mpdir/mapfile.c
new file mode 100644
index 00000000000..25d5818f5c0
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/mapfile.c
@@ -0,0 +1,993 @@
+/* Copyright (c) 2006 Taco Hoekwater <taco@elvenkind.com>
+
+This file is part of MetaPost.
+
+MetaPost is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+MetaPost is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with MetaPost; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id: mapfile.c,v 1.20 2005/10/16 17:41:51 hahe Exp hahe $
+
+*/
+
+#include <math.h>
+#include "mplib.h"
+#include <kpathsea/c-auto.h>
+#include <kpathsea/c-memstr.h>
+#include <string.h>
+
+static const char perforce_id[] =
+ "$Id: mapfile.c,v 1.20 2005/10/16 17:41:51 hahe Exp hahe $";
+
+#define FM_BUF_SIZE 1024
+
+static FILE *fm_file;
+
+#define fm_open() \
+ open_input (&fm_file, kpse_fontmap_format, FOPEN_RBIN_MODE)
+#define fm_close() xfclose(fm_file, cur_file_name)
+#define fm_getchar() xgetc(fm_file)
+#define fm_eof() feof(fm_file)
+
+enum _mode { FM_DUPIGNORE, FM_REPLACE, FM_DELETE };
+enum _ltype { MAPFILE, MAPLINE };
+enum _tfmavail { TFM_UNCHECKED, TFM_FOUND, TFM_NOTFOUND };
+
+typedef struct mitem {
+ int mode; /* FM_DUPIGNORE or FM_REPLACE or FM_DELETE */
+ int type; /* map file or map line */
+ char *line; /* pointer to map file name or map line */
+ int lineno; /* line number in map file */
+} mapitem;
+mapitem *mitem = NULL;
+
+fm_entry *fm_cur;
+static const char nontfm[] = "<nontfm>";
+static fm_entry *loaded_tfm_found;
+static fm_entry *avail_tfm_found;
+static fm_entry *non_tfm_found;
+static fm_entry *not_avail_tfm_found;
+
+#define read_field(r, q, buf) do { \
+ q = buf; \
+ while (*r != ' ' && *r != '\0') \
+ *q++ = *r++; \
+ *q = '\0'; \
+ skip (r, ' '); \
+} while (0)
+
+#define set_field(F) do { \
+ if (q > buf) \
+ fm->F = xstrdup(buf); \
+ if (*r == '\0') \
+ goto done; \
+} while (0)
+
+#define cmp_return(a, b) \
+ if (a > b) \
+ return 1; \
+ if (a < b) \
+ return -1
+
+fm_entry *new_fm_entry (void)
+{
+ fm_entry *fm;
+ fm = xtalloc (1, fm_entry);
+ fm->tfm_name = NULL;
+ fm->ps_name = NULL;
+ fm->flags = 4;
+ fm->ff_name = NULL;
+ fm->subset_tag = NULL;
+ fm->encoding = NULL;
+ fm->tfm_num = getnullfont ();
+ fm->tfm_avail = TFM_UNCHECKED;
+ fm->type = 0;
+ fm->slant = 0;
+ fm->extend = 0;
+ fm->ff_objnum = 0;
+ fm->fn_objnum = 0;
+ fm->fd_objnum = 0;
+ fm->charset = NULL;
+ fm->all_glyphs = false;
+ fm->links = 0;
+ fm->pid = -1;
+ fm->eid = -1;
+ fm->subfont = NULL;
+ return fm;
+}
+
+void delete_fm_entry (fm_entry * fm)
+{
+ xfree (fm->tfm_name);
+ xfree (fm->ps_name);
+ xfree (fm->ff_name);
+ xfree (fm->subset_tag);
+ xfree (fm->charset);
+ xfree (fm);
+}
+
+static ff_entry *new_ff_entry (void)
+{
+ ff_entry *ff;
+ ff = xtalloc (1, ff_entry);
+ ff->ff_name = NULL;
+ ff->ff_path = NULL;
+ return ff;
+}
+
+static void delete_ff_entry (ff_entry * ff)
+{
+ xfree (ff->ff_name);
+ xfree (ff->ff_path);
+ xfree (ff);
+}
+
+static fm_entry *dummy_fm_entry ()
+{
+ static const fm_entry const_fm_entry;
+ return (fm_entry *) & const_fm_entry;
+}
+
+char *mk_base_tfm (char *tfmname, int *i)
+{
+ static char buf[SMALL_BUF_SIZE];
+ char *p = tfmname, *r = strend (p) - 1, *q = r;
+ while (q > p && isdigit (*q))
+ --q;
+ if (!(q > p) || q == r || (*q != '+' && *q != '-'))
+ return NULL;
+ check_buf (q - p + 1, SMALL_BUF_SIZE);
+ strncpy (buf, p, (size_t) (q - p));
+ buf[q - p] = '\0';
+ *i = atoi (q);
+ return buf;
+}
+
+static fmentryptr fmlookup (fontnumber);
+
+boolean hasfmentry (fontnumber f)
+{
+ if (mpfontmap[f] == NULL)
+ mpfontmap[f] = fmlookup (f);
+ assert (mpfontmap[f] != NULL);
+ return mpfontmap[f] != (fmentryptr) dummy_fm_entry ();
+}
+
+/**********************************************************************/
+
+struct avl_table *tfm_tree = NULL;
+struct avl_table *ps_tree = NULL;
+struct avl_table *ff_tree = NULL;
+
+/* AVL sort fm_entry into tfm_tree by tfm_name */
+
+static int comp_fm_entry_tfm (const void *pa, const void *pb, void *p)
+{
+ return strcmp (((const fm_entry *) pa)->tfm_name,
+ ((const fm_entry *) pb)->tfm_name);
+}
+
+/* AVL sort fm_entry into ps_tree by ps_name, slant, and extend */
+
+static int comp_fm_entry_ps (const void *pa, const void *pb, void *p)
+{
+ const fm_entry *p1 = (const fm_entry *) pa, *p2 = (const fm_entry *) pb;
+ int i;
+ assert (p1->ps_name != NULL && p2->ps_name != NULL);
+ if ((i = strcmp (p1->ps_name, p2->ps_name)))
+ return i;
+ cmp_return (p1->slant, p2->slant);
+ cmp_return (p1->extend, p2->extend);
+ if (p1->tfm_name != NULL && p2->tfm_name != NULL &&
+ (i = strcmp (p1->tfm_name, p2->tfm_name)))
+ return i;
+ return 0;
+}
+
+/* AVL sort ff_entry into ff_tree by ff_name */
+
+static int comp_ff_entry (const void *pa, const void *pb, void *p)
+{
+ return strcmp (((const ff_entry *) pa)->ff_name,
+ ((const ff_entry *) pb)->ff_name);
+}
+
+static void create_avl_trees ()
+{
+ if (tfm_tree == NULL) {
+ tfm_tree = avl_create (comp_fm_entry_tfm, NULL, &avl_xallocator);
+ assert (tfm_tree != NULL);
+ }
+ if (ps_tree == NULL) {
+ ps_tree = avl_create (comp_fm_entry_ps, NULL, &avl_xallocator);
+ assert (ps_tree != NULL);
+ }
+ if (ff_tree == NULL) {
+ ff_tree = avl_create (comp_ff_entry, NULL, &avl_xallocator);
+ assert (ff_tree != NULL);
+ }
+}
+
+/*
+The function avl_do_entry() is not completely symmetrical with regards
+to tfm_name and ps_name handling, e. g. a duplicate tfm_name gives a
+"goto exit", and no ps_name link is tried. This is to keep it compatible
+with the original version.
+*/
+
+int avl_do_entry (fm_entry * fp, int mode)
+{
+ fm_entry *p;
+ void *a;
+ void **aa;
+
+ /* handle tfm_name link */
+
+ if (strcmp (fp->tfm_name, nontfm)) {
+ p = (fm_entry *) avl_find (tfm_tree, fp);
+ if (p != NULL) {
+ if (mode == FM_DUPIGNORE) {
+ pdftex_warn
+ ("fontmap entry for `%s' already exists, duplicates ignored",
+ fp->tfm_name);
+ goto exit;
+ } else { /* mode == FM_REPLACE / FM_DELETE */
+ if (fontsizes[p->tfm_num]!=0) {
+ pdftex_warn
+ ("fontmap entry for `%s' has been used, replace/delete not allowed",
+ fp->tfm_name);
+ goto exit;
+ }
+ a = avl_delete (tfm_tree, p);
+ assert (a != NULL);
+ unset_tfmlink (p);
+ if (!has_pslink (p))
+ delete_fm_entry (p);
+ }
+ }
+ if (mode != FM_DELETE) {
+ aa = avl_probe (tfm_tree, fp);
+ assert (aa != NULL);
+ set_tfmlink (fp);
+ }
+ }
+
+ /* handle ps_name link */
+
+ if (fp->ps_name != NULL) {
+ assert (fp->tfm_name != NULL);
+ p = (fm_entry *) avl_find (ps_tree, fp);
+ if (p != NULL) {
+ if (mode == FM_DUPIGNORE) {
+ pdftex_warn
+ ("ps_name entry for `%s' already exists, duplicates ignored",
+ fp->ps_name);
+ goto exit;
+ } else { /* mode == FM_REPLACE / FM_DELETE */
+ if (fontsizes[p->tfm_num]!=0) {
+ /* REPLACE/DELETE not allowed */
+ pdftex_warn
+ ("fontmap entry for `%s' has been used, replace/delete not allowed",
+ p->tfm_name);
+ goto exit;
+ }
+ a = avl_delete (ps_tree, p);
+ assert (a != NULL);
+ unset_pslink (p);
+ if (!has_tfmlink (p))
+ delete_fm_entry (p);
+ }
+ }
+ if (mode != FM_DELETE) {
+ aa = avl_probe (ps_tree, fp);
+ assert (aa != NULL);
+ set_pslink (fp);
+ }
+ }
+ exit:
+ if (!has_tfmlink (fp) && !has_pslink (fp)) /* e. g. after FM_DELETE */
+ return 1; /* deallocation of fm_entry structure required */
+ else
+ return 0;
+}
+
+/**********************************************************************/
+/* consistency check for map entry, with warn flag */
+
+int check_fm_entry (fm_entry * fm, boolean warn)
+{
+ int a = 0;
+ assert (fm != NULL);
+ if (fm->ps_name != NULL) {
+ if (is_basefont (fm)) {
+ if (is_fontfile (fm) && !is_included (fm)) {
+ if (warn)
+ pdftex_warn
+ ("invalid entry for `%s': font file must be included or omitted for base fonts",
+ fm->tfm_name);
+ a += 1;
+ }
+ } else { /* not a base font */
+ /* if no font file given, drop this entry */
+ /* if (!is_fontfile (fm)) {
+ if (warn)
+ pdftex_warn
+ ("invalid entry for `%s': font file missing",
+ fm->tfm_name);
+ a += 2;
+ }
+ */
+ }
+ }
+ if (is_truetype (fm) && is_reencoded (fm) && !is_subsetted (fm)) {
+ if (warn)
+ pdftex_warn
+ ("invalid entry for `%s': only subsetted TrueType font can be reencoded",
+ fm->tfm_name);
+ a += 4;
+ }
+ if ((fm->slant != 0 || fm->extend != 0) &&
+ (is_truetype (fm))) {
+ if (warn)
+ pdftex_warn
+ ("invalid entry for `%s': SlantFont/ExtendFont can be used only with embedded T1 fonts",
+ fm->tfm_name);
+ a += 8;
+ }
+ if (abs (fm->slant) > 1000) {
+ if (warn)
+ pdftex_warn
+ ("invalid entry for `%s': too big value of SlantFont (%g)",
+ fm->tfm_name, fm->slant / 1000.0);
+ a += 16;
+ }
+ if (abs (fm->extend) > 2000) {
+ if (warn)
+ pdftex_warn
+ ("invalid entry for `%s': too big value of ExtendFont (%g)",
+ fm->tfm_name, fm->extend / 1000.0);
+ a += 32;
+ }
+ if (fm->pid != -1 &&
+ !(is_truetype (fm) && is_included (fm) &&
+ is_subsetted (fm) && !is_reencoded (fm))) {
+ if (warn)
+ pdftex_warn
+ ("invalid entry for `%s': PidEid can be used only with subsetted non-reencoded TrueType fonts",
+ fm->tfm_name);
+ a += 64;
+ }
+ return a;
+}
+
+/**********************************************************************/
+/* returns true if s is one of the 14 std. font names; speed-trimmed. */
+
+boolean check_basefont (char *s)
+{
+ static const char *basefont_names[] = {
+ "Courier", /* 0:7 */
+ "Courier-Bold", /* 1:12 */
+ "Courier-Oblique", /* 2:15 */
+ "Courier-BoldOblique", /* 3:19 */
+ "Helvetica", /* 4:9 */
+ "Helvetica-Bold", /* 5:14 */
+ "Helvetica-Oblique", /* 6:17 */
+ "Helvetica-BoldOblique", /* 7:21 */
+ "Symbol", /* 8:6 */
+ "Times-Roman", /* 9:11 */
+ "Times-Bold", /* 10:10 */
+ "Times-Italic", /* 11:12 */
+ "Times-BoldItalic", /* 12:16 */
+ "ZapfDingbats" /* 13:12 */
+ };
+ static const int index[] =
+ { -1, -1, -1, -1, -1, -1, 8, 0, -1, 4, 10, 9, -1, -1, 5, 2, 12, 6,
+ -1, 3, -1, 7
+ };
+ const size_t n = strlen (s);
+ int k = -1;
+ if (n > 21)
+ return false;
+ if (n == 12) { /* three names have length 12 */
+ switch (*s) {
+ case 'C':
+ k = 1; /* Courier-Bold */
+ break;
+ case 'T':
+ k = 11; /* Times-Italic */
+ break;
+ case 'Z':
+ k = 13; /* ZapfDingbats */
+ break;
+ default:
+ return false;
+ }
+ } else
+ k = index[n];
+ if (k > -1 && !strcmp (basefont_names[k], s))
+ return true;
+ return false;
+};
+
+/**********************************************************************/
+
+static void fm_scan_line ()
+{
+ int a, b, c, j, u = 0, v = 0;
+ float d;
+ fm_entry *fm;
+ char fm_line[FM_BUF_SIZE], buf[FM_BUF_SIZE];
+ char *p, *q, *r, *s;
+ switch (mitem->type) {
+ case MAPFILE:
+ p = fm_line;
+ do {
+ c = fm_getchar ();
+ append_char_to_buf (c, p, fm_line, FM_BUF_SIZE);
+ }
+ while (c != 10);
+ *(--p) = '\0';
+ r = fm_line;
+ break;
+ case MAPLINE:
+ r = mitem->line; /* work on string from makecstring() */
+ break;
+ default:
+ assert (0);
+ }
+ if (*r == '\0' || is_cfg_comment (*r))
+ return;
+ fm = new_fm_entry ();
+ read_field (r, q, buf);
+ set_field (tfm_name);
+ p = r;
+ read_field (r, q, buf);
+ if (*buf != '<' && *buf != '"')
+ set_field (ps_name);
+ else
+ r = p; /* unget the field */
+ if (isdigit (*r)) { /* font flags given */
+ fm->flags = atoi (r);
+ while (isdigit (*r))
+ r++;
+ }
+ while (1) { /* loop through "specials", encoding, font file */
+ skip (r, ' ');
+ switch (*r) {
+ case '\0':
+ goto done;
+ case '"': /* opening quote */
+ r++;
+ u = v = 0;
+ do {
+ skip (r, ' ');
+ if (sscanf (r, "%f %n", &d, &j) > 0) {
+ s = r + j; /* jump behind number, eat also blanks, if any */
+ if (*(s - 1) == 'E' || *(s - 1) == 'e')
+ s--; /* e. g. 0.5ExtendFont: %f = 0.5E */
+ if (str_prefix (s, "SlantFont")) {
+ d *= 1000.0; /* correct rounding also for neg. numbers */
+ fm->slant = (integer) (d > 0 ? d + 0.5 : d - 0.5);
+ r = s + strlen ("SlantFont");
+ } else if (str_prefix (s, "ExtendFont")) {
+ d *= 1000.0;
+ fm->extend = (integer) (d > 0 ? d + 0.5 : d - 0.5);
+ if (fm->extend == 1000)
+ fm->extend = 0;
+ r = s + strlen ("ExtendFont");
+ } else { /* unknown name */
+ for (r = s; *r != ' ' && *r != '"' && *r != '\0'; r++); /* jump over name */
+ c = *r; /* remember char for temporary end of string */
+ *r = '\0';
+ pdftex_warn
+ ("invalid entry for `%s': unknown name `%s' ignored",
+ fm->tfm_name, s);
+ *r = c;
+ }
+ } else
+ for (; *r != ' ' && *r != '"' && *r != '\0'; r++);
+ }
+ while (*r == ' ');
+ if (*r == '"') /* closing quote */
+ r++;
+ else {
+ pdftex_warn
+ ("invalid entry for `%s': closing quote missing",
+ fm->tfm_name);
+ goto bad_line;
+ }
+ break;
+ case 'P': /* handle cases for subfonts like 'PidEid=3,1' */
+ if (sscanf (r, "PidEid=%i, %i %n", &a, &b, &c) >= 2) {
+ fm->pid = a;
+ fm->eid = b;
+ r += c;
+ break;
+ }
+ default: /* encoding or font file specification */
+ a = b = 0;
+ if (*r == '<') {
+ a = *r++;
+ if (*r == '<' || *r == '[')
+ b = *r++;
+ }
+ read_field (r, q, buf);
+ /* encoding, formats: '8r.enc' or '<8r.enc' or '<[8r.enc' */
+ if (strlen (buf) > 4 && strcasecmp (strend (buf) - 4, ".enc") == 0) {
+ fm->encoding = add_enc (buf);
+ u = v = 0; /* u, v used if intervening blank: "<< foo" */
+ } else if (strlen (buf) > 0) { /* file name given */
+ /* font file, formats:
+ * subsetting: '<cmr10.pfa'
+ * no subsetting: '<<cmr10.pfa'
+ * no embedding: 'cmr10.pfa'
+ */
+ if (a == '<' || u == '<') {
+ set_included (fm);
+ if ((a == '<' && b == 0) || (a == 0 && v == 0))
+ set_subsetted (fm);
+ /* otherwise b == '<' (or '[') => no subsetting */
+ }
+ set_field (ff_name);
+ u = v = 0;
+ } else {
+ u = a;
+ v = b;
+ }
+ }
+ }
+ done:
+ if (fm->ps_name != NULL && check_basefont (fm->ps_name))
+ set_basefont (fm);
+ if (is_fontfile (fm)
+ && strcasecmp (strend (fm_fontfile (fm)) - 4, ".ttf") == 0)
+ set_truetype (fm);
+ if (check_fm_entry (fm, true) != 0)
+ goto bad_line;
+ /*
+ Until here the map line has been completely scanned without errors;
+ fm points to a valid, freshly filled-out fm_entry structure.
+ Now follows the actual work of registering/deleting.
+ */
+ // if (handle_subfont_fm (fm, mitem->mode)) /* is this a subfont? */
+ // return;
+ if (avl_do_entry (fm, mitem->mode) == 0) /* if success */
+ return;
+ bad_line:
+ delete_fm_entry (fm);
+}
+
+/**********************************************************************/
+
+void fm_read_info ()
+{
+ if (tfm_tree == NULL)
+ create_avl_trees ();
+ if (mitem->line == NULL) /* nothing to do */
+ return;
+ mitem->lineno = 1;
+ switch (mitem->type) {
+ case MAPFILE:
+ set_cur_file_name (mitem->line);
+ if (!fm_open ()) {
+ pdftex_warn ("cannot open font map file");
+ } else {
+ cur_file_name = (char *) nameoffile + 1;
+ mp_printf ("{%s", cur_file_name);
+ while (!fm_eof ()) {
+ fm_scan_line ();
+ mitem->lineno++;
+ }
+ fm_close ();
+ mp_printf ("}");
+ fm_file = NULL;
+ }
+ break;
+ case MAPLINE:
+ cur_file_name = NULL; /* makes pdftex_warn() shorter */
+ fm_scan_line ();
+ break;
+ default:
+ assert (0);
+ }
+ mitem->line = NULL; /* done with this line */
+ cur_file_name = NULL;
+ return;
+}
+
+/**********************************************************************/
+
+fontnumber tfmoffm (fmentryptr fm_pt)
+{
+ return ((fm_entry *) fm_pt)->tfm_num;
+}
+
+static fm_entry *mk_ex_fm (fontnumber f, fm_entry * basefm, int ex)
+{
+ fm_entry *fm;
+ integer e = basefm->extend;
+ if (e == 0)
+ e = 1000;
+ fm = new_fm_entry ();
+ fm->flags = basefm->flags;
+ fm->encoding = basefm->encoding;
+ fm->type = basefm->type;
+ fm->slant = basefm->slant;
+ fm->extend = roundxnoverd (e, 1000 + ex, 1000); /* modify ExtentFont to simulate expansion */
+ if (fm->extend == 1000)
+ fm->extend = 0;
+ fm->tfm_name = xstrdup (makecstring (fontname[f]));
+ if (basefm->ps_name != NULL)
+ fm->ps_name = xstrdup (basefm->ps_name);
+ fm->ff_name = xstrdup (basefm->ff_name);
+ fm->ff_objnum = 0;
+ fm->tfm_num = f;
+ fm->tfm_avail = TFM_FOUND;
+ assert (strcmp (fm->tfm_name, nontfm));
+ return fm;
+}
+
+static void init_fm (fm_entry * fm, fontnumber f)
+{
+ // if (fm->fd_objnum == 0 && !no_font_desc (fm))
+ // fm->fd_objnum = pdfnewobjnum ();
+ // if (fm->ff_objnum == 0 && is_included (fm))
+ // fm->ff_objnum = pdfnewobjnum ();
+ if (fm->tfm_num == getnullfont ()) {
+ fm->tfm_num = f;
+ fm->tfm_avail = TFM_FOUND;
+ }
+}
+
+static fmentryptr fmlookup (fontnumber f)
+{
+ char *tfm;
+ fm_entry *fm, *exfm;
+ fm_entry tmp;
+ int ai, e;
+ if (tfm_tree == NULL)
+ fm_read_info (); /* only to read default map file */
+ tfm = makecstring (fontname[f]);
+ assert (strcmp (tfm, nontfm));
+
+ /* Look up for full <tfmname>[+-]<expand> */
+ tmp.tfm_name = tfm;
+ fm = (fm_entry *) avl_find (tfm_tree, &tmp);
+ if (fm != NULL) {
+ init_fm (fm, f);
+ return (fmentryptr) fm;
+ }
+ tfm = mk_base_tfm (makecstring (fontname[f]), &e);
+ if (tfm == NULL) /* not an expanded font, nothing to do */
+ return (fmentryptr) dummy_fm_entry ();
+
+ tmp.tfm_name = tfm;
+ fm = (fm_entry *) avl_find (tfm_tree, &tmp);
+ if (fm != NULL) { /* found an entry with the base tfm name, e.g. cmr10 */
+ return (fmentryptr) fm; /* font expansion uses the base font */
+ /* the following code would be obsolete, as would be mk_ex_fm() */
+ if (!is_t1fontfile (fm) || !is_included (fm)) {
+ pdftex_warn
+ ("font %s cannot be expanded (not an included Type1 font)",
+ tfm);
+ return (fmentryptr) dummy_fm_entry ();
+ }
+ exfm = mk_ex_fm (f, fm, e); /* copies all fields from fm except tfm name */
+ init_fm (exfm, f);
+ ai = avl_do_entry (exfm, FM_DUPIGNORE);
+ assert (ai == 0);
+ return (fmentryptr) exfm;
+ }
+ return (fmentryptr) dummy_fm_entry ();
+}
+
+/*
+ Early check whether a font file exists. Used e. g. for replacing fonts
+ of embedded PDF files: Without font file, the font within the embedded
+ PDF-file is used. Search tree ff_tree is used in 1st instance, as it
+ may be faster than the kpse_find_file(), and kpse_find_file() is called
+ only once per font file name + expansion parameter. This might help
+ keeping speed, if many PDF pages with same fonts are to be embedded.
+
+ The ff_tree contains only font files, which are actually needed,
+ so this tree typically is much smaller than the tfm_tree or ps_tree.
+*/
+
+ff_entry *check_ff_exist (fm_entry * fm)
+{
+ ff_entry *ff;
+ ff_entry tmp;
+ void **aa;
+
+ assert (fm->ff_name != NULL);
+ tmp.ff_name = fm->ff_name;
+ ff = (ff_entry *) avl_find (ff_tree, &tmp);
+ if (ff == NULL) { /* not yet in database */
+ ff = new_ff_entry ();
+ ff->ff_name = xstrdup (fm->ff_name);
+ if (is_truetype (fm))
+ ff->ff_path = kpse_find_file (fm->ff_name, kpse_truetype_format, 0);
+ else
+ ff->ff_path = kpse_find_file (fm->ff_name, kpse_type1_format, 0);
+ aa = avl_probe (ff_tree, ff);
+ assert (aa != NULL);
+ }
+ return ff;
+}
+
+/**********************************************************************/
+
+static boolean used_tfm (fm_entry * p)
+{
+ fontnumber f;
+ strnumber s;
+ ff_entry *ff;
+
+ /* check if the font file is not a TrueType font */
+ /* font replacement makes sense only for included Type1 files */
+ if (is_truetype (p) || !is_included (p))
+ return false;
+
+ /* check if the font file is available */
+ ff = check_ff_exist (p);
+ if (ff->ff_path == NULL)
+ return false;
+
+ /* check whether this font has been used */
+ if (fontsizes[p->tfm_num]!=0)
+ return true;
+ assert (p->tfm_name != NULL);
+
+ /* check whether we didn't find a loaded font yet,
+ * and this font has been loaded */
+ if (loaded_tfm_found == NULL && strcmp (p->tfm_name, nontfm)) {
+ s = maketexstring (p->tfm_name);
+ if ((f = tfmlookup (s, 0)) != getnullfont ()) {
+ loaded_tfm_found = p;
+ if (mpfontmap[f] == NULL)
+ mpfontmap[f] = (fmentryptr) p;
+ if (p->tfm_num == getnullfont ())
+ p->tfm_num = f;
+ assert (p->tfm_num == f);
+ /* don't call flushstr() here as it has been called by tfmlookup() */
+ } else
+ flushstr (s);
+ }
+
+ /* check whether we didn't find either a loaded or a loadable font yet,
+ * and this font is loadable */
+ if (avail_tfm_found == NULL && loaded_tfm_found == NULL &&
+ strcmp (p->tfm_name, nontfm)) {
+ if (p->tfm_avail == TFM_UNCHECKED) {
+ if (kpse_find_file (p->tfm_name, kpse_tfm_format, 0) != NULL) {
+ avail_tfm_found = p;
+ p->tfm_avail = TFM_FOUND;
+ } else {
+ p->tfm_avail = TFM_NOTFOUND;
+ if (not_avail_tfm_found == NULL)
+ not_avail_tfm_found = p;
+ }
+ }
+ }
+
+ /* check whether the current entry is a <nontfm> entry */
+ if (non_tfm_found == NULL && !strcmp (p->tfm_name, nontfm))
+ non_tfm_found = p;
+
+ return false;
+}
+
+/* lookup_ps_name looks for an entry with a given ps name + slant + extend;
+ * return NULL if not found.
+ *
+ * As there may exist several such entries, we need to select the `right'
+ * one. We do so by checking all such entries and return the first one that
+ * fulfils the following criteria (in descending priority):
+ *
+ * - the tfm has been used (some char from this font has been typeset)
+ * - the tfm has been loaded (but not used yet)
+ * - the tfm can be loaded (but not loaded yet)
+ * - the tfm is present in map files, but cannot be loaded. In this case a
+ * dummy tfm can be loaded instead, and a warning should be written out
+ */
+
+static fm_entry *lookup_ps_name (fm_entry * fm)
+{
+ fm_entry *p, *p2;
+ struct avl_traverser t, t2;
+ int a;
+
+ loaded_tfm_found = NULL;
+ avail_tfm_found = NULL;
+ non_tfm_found = NULL;
+ not_avail_tfm_found = NULL;
+
+ assert (fm->tfm_name == NULL);
+ p = (fm_entry *) avl_t_find (&t, ps_tree, fm);
+ if (p == NULL)
+ return NULL;
+ t2 = t;
+ p2 = (fm_entry *) avl_t_prev (&t2);
+
+ /* search forward */
+ do {
+ if (used_tfm (p))
+ return p;
+ p = (fm_entry *) avl_t_next (&t);
+ }
+ while (p != NULL && comp_fm_entry_ps (fm, p, NULL) == 0);
+
+ /* search backward */
+ while (p2 != NULL && comp_fm_entry_ps (fm, p2, NULL) == 0) {
+ if (used_tfm (p2))
+ return p2;
+ p2 = (fm_entry *) avl_t_prev (&t2);
+ }
+
+ if (loaded_tfm_found != NULL)
+ p = loaded_tfm_found;
+ else if (avail_tfm_found != NULL) {
+ /* TH: do not do this for metapost, there is no embedding anyway */
+ /* p = avail_tfm_found;
+ * p->tfm_num = readfontinfo (getnullcs (), maketexstring (p->tfm_name),
+ * getnullstr (), -1000);
+ * p->tfm_avail = TFM_FOUND;
+ */
+ } else if (non_tfm_found != NULL) {
+ p = non_tfm_found;
+ p->tfm_num = newdummyfont ();
+ p->tfm_avail = TFM_FOUND;
+ } else if (not_avail_tfm_found != NULL) {
+ p = not_avail_tfm_found;
+ pdftex_warn ("`%s' not loadable, use a dummy tfm instead", p->tfm_name);
+ p2 = new_fm_entry ();
+ p2->flags = p->flags;
+ p2->encoding = p->encoding;
+ p2->type = p->type;
+ p2->slant = p->slant;
+ p2->extend = p->extend;
+ p2->tfm_name = xstrdup (nontfm);
+ p2->ps_name = xstrdup (p->ps_name);
+ if (p->ff_name != NULL)
+ p2->ff_name = xstrdup (p->ff_name);
+ p2->tfm_num = newdummyfont ();
+ p2->tfm_avail = TFM_FOUND;
+ a = avl_do_entry (p2, FM_DUPIGNORE);
+ assert (a == 0);
+ p = p2;
+ } else
+ return NULL;
+ assert (p->tfm_num != getnullfont ());
+ return p;
+}
+
+
+/**********************************************************************/
+/*
+Process map file given by its name or map line contents. Items not
+beginning with [+-=] flush default map file, if it has not yet been
+read. Leading blanks and blanks immediately following [+-=] are ignored.
+*/
+
+void process_map_item (char *s, int type)
+{
+ char *p;
+ int mode;
+ if (*s == ' ')
+ s++; /* ignore leading blank */
+ switch (*s) {
+ case '+': /* +mapfile.map, +mapline */
+ mode = FM_DUPIGNORE; /* insert entry, if it is not duplicate */
+ s++;
+ break;
+ case '=': /* =mapfile.map, =mapline */
+ mode = FM_REPLACE; /* try to replace earlier entry */
+ s++;
+ break;
+ case '-': /* -mapfile.map, -mapline */
+ mode = FM_DELETE; /* try to delete entry */
+ s++;
+ break;
+ default:
+ mode = FM_DUPIGNORE; /* like +, but also: */
+ mitem->line = NULL; /* flush default map file name */
+ }
+ if (*s == ' ')
+ s++; /* ignore blank after [+-=] */
+ p = s; /* map item starts here */
+ switch (type) {
+ case MAPFILE: /* remove blank at end */
+ while (*p != '\0' && *p != ' ')
+ p++;
+ *p = '\0';
+ break;
+ case MAPLINE: /* blank at end allowed */
+ break;
+ default:
+ assert (0);
+ }
+ if (mitem->line != NULL) /* read default map file first */
+ fm_read_info ();
+ if (*s != '\0') { /* only if real item to process */
+ mitem->mode = mode;
+ mitem->type = type;
+ mitem->line = s;
+ fm_read_info ();
+ }
+}
+
+void mpmapfile (strnumber t)
+{
+ char *s = xstrdup(makecstring (t));
+ process_map_item (s, MAPFILE);
+ xfree (s);
+}
+
+void mpmapline (strnumber t)
+{
+ char *s = xstrdup(makecstring (t));
+ process_map_item (s, MAPLINE);
+ xfree (s);
+}
+
+void mpinitmapfile (void)
+{
+ assert (mitem == NULL);
+ mitem = xtalloc (1, mapitem);
+ mitem->mode = FM_DUPIGNORE;
+ mitem->type = MAPFILE;
+ if (kpse_find_file("mpost.map", kpse_fontmap_format,0))
+ mitem->line = xstrdup ("mpost.map");
+ else
+ mitem->line = xstrdup ("pdftex.map");
+}
+
+/**********************************************************************/
+/* cleaning up... */
+
+static void destroy_fm_entry_tfm (void *pa, void *pb)
+{
+ fm_entry *fm;
+ fm = (fm_entry *) pa;
+ if (!has_pslink (fm))
+ delete_fm_entry (fm);
+ else
+ unset_tfmlink (fm);
+}
+static void destroy_fm_entry_ps (void *pa, void *pb)
+{
+ fm_entry *fm;
+ fm = (fm_entry *) pa;
+ if (!has_tfmlink (fm))
+ delete_fm_entry (fm);
+ else
+ unset_pslink (fm);
+}
+static void destroy_ff_entry (void *pa, void *pb)
+{
+ ff_entry *ff;
+ ff = (ff_entry *) pa;
+ delete_ff_entry (ff);
+} void fm_free (void)
+{
+ if (tfm_tree != NULL)
+ avl_destroy (tfm_tree, destroy_fm_entry_tfm);
+ if (ps_tree != NULL)
+ avl_destroy (ps_tree, destroy_fm_entry_ps);
+ if (ff_tree != NULL)
+ avl_destroy (ff_tree, destroy_ff_entry);
+}
+
+/**********************************************************************/
+/* end of mapfile.c */
diff --git a/Build/source/texk/web2c/mpdir/mp.defines b/Build/source/texk/web2c/mpdir/mp.defines
new file mode 100644
index 00000000000..bdd51f83332
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/mp.defines
@@ -0,0 +1,54 @@
+{
+Copyright (c) 2006 Taco Hoekwater <taco@elvenkind.com>
+
+This file is part of MetaPost.
+
+MetaPost is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+MetaPost is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with MetaPost; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id$
+}
+
+{ functions from loadpool.c }
+
+@define function loadpoolstrings();
+
+{ functions from mapfile.c }
+
+@define function hasfmentry();
+@define function tfmoffm();
+@define procedure mpmapfile();
+@define procedure mpmapline();
+@define procedure mpinitmapfile;
+
+{ functions from writefont.c }
+
+@define procedure mploadencodings();
+@define procedure mpfontencodings();
+@define function fontisreencoded();
+@define function fontisincluded();
+@define function fontissubsetted();
+
+@define function fmencodingname();
+@define function fmfontname();
+@define function fmfontsubsetname();
+@define function fmfontslant();
+@define function fmfontextend();
+
+@define function dopsfont();
+
+{ functions from utils.c }
+
+@define procedure setjobid();
+
diff --git a/Build/source/texk/web2c/mpdir/mplib.h b/Build/source/texk/web2c/mpdir/mplib.h
new file mode 100644
index 00000000000..363836a994d
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/mplib.h
@@ -0,0 +1,300 @@
+/*
+Copyright (c) 2006 Taco Hoekwater <taco@elvenkind.com>
+
+This file is part of pdfTeX.
+
+pdfTeX is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+pdfTeX is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with pdfTeX; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id$
+*/
+
+#ifndef MPOSTLIB
+# define MPOSTLIB
+
+/* WEB2C macros and prototypes */
+# if !defined(MPOSTCOERCE)
+# define EXTERN extern
+# include "mpd.h"
+# endif
+
+/* pdftexlib macros */
+# include "mpmac.h"
+
+# include "avlstuff.h"
+
+
+/* pdftexlib type declarations */
+typedef struct {
+ const char *pdfname;
+ const char *t1name;
+ float value;
+ boolean valid;
+} key_entry;
+
+typedef struct {
+ boolean loaded; /* the encoding has been loaded? */
+ char *name; /* encoding file name */
+ char *encname; /* encoding true name */
+ integer objnum; /* object number */
+ char **glyph_names;
+ integer tounicode; /* object number of associated ToUnicode entry */
+} enc_entry;
+
+struct _subfont_entry;
+typedef struct _subfont_entry subfont_entry;
+
+struct _subfont_entry {
+ char *infix; /* infix for this subfont, eg "01" */
+ long charcodes[256]; /* the mapping for this subfont as read from sfd */
+ subfont_entry *next;
+};
+
+typedef struct {
+ char *name; /* sfd name, eg "Unicode" */
+ subfont_entry *subfont; /* linked list of subfonts */
+} sfd_entry;
+
+typedef struct {
+ char *name; /* glyph name */
+ long code; /* -1 = undefined; -2 = multiple codes, stored
+ as string in unicode_seq; otherwise unicode value */
+ char *unicode_seq; /* multiple unicode sequence */
+} glyph_unicode_entry;
+
+typedef struct {
+ char *tfm_name; /* TFM file name */
+ char *ps_name; /* PostScript name */
+ integer flags; /* font flags */
+ char *ff_name; /* font file name */
+ char *subset_tag; /* pseudoUniqueTag for subsetted font */
+ enc_entry *encoding; /* pointer to corresponding encoding */
+ fontnumber tfm_num; /* number of the TFM refering this entry */
+ unsigned short type; /* font type (T1/TTF/...) */
+ short slant; /* SlantFont */
+ short extend; /* ExtendFont */
+ integer ff_objnum; /* FontFile object number */
+ integer fn_objnum; /* FontName/BaseName object number */
+ integer fd_objnum; /* FontDescriptor object number */
+ char *charset; /* string containing used glyphs */
+ boolean all_glyphs; /* embed all glyphs? */
+ unsigned short links; /* link flags from tfm_tree and ps_tree */
+ short tfm_avail; /* flags whether a tfm is available */
+ short pid; /* Pid for truetype fonts */
+ short eid; /* Eid for truetype fonts */
+ subfont_entry *subfont; /* subfont mapping */
+} fm_entry;
+
+typedef struct {
+ char *ff_name; /* base name of font file */
+ char *ff_path; /* full path to font file */
+} ff_entry;
+
+typedef short shalfword;
+typedef struct {
+ integer charcode, cwidth, cheight, xoff, yoff, xescape, rastersize;
+ halfword *raster;
+} chardesc;
+
+/* pdftexlib variable declarations */
+extern boolean fontfile_found;
+extern boolean is_otf_font;
+extern boolean true_dimen;
+extern boolean write_ttf_glyph_names;
+extern char **t1_glyph_names, *t1_builtin_glyph_names[];
+extern char *cur_file_name;
+extern const char notdef[];
+extern integer t1_length1, t1_length2, t1_length3;
+extern integer ttf_length;
+extern key_entry font_keys[];
+extern strnumber last_tex_string;
+extern size_t last_ptr_index;
+extern char fontname_buf[];
+
+/* pdftexlib function prototypes */
+
+/* epdf.c */
+extern integer get_fontfile_num (int);
+extern integer get_fontname_num (int);
+extern void epdf_free (void);
+extern int is_type1 (fm_entry *);
+
+/* mapfile.c */
+extern char *mk_basename (char *);
+extern char *mk_exname (char *, int);
+extern fm_entry *lookup_fontmap (char *);
+extern boolean hasfmentry (fontnumber);
+extern fontnumber tfmoffm (fmentryptr);
+extern void checkextfm (strnumber, integer);
+extern void fm_free (void);
+extern void fm_read_info (void);
+extern ff_entry *check_ff_exist (fm_entry *);
+extern void pdfmapfile (integer);
+extern void pdfmapline (integer);
+extern void pdfinitmapfile (string map_name);
+extern fm_entry *new_fm_entry (void);
+extern void delete_fm_entry (fm_entry *);
+extern int avl_do_entry (fm_entry *, int);
+
+/* papersiz.c */
+extern integer myatodim (char **);
+extern integer myatol (char **);
+
+/* pkin.c */
+extern int readchar (boolean, chardesc *);
+
+/* subfont.c */
+extern void sfd_free (void);
+extern boolean handle_subfont_fm (fm_entry *, int);
+
+/* tounicode.c */
+extern void glyph_unicode_free (void);
+extern void deftounicode (strnumber, strnumber);
+extern integer write_tounicode (char **, char *);
+
+/* utils.c */
+extern boolean str_eq_cstr (strnumber, char *);
+extern char *makecstring (integer);
+extern int xfflush (FILE *);
+extern int xgetc (FILE *);
+extern int xputc (int, FILE *);
+extern scaled extxnoverd (scaled, scaled, scaled);
+extern size_t xfwrite (void *, size_t size, size_t nmemb, FILE *);
+extern strnumber getresnameprefix (void);
+extern strnumber maketexstring (const char *);
+extern integer fb_offset (void);
+extern void fb_flush (void);
+extern void fb_putchar (eightbits b);
+extern void fb_seek (integer);
+extern void libpdffinish (void);
+extern char *makecfilename (strnumber s);
+extern void make_subset_tag (fm_entry *, char **, int);
+extern void pdf_printf (const char *, ...);
+extern void pdf_puts (const char *);
+extern void pdftex_fail (const char *, ...);
+extern void pdftex_warn (const char *, ...);
+extern void setjobid (int, int, int, int);
+extern void mp_printf (const char *, ...);
+extern void writestreamlength (integer, integer);
+extern char *convertStringToPDFString (const char *in, int len);
+extern void printID (strnumber);
+extern void printcreationdate ();
+extern void printmoddate ();
+extern void escapename (poolpointer in);
+extern void escapestring (poolpointer in);
+extern void escapehex (poolpointer in);
+extern void unescapehex (poolpointer in);
+extern void getcreationdate ();
+extern void getfilemoddate (strnumber s);
+extern void getfilesize (strnumber s);
+extern void getmd5sum (strnumber s, boolean file);
+extern void getfiledump (strnumber s, int offset, int length);
+extern void matchstrings (strnumber s, strnumber t, int subcount,
+ boolean icase);
+extern void getmatch (int i);
+extern void makepdftexbanner (void);
+extern void initstarttime ();
+extern void removepdffile (void);
+extern void garbagewarning (void);
+extern void stripspaces (char *p);
+extern void initversionstring (char **versions);
+extern int newcolorstack (integer s, integer literal_mode, boolean pagestart);
+extern int colorstackused ();
+extern integer colorstackset (int colstack_no, integer s);
+extern integer colorstackpush (int colstack_no, integer s);
+extern integer colorstackpop (int colstack_no);
+extern integer colorstackcurrent (int colstack_no);
+extern integer colorstackskippagestart (int colstack_no);
+extern void checkpdfsave (int cur_h, int cur_v);
+extern void checkpdfrestore (int cur_h, int cur_v);
+extern void pdfshipoutbegin (boolean shipping_page);
+extern void pdfshipoutend (boolean shipping_page);
+extern void pdfsetmatrix (poolpointer in, scaled cur_h, scaled cur_v);
+extern void matrixtransformpoint (scaled x, scaled y);
+extern void matrixtransformrect (scaled llx, scaled lly, scaled urx,
+ scaled ury);
+extern boolean matrixused ();
+extern void matrixrecalculate (scaled urx);
+extern scaled getllx ();
+extern scaled getlly ();
+extern scaled geturx ();
+extern scaled getury ();
+
+/* vfpacket.c */
+extern eightbits packetbyte (void);
+extern integer newvfpacket (fontnumber);
+extern void poppacketstate (void);
+extern void pushpacketstate (void);
+extern void startpacket (fontnumber, integer);
+extern void storepacket (integer, integer, integer);
+extern void vf_free (void);
+
+/* writeenc.c */
+extern boolean indexed_enc (fm_entry *);
+extern enc_entry *add_enc (char *);
+extern void enc_free (void);
+extern void read_enc (enc_entry *);
+extern void write_enc (char **, enc_entry *, integer);
+
+/* writefont.c */
+extern boolean dopsfont (fontnumber);
+
+/* writeimg.c */
+extern boolean checkimageb (integer);
+extern boolean checkimagec (integer);
+extern boolean checkimagei (integer);
+extern boolean ispdfimage (integer);
+extern integer epdforigx (integer);
+extern integer epdforigy (integer);
+extern integer imageheight (integer);
+extern integer imagepages (integer);
+extern integer imagewidth (integer);
+extern integer imagexres (integer);
+extern integer imageyres (integer);
+extern integer readimage (strnumber, integer, strnumber, integer, integer,
+ integer, integer);
+extern void deleteimage (integer);
+extern void img_free (void);
+extern void updateimageprocset (integer);
+extern void writeimage (integer);
+extern integer imagecolordepth (integer img);
+
+/* writejbig2.c */
+extern void flushjbig2page0objects ();
+
+/* writet1.c */
+extern boolean t1_subset (char *, char *, unsigned char *);
+extern void load_enc (char *, char **, char **);
+extern void writet1 (int, fm_entry *);
+extern void t1_free (void);
+
+#define bitfile psfile
+
+/* writet3.c */
+extern void writet3 (int, fontnumber);
+extern scaled getpkcharwidth (fontnumber, scaled);
+
+/* writettf.c */
+extern void writettf (void);
+extern void writeotf (void);
+extern void ttf_free (void);
+
+/* writezip.c */
+extern void writezip (boolean);
+
+/* avlstuff.c */
+extern void avlputobj (integer, integer);
+extern integer avlfindobj (integer, integer, integer);
+
+#endif /* MPOSTLIB */
diff --git a/Build/source/texk/web2c/mpdir/mpmac.h b/Build/source/texk/web2c/mpdir/mpmac.h
new file mode 100644
index 00000000000..bc9e6a79640
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/mpmac.h
@@ -0,0 +1,218 @@
+/*
+Copyright (c) 2006 Taco Hoekwater <taco@elvenkind.com>
+
+This file is part of MetaPost.
+
+MetaPost is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+MetaPost is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with MetaPost; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id $
+*/
+
+#ifndef MPOSTMAC
+# define MPOSTMAC
+
+/* Not all systems define it. */
+# ifndef M_PI
+# define M_PI 3.14159265358979323846
+ /* pi */
+# define M_PI_2 1.5707963267948966192E0
+ /*Hex 2^ 0 * 1.921FB54442D18 */
+# define M_PI_4 7.8539816339744830962E-1
+ /*Hex 2^-1 * 1.921FB54442D18 */
+# endif
+
+# ifdef WIN32
+// Why relying on gmalloc() ???
+# define gmalloc(n) xmalloc(n)
+# define gfree(p) free(p)
+# define inline __inline
+# define srandom(n) srand(n)
+# define random() rand()
+# endif
+
+/* Pascal WEB macros */
+# define maxinteger 0x7FFFFFFF
+# define maxdimen 0x3FFFFFFF
+
+# define objinfo(n) objtab[n].int0
+
+# define pdfroom(n) do { \
+ if ((unsigned)(n + pdfptr) > (unsigned)pdfbufsize) { \
+ if (pdfosmode) \
+ zpdfosgetosbuf(n); \
+ else { \
+ if ((unsigned)(n) > (unsigned)pdfbufsize) \
+ pdftex_fail("PDF output buffer overflowed"); \
+ else \
+ pdfflush(); \
+ } \
+ } \
+} while (0)
+
+# define pdfout(c) do { \
+ pdfroom(1); \
+ pdfbuf[pdfptr++] = c; \
+} while (0)
+
+# define pdfoffset() (pdfgone + pdfptr)
+# define pdfinitfont(f) {tmpf = f; pdfcreatefontobj();}
+
+# define MAX_CHAR_CODE 255
+# define PRINTF_BUF_SIZE 1024
+# define MAX_CSTRING_LEN 1024 * 1024
+# define MAX_PSTRING_LEN 1024
+# define SMALL_BUF_SIZE 256
+# define SMALL_ARRAY_SIZE 256
+# define FONTNAME_BUF_SIZE 128
+ /* a PDF name can be maximum 127 chars long */
+
+# define pdftex_debug tex_printf
+
+# define check_buf(size, buf_size) \
+ if ((unsigned)(size) > (unsigned)(buf_size)) \
+ pdftex_fail("buffer overflow: (%d,%d) at file %s, line %d",size,buf_size, __FILE__, __LINE__ )
+
+# define append_char_to_buf(c, p, buf, buf_size) do { \
+ if (c == 9) \
+ c = 32; \
+ if (c == 13 || c == EOF) \
+ c = 10; \
+ if (c != ' ' || (p > buf && p[-1] != 32)) { \
+ check_buf(p - buf + 1, (buf_size)); \
+ *p++ = c; \
+ } \
+} while (0)
+
+# define append_eol(p, buf, buf_size) do { \
+ check_buf(p - buf + 2, (buf_size)); \
+ if (p - buf > 1 && p[-1] != 10) \
+ *p++ = 10; \
+ if (p - buf > 2 && p[-2] == 32) { \
+ p[-2] = 10; \
+ p--; \
+ } \
+ *p = 0; \
+} while (0)
+
+# define remove_eol(p, buf) do { \
+ p = strend(buf) - 1; \
+ if (*p == 10) \
+ *p = 0; \
+} while (0)
+
+# define skip(p, c) if (*p == c) p++
+
+# define alloc_array(T, n, s) do { \
+ if (T##_array == NULL) { \
+ T##_limit = (s); \
+ if ((unsigned)(n) > T##_limit) \
+ T##_limit = (n); \
+ T##_array = xtalloc(T##_limit, T##_entry); \
+ T##_ptr = T##_array; \
+ } \
+ else if ((unsigned)(T##_ptr - T##_array + (n)) > T##_limit) { \
+ last_ptr_index = T##_ptr - T##_array; \
+ T##_limit *= 2; \
+ if ((unsigned)(T##_ptr - T##_array + (n)) > T##_limit) \
+ T##_limit = T##_ptr - T##_array + (n); \
+ xretalloc(T##_array, T##_limit, T##_entry); \
+ T##_ptr = T##_array + last_ptr_index; \
+ } \
+} while (0)
+
+# define is_cfg_comment(c) \
+ (c == 10 || c == '*' || c == '#' || c == ';' || c == '%')
+
+# define define_array(T) \
+T##_entry *T##_ptr, *T##_array = NULL; \
+size_t T##_limit
+
+# define xfree(p) do { if (p != NULL) free(p); p = NULL; } while (0)
+# define strend(s) strchr(s, 0)
+# define xtalloc XTALLOC
+# define xretalloc XRETALLOC
+
+# define ASCENT_CODE 0
+# define CAPHEIGHT_CODE 1
+# define DESCENT_CODE 2
+# define FONTNAME_CODE 3
+# define ITALIC_ANGLE_CODE 4
+# define STEMV_CODE 5
+# define XHEIGHT_CODE 6
+# define FONTBBOX1_CODE 7
+# define FONTBBOX2_CODE 8
+# define FONTBBOX3_CODE 9
+# define FONTBBOX4_CODE 10
+# define MAX_KEY_CODE (FONTBBOX1_CODE + 1)
+# define FONT_KEYS_NUM (FONTBBOX4_CODE + 1)
+
+# define F_INCLUDED 0x01
+# define F_SUBSETTED 0x02
+# define F_TRUETYPE 0x04
+# define F_BASEFONT 0x08
+# define F_SUBFONT 0x10
+
+# define set_included(fm) ((fm)->type |= F_INCLUDED)
+# define set_subsetted(fm) ((fm)->type |= F_SUBSETTED)
+# define set_truetype(fm) ((fm)->type |= F_TRUETYPE)
+# define set_basefont(fm) ((fm)->type |= F_BASEFONT)
+# define set_subfont(fm) ((fm)->type |= F_SUBFONT)
+
+# define unset_included(fm) ((fm)->type &= ~F_INCLUDED)
+# define unset_subsetted(fm) ((fm)->type &= ~F_SUBSETTED)
+# define unset_truetype(fm) ((fm)->type &= ~F_TRUETYPE)
+# define unset_basefont(fm) ((fm)->type &= ~F_BASEFONT)
+# define unset_subfont(fm) ((fm)->type &= ~F_SUBFONT)
+
+# define unset_fontfile(fm) xfree((fm)->ff_name)
+
+# define is_included(fm) ((fm)->type & F_INCLUDED)
+# define is_subsetted(fm) ((fm)->type & F_SUBSETTED)
+# define is_truetype(fm) ((fm)->type & F_TRUETYPE)
+# define is_basefont(fm) ((fm)->type & F_BASEFONT)
+# define is_subfont(fm) ((fm)->type & F_SUBFONT)
+# define no_font_desc(fm) (is_basefont(fm) && !is_included(fm))
+
+# define fm_slant(fm) (fm)->slant
+# define fm_extend(fm) (fm)->extend
+# define fm_fontfile(fm) (fm)->ff_name
+
+# define is_reencoded(fm) ((fm)->encoding != NULL)
+# define is_fontfile(fm) (fm_fontfile(fm) != NULL)
+# define is_t1fontfile(fm) (is_fontfile(fm) && !is_truetype(fm))
+
+# define LINK_TFM 0x01
+# define LINK_PS 0x02
+# define set_tfmlink(fm) ((fm)->links |= LINK_TFM)
+# define set_pslink(fm) ((fm)->links |= LINK_PS)
+# define unset_tfmlink(fm) ((fm)->links &= ~LINK_TFM)
+# define unset_pslink(fm) ((fm)->links &= ~LINK_PS)
+# define has_tfmlink(fm) ((fm)->links & LINK_TFM)
+# define has_pslink(fm) ((fm)->links & LINK_PS)
+
+
+# define set_cur_file_name(s) \
+ cur_file_name = s; \
+ packfilename(maketexstring(cur_file_name), getnullstr(), getnullstr())
+
+# define cmp_return(a, b) \
+ if (a > b) \
+ return 1; \
+ if (a < b) \
+ return -1
+
+# define str_prefix(s1, s2) (strncmp((s1), (s2), strlen(s2)) == 0)
+
+#endif /* MPOSTMAC */
diff --git a/Build/source/texk/web2c/mpdir/mpostlib.mk b/Build/source/texk/web2c/mpdir/mpostlib.mk
new file mode 100644
index 00000000000..01d798b60bb
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/mpostlib.mk
@@ -0,0 +1,29 @@
+## mpostlib.mk - Makefile fragment for libraries used by mpost
+# Public domain.
+
+# Include dependencies to get the built if we don't do make
+# from the top-level directory.
+
+Makefile: mpdir/mpostlib.mk
+
+# libmpost
+mpostlib = mpdir/libmpost.a
+mpostlib_sources = $(srcdir)/mpdir/*.c $(srcdir)/mpdir/*.h
+
+mpdir/libmpost.a: $(mpostlib_sources)
+ cd mpdir && $(MAKE) $(common_makeargs) libmpost.a
+
+# makecpool
+
+makecpool = mpdir/makecpool
+
+mpdir/makecpool: mpdir/makecpool.c
+ cd mpdir && $(MAKE) $(common_makeargs) makecpool
+
+# Convenience variables.
+
+mpostlibs = $(mpostlib)
+mpostlibsdep = $(mpostlib) $(makecpool)
+
+## end of mpostlib.mk - Makefile fragment for libraries used by mpost
+
diff --git a/Build/source/texk/web2c/mpdir/utils.c b/Build/source/texk/web2c/mpdir/utils.c
new file mode 100644
index 00000000000..16de3f5a8d3
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/utils.c
@@ -0,0 +1,719 @@
+/* Copyright (c) 2006 Taco Hoekwater <taco@elvenkind.com>
+
+This file is part of MetaPost.
+
+MetaPost is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+MetaPost is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with MetaPost; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id $
+*/
+
+#ifdef HAVE_ASPRINTF /* asprintf is not defined in openbsd-compat.h, but in stdio.h */
+# include <stdio.h>
+#endif
+#include <sys/types.h>
+
+#include <kpathsea/c-proto.h>
+#include <kpathsea/c-stat.h>
+#include <kpathsea/c-fopen.h>
+#include <string.h>
+#include <time.h>
+#include <float.h> /* for DBL_EPSILON */
+#include "mplib.h"
+
+/* define char_ptr, char_array & char_limit */
+typedef char char_entry;
+define_array (char);
+
+#define Z_NULL 0
+
+typedef unsigned char Byte;
+typedef Byte Bytef;
+
+#define check_nprintf(size_get, size_want) \
+ if ((unsigned)(size_get) >= (unsigned)(size_want)) \
+ pdftex_fail ("snprintf failed: file %s, line %d", __FILE__, __LINE__);
+
+/*@unused@*/
+static const char perforce_id[] =
+ "$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/utils.c#24 $";
+
+char *cur_file_name = NULL;
+strnumber last_tex_string;
+static char print_buf[PRINTF_BUF_SIZE];
+static char *jobname_cstr = NULL;
+static char *job_id_string = NULL;
+extern string ptexbanner; /* from web2c/lib/texmfmp.c */
+extern string versionstring; /* from web2c/lib/version.c */
+extern KPSEDLL string kpathsea_version_string; /* from kpathsea/version.c */
+
+size_t last_ptr_index; /* for use with alloc_array */
+
+
+
+void pdf_puts (const char *s)
+{
+ while (*s)
+ fputc(*s++,psfile);
+}
+
+void pdf_printf (const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ vsnprintf (print_buf, PRINTF_BUF_SIZE, fmt, args);
+ pdf_puts (print_buf);
+ va_end (args);
+}
+
+strnumber maketexstring (const char *s)
+{
+ size_t l;
+ if (s == NULL || *s == 0)
+ return getnullstr ();
+ l = strlen (s);
+ check_buf (poolptr + l, poolsize);
+ while (l-- > 0)
+ strpool[poolptr++] = *s++;
+ last_tex_string = makestring ();
+ return last_tex_string;
+}
+
+void mp_printf (const char *fmt, ...)
+{
+ va_list args;
+ int saved_selector;
+ saved_selector = selector;
+ va_start (args, fmt);
+ vsnprintf (print_buf, PRINTF_BUF_SIZE, fmt, args);
+ selector = gettermandlogid();
+ print (maketexstring (print_buf));
+ flushstr (last_tex_string);
+ xfflush (stdout);
+ va_end (args);
+ selector = saved_selector; /* ps_file_only, probably */
+}
+
+/* Helper for pdftex_fail. */
+static void safe_print (const char *str)
+{
+ const char *c;
+ for (c = str; *c; ++c)
+ print (*c);
+}
+
+/* pdftex_fail may be called when a buffer overflow has happened/is
+ happening, therefore may not call mktexstring. However, with the
+ current implementation it appears that error messages are misleading,
+ possibly because pool overflows are detected too late.
+
+ The output format of this fuction must be the same as pdf_error in
+ pdftex.web! */
+
+void pdftex_fail (const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ fputs ("\nError: module writet1", stderr);
+ if (cur_file_name)
+ fprintf (stderr, " (file %s)", cur_file_name);
+ fputs (": ", stderr);
+ vsprintf (print_buf, fmt, args);
+ fputs (print_buf, stderr);
+ fputs
+ ("\n ==> Fatal error occurred, the output PS file is not finished!\n",
+ stderr);
+ va_end (args);
+ exit (1);
+}
+
+/* The output format of this fuction must be the same as pdf_warn in
+ pdftex.web! */
+void pdftex_warn (const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ fputs ("\nWarning: module writet1", stderr);
+ if (cur_file_name)
+ fprintf (stderr, " (file %s)", cur_file_name);
+ fputs (": ", stderr);
+ vsprintf (print_buf, fmt, args);
+ fputs (print_buf, stderr);
+ fputs ("\n", stderr);
+ va_end (args);
+}
+
+
+static char *cstrbuf = NULL;
+
+char *makecstring (integer s)
+{
+ char *p;
+ static int allocsize;
+ int allocgrow, i, l ;
+ if (s==0)
+ return "";
+ l = strstart[nextstr[s]] - strstart[s];
+ if (l==0)
+ return "";
+ check_buf (l + 1, MAX_CSTRING_LEN);
+ if (cstrbuf == NULL) {
+ allocsize = l + 1;
+ cstrbuf = xmallocarray (char, allocsize);
+ } else if (l + 1 > allocsize) {
+ allocgrow = allocsize * 0.2;
+ if (l + 1 - allocgrow > allocsize)
+ allocsize = l + 1;
+ else if (allocsize < MAX_CSTRING_LEN - allocgrow)
+ allocsize += allocgrow;
+ else
+ allocsize = MAX_CSTRING_LEN;
+ cstrbuf = xrealloc (cstrbuf, sizeof (char) * allocsize);
+ }
+ p = cstrbuf;
+ for (i = 0; i < l; i++)
+ *p++ = strpool[i + strstart[s]];
+ *p = 0;
+ return cstrbuf;
+}
+
+size_t xfwrite (void *ptr, size_t size, size_t nmemb, FILE * stream)
+{
+ if (fwrite (ptr, size, nmemb, stream) != nmemb)
+ pdftex_fail ("fwrite() failed");
+ return nmemb;
+}
+
+int xfflush (FILE * stream)
+{
+ if (fflush (stream) != 0)
+ pdftex_fail ("fflush() failed");
+ return 0;
+}
+
+int xgetc (FILE * stream)
+{
+ int c = getc (stream);
+ if (c < 0 && c != EOF)
+ pdftex_fail ("getc() failed");
+ return c;
+}
+
+int xputc (int c, FILE * stream)
+{
+ int i = putc (c, stream);
+ if (i < 0)
+ pdftex_fail ("putc() failed");
+ return i;
+}
+
+
+scaled extxnoverd (scaled x, scaled n, scaled d)
+{
+ double r = (((double) x) * ((double) n)) / ((double) d);
+ if (r > DBL_EPSILON)
+ r += 0.5;
+ else
+ r -= 0.5;
+ if (r >= (double) maxinteger || r <= -(double) maxinteger)
+ pdftex_warn ("arithmetic: number too big");
+ return (scaled) r;
+}
+
+/* Converts any string given in in in an allowed PDF string which can be
+ * handled by printf et.al.: \ is escaped to \\, parenthesis are escaped and
+ * control characters are octal encoded.
+ * This assumes that the string does not contain any already escaped
+ * characters!
+ */
+char *convertStringToPDFString (const char *in, int len)
+{
+ static char pstrbuf[MAX_PSTRING_LEN];
+ char *out = pstrbuf;
+ int i, j = 0, k;
+ char buf[5];
+ for (i = 0; i < len; i++) {
+ check_buf (j + sizeof (buf), MAX_PSTRING_LEN);
+ if (((unsigned char) in[i] < '!') || ((unsigned char) in[i] > '~')) {
+ /* convert control characters into oct */
+ k = snprintf (buf, sizeof (buf),
+ "\\%03o", (unsigned int) (unsigned char) in[i]);
+ check_nprintf (k, sizeof (buf));
+ out[j++] = buf[0];
+ out[j++] = buf[1];
+ out[j++] = buf[2];
+ out[j++] = buf[3];
+ } else if ((in[i] == '(') || (in[i] == ')')) {
+ /* escape paranthesis */
+ out[j++] = '\\';
+ out[j++] = in[i];
+ } else if (in[i] == '\\') {
+ /* escape backslash */
+ out[j++] = '\\';
+ out[j++] = '\\';
+ } else {
+ /* copy char :-) */
+ out[j++] = in[i];
+ }
+ }
+ out[j] = '\0';
+ return pstrbuf;
+}
+
+
+/* Converts any string given in in in an allowed PDF string which can be
+ * handled by printf et.al.: \ is escaped to \\, parenthesis are escaped and
+ * control characters are octal encoded.
+ * This assumes that the string does not contain any already escaped
+ * characters!
+ *
+ * See escapename for parameter description.
+ */
+void escapestring (poolpointer in)
+{
+ const poolpointer out = poolptr;
+ unsigned char ch;
+ while (in < out) {
+ if (poolptr + 4 >= poolsize) {
+ poolptr = poolsize;
+ /* error by str_toks that calls str_room(1) */
+ return;
+ }
+
+ ch = (unsigned char) strpool[in++];
+
+ if ((ch < '!') || (ch > '~')) {
+ /* convert control characters into oct */
+ int i = snprintf ((char *) &strpool[poolptr], 5,
+ "\\%.3o", (unsigned int) ch);
+ check_nprintf (i, 5);
+ poolptr += i;
+ continue;
+ }
+ if ((ch == '(') || (ch == ')') || (ch == '\\')) {
+ /* escape parenthesis and backslash */
+ strpool[poolptr++] = '\\';
+ }
+ /* copy char :-) */
+ strpool[poolptr++] = ch;
+ }
+}
+
+/* Convert any given string in a PDF name using escaping mechanism
+ of PDF 1.2. The result does not include the leading slash.
+
+ PDF specification 1.6, section 3.2.6 "Name Objects" explains:
+ <blockquote>
+ Beginning with PDF 1.2, any character except null (character code 0) may
+ be included in a name by writing its 2-digit hexadecimal code, preceded
+ by the number sign character (#); see implementation notes 3 and 4 in
+ Appendix H. This syntax is required to represent any of the delimiter or
+ white-space characters or the number sign character itself; it is
+ recommended but not required for characters whose codes are outside the
+ range 33 (!) to 126 (~).
+ </blockquote>
+ The following table shows the conversion that are done by this
+ function:
+ code result reason
+ -----------------------------------
+ 0 ignored not allowed
+ 1..32 escaped must for white-space:
+ 9 (tab), 10 (lf), 12 (ff), 13 (cr), 32 (space)
+ recommended for the other control characters
+ 35 escaped escape char "#"
+ 37 escaped delimiter "%"
+ 40..41 escaped delimiters "(" and ")"
+ 47 escaped delimiter "/"
+ 60 escaped delimiter "<"
+ 62 escaped delimiter ">"
+ 91 escaped delimiter "["
+ 93 escaped delimiter "]"
+ 123 escaped delimiter "{"
+ 125 escaped delimiter "}"
+ 127..255 escaped recommended
+ else copy regular characters
+
+ Parameter "in" is a pointer into the string pool where
+ the input string is located. The output string is written
+ as temporary string right after the input string.
+ Thus at the begin of the procedure the global variable
+ "poolptr" points to the start of the output string and
+ after the end when the procedure returns.
+*/
+void escapename (poolpointer in)
+{
+ const poolpointer out = poolptr;
+ unsigned char ch;
+ int i;
+
+ while (in < out) {
+ if (poolptr + 3 >= poolsize) {
+ poolptr = poolsize;
+ /* error by str_toks that calls str_room(1) */
+ return;
+ }
+
+ ch = (unsigned char) strpool[in++];
+
+ if ((ch >= 1 && ch <= 32) || ch >= 127) {
+ /* escape */
+ i = snprintf ((char *) &strpool[poolptr], 4,
+ "#%.2X", (unsigned int) ch);
+ check_nprintf (i, 4);
+ poolptr += i;
+ continue;
+ }
+ switch (ch) {
+ case 0:
+ /* ignore */
+ break;
+ case 35:
+ case 37:
+ case 40:
+ case 41:
+ case 47:
+ case 60:
+ case 62:
+ case 91:
+ case 93:
+ case 123:
+ case 125:
+ /* escape */
+ i = snprintf ((char *) &strpool[poolptr], 4,
+ "#%.2X", (unsigned int) ch);
+ check_nprintf (i, 4);
+ poolptr += i;
+ break;
+ default:
+ /* copy */
+ strpool[poolptr++] = ch;
+ }
+ }
+}
+
+/* Convert any given string in a PDF hexadecimal string. The
+ result does not include the angle brackets.
+
+ This procedure uses uppercase hexadecimal letters.
+
+ See escapename for description of parameters.
+*/
+void escapehex (poolpointer in)
+{
+ const poolpointer out = poolptr;
+ unsigned char ch;
+ int i;
+
+ while (in < out) {
+ if (poolptr + 2 >= poolsize) {
+ poolptr = poolsize;
+ /* error by str_toks that calls str_room(1) */
+ return;
+ }
+
+ ch = (unsigned char) strpool[in++];
+
+ i = snprintf ((char *) &strpool[poolptr], 3, "%.2X", (unsigned int) ch);
+ check_nprintf (i, 3);
+ poolptr += 2;
+ }
+}
+
+/* Unescape any given hexadecimal string.
+
+ Last hex digit can be omitted, it is replaced by zero, see
+ PDF specification.
+
+ Invalid digits are silently ignored.
+
+ See escapename for description of parameters.
+*/
+void unescapehex (poolpointer in)
+{
+ const poolpointer out = poolptr;
+ unsigned char ch;
+ unsigned char a = 0; /* to avoid warning about uninitialized use of a */
+ boolean first = true;
+
+ while (in < out) {
+ if (poolptr + 1 >= poolsize) {
+ poolptr = poolsize;
+ /* error by str_toks that calls str_room(1) */
+ return;
+ }
+
+ ch = (unsigned char) strpool[in++];
+
+ if ((ch >= '0') && (ch <= '9')) {
+ ch -= '0';
+ } else if ((ch >= 'A') && (ch <= 'F')) {
+ ch -= 'A' - 10;
+ } else if ((ch >= 'a') && (ch <= 'f')) {
+ ch -= 'a' - 10;
+ } else {
+ continue; /* ignore wrong character */
+ }
+
+ if (first) {
+ a = ch << 4;
+ first = false;
+ continue;
+ }
+
+ strpool[poolptr++] = a + ch;
+ first = true;
+ }
+ if (!first) { /* last hex digit is omitted */
+ strpool[poolptr++] = ch << 4;
+ }
+}
+
+
+/* Converts any string given in in in an allowed PDF string which is
+ * hexadecimal encoded;
+ * sizeof(out) should be at least lin*2+1.
+ */
+static void convertStringToHexString (const char *in, char *out, int lin)
+{
+ int i, j, k;
+ char buf[3];
+ j = 0;
+ for (i = 0; i < lin; i++) {
+ k = snprintf (buf, sizeof (buf),
+ "%02X", (unsigned int) (unsigned char) in[i]);
+ check_nprintf (k, sizeof (buf));
+ out[j++] = buf[0];
+ out[j++] = buf[1];
+ }
+ out[j] = '\0';
+}
+
+
+
+/* makecfilename
+ input/ouput same as makecstring:
+ input: string number
+ output: C string with quotes removed.
+ That means, file names that are legal on some operation systems
+ cannot any more be used since pdfTeX version 1.30.4.
+*/
+char *makecfilename (strnumber s)
+{
+ char *name = makecstring (s);
+ char *p = name;
+ char *q = name;
+
+ while (*p) {
+ if (*p != '"')
+ *q++ = *p;
+ p++;
+ }
+ *q = '\0';
+ return name;
+}
+
+/* function strips trailing zeros in string with numbers; */
+/* leading zeros are not stripped (as in real life) */
+char *stripzeros (char *a)
+{
+ enum { NONUM, DOTNONUM, INT, DOT, LEADDOT, FRAC } s = NONUM, t = NONUM;
+ char *p, *q, *r;
+ for (p = q = r = a; *p != '\0';) {
+ switch (s) {
+ case NONUM:
+ if (*p >= '0' && *p <= '9')
+ s = INT;
+ else if (*p == '.')
+ s = LEADDOT;
+ break;
+ case DOTNONUM:
+ if (*p != '.' && (*p < '0' || *p > '9'))
+ s = NONUM;
+ break;
+ case INT:
+ if (*p == '.')
+ s = DOT;
+ else if (*p < '0' || *p > '9')
+ s = NONUM;
+ break;
+ case DOT:
+ case LEADDOT:
+ if (*p >= '0' && *p <= '9')
+ s = FRAC;
+ else if (*p == '.')
+ s = DOTNONUM;
+ else
+ s = NONUM;
+ break;
+ case FRAC:
+ if (*p == '.')
+ s = DOTNONUM;
+ else if (*p < '0' || *p > '9')
+ s = NONUM;
+ break;
+ default:;
+ }
+ switch (s) {
+ case DOT:
+ r = q;
+ break;
+ case LEADDOT:
+ r = q + 1;
+ break;
+ case FRAC:
+ if (*p > '0')
+ r = q + 1;
+ break;
+ case NONUM:
+ if ((t == FRAC || t == DOT) && r != a) {
+ q = r--;
+ if (*r == '.') /* was a LEADDOT */
+ *r = '0';
+ r = a;
+ }
+ break;
+ default:;
+ }
+ *q++ = *p++;
+ t = s;
+ }
+ *q = '\0';
+ return a;
+}
+
+void stripspaces (char *p)
+{
+ char *q;
+ for (q = p; *p != '\0'; p++) {
+ if (*p != ' ')
+ *q++ = *p;
+ }
+ *q = '\0';
+}
+
+void initversionstring (char **versions)
+{
+}
+
+void setjobid (int year, int month, int day, int time)
+{
+ char *name_string, *format_string, *s;
+ size_t slen;
+ int i;
+
+ if (job_id_string != NULL)
+ return;
+
+ name_string = xstrdup (makecstring (jobname));
+ format_string = xstrdup (makecstring (memident));
+
+ slen = SMALL_BUF_SIZE +
+ strlen (name_string) +
+ strlen (format_string) +
+ //strlen (banner) +
+ strlen (versionstring) + strlen (kpathsea_version_string);
+ s = xtalloc (slen, char);
+ /* The Web2c version string starts with a space. */
+ i = snprintf (s, slen,
+ "%.4d/%.2d/%.2d %.2d:%.2d %s %s%s %s",
+ (year>>16), (month>>16), (day>>16), (time>>16) / 60, (time>>16) % 60,
+ name_string, format_string, //ptexbanner,
+ versionstring, kpathsea_version_string);
+ check_nprintf (i, slen);
+ job_id_string = xstrdup (s);
+ xfree (s);
+ xfree (name_string);
+ xfree (format_string);
+}
+
+
+
+static void fnstr_append (const char *s)
+{
+ size_t l = strlen (s) + 1;
+ alloc_array (char, l, SMALL_ARRAY_SIZE);
+ strcat (char_ptr, s);
+ char_ptr = strend (char_ptr);
+}
+
+/* this is not really a true crc32, but it should be just enough to keep
+ subsets prefixes somewhat disjunct */
+unsigned long crc32 (int oldcrc, const Byte *buf, int len) {
+ unsigned long ret;
+ int i;
+ if (oldcrc==0)
+ ret = (23<<24)+(45<<16)+(67<<8)+89;
+ else
+ for (i=0;i<len;i++)
+ ret = (ret<<2)+buf[i];
+ return ret;
+}
+
+void make_subset_tag (fm_entry * fm_cur, char **glyph_names, int tex_font)
+{
+ char tag[7];
+ unsigned long crc;
+ int i;
+ size_t l ;
+ if (job_id_string ==NULL)
+ exit;
+ l = strlen (job_id_string) + 1;
+
+ alloc_array (char, l, SMALL_ARRAY_SIZE);
+ strcpy (char_array, job_id_string);
+ char_ptr = strend (char_array);
+ if (fm_cur->tfm_name != NULL) {
+ fnstr_append (" TFM name: ");
+ fnstr_append (fm_cur->tfm_name);
+ }
+ fnstr_append (" PS name: ");
+ //if (font_keys[FONTNAME_CODE].valid)
+ // fnstr_append (fontname_buf);
+ //else
+ if (fm_cur->ps_name != NULL)
+ fnstr_append (fm_cur->ps_name);
+ fnstr_append (" Encoding: ");
+ if (fm_cur->encoding != NULL && (fm_cur->encoding)->name != NULL)
+ fnstr_append ((fm_cur->encoding)->name);
+ else
+ fnstr_append ("built-in");
+ fnstr_append (" CharSet: ");
+ assert (glyph_names != NULL);
+ for (i = 0; i < 256; i++)
+ if (mpcharmarked (tex_font, i) && glyph_names[i] != notdef) {
+ if (glyph_names[i]!=NULL) {
+ fnstr_append ("/");
+ fnstr_append (glyph_names[i]);
+ }
+ }
+ if (fm_cur->charset != NULL) {
+ fnstr_append (" Extra CharSet: ");
+ fnstr_append (fm_cur->charset);
+ }
+ crc = crc32 (0L, Z_NULL, 0);
+ crc = crc32 (crc, (Bytef *) char_array, strlen (char_array));
+ /* we need to fit a 32-bit number into a string of 6 uppercase chars long;
+ * there are 26 uppercase chars ==> each char represents a number in range
+ * 0..25. The maximal number that can be represented by the tag is
+ * 26^6 - 1, which is a number between 2^28 and 2^29. Thus the bits 29..31
+ * of the CRC must be dropped out.
+ */
+ for (i = 0; i < 6; i++) {
+ tag[i] = 'A' + crc % 26;
+ crc /= 26;
+ }
+ tag[6] = 0;
+ fm_cur->subset_tag = xstrdup (tag);
+}
+
diff --git a/Build/source/texk/web2c/mpdir/writeenc.c b/Build/source/texk/web2c/mpdir/writeenc.c
new file mode 100644
index 00000000000..30673cd6aa3
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/writeenc.c
@@ -0,0 +1,142 @@
+/* Copyright (c) 2006 Taco Hoekwater <taco@elvenkind.com>
+
+This file is part of MetaPost.
+
+MetaPost is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+MetaPost is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with MetaPost; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id $
+*/
+
+#include "mplib.h"
+
+/*@unused@*/
+static const char perforce_id[] =
+ "$Id: writeenc.c,v 1.3 2005/12/26 14:20:13 hahe Exp hahe $";
+
+void read_enc (enc_entry * e)
+{
+ assert (e != NULL);
+ if (e->loaded)
+ return;
+ e->encname = NULL;
+ load_enc (e->name, &e->encname, e->glyph_names);
+ e->loaded = true;
+}
+
+/* write_enc is used to write either external encoding (given in map file) or
+ * internal encoding (read from the font file); when glyph_names is NULL
+ * the 2nd argument is a pointer to the encoding entry; otherwise the 3rd is
+ * the object number of the Encoding object
+ */
+void write_enc (char **glyph_names, enc_entry * e, integer eobjnum)
+{
+ boolean is_notdef;
+ int i;
+ int s;
+ int foffset;
+ char **g;
+ if (glyph_names == NULL) {
+ assert (e != NULL);
+ if (e->objnum != 0) /* the encoding has been written already */
+ return;
+ e->objnum = 1;
+ g = e->glyph_names;
+ } else {
+ g = glyph_names;
+ }
+ pdf_printf("\n%%%%BeginResource: encoding %s",e->encname);
+ pdf_printf ("\n/%s [ ", e->encname);
+ foffset = strlen(e->name)+3;
+ for (i = 0; i < 256; i++) {
+ s = strlen(g[i]);
+ if (s+1+foffset>=80) {
+ pdf_printf ("\n");
+ foffset = 0;
+ }
+ foffset += s+2;
+ pdf_printf ("/%s ", g[i]);
+ }
+ if (foffset>75)
+ pdf_printf ("\n");
+ pdf_puts ("] def\n");
+ pdf_printf("%%%%EndResource");
+}
+
+/**********************************************************************/
+/* All encoding entries go into AVL tree for fast search by name. */
+
+struct avl_table *enc_tree = NULL;
+
+/* AVL sort enc_entry into enc_tree by name */
+
+static int comp_enc_entry (const void *pa, const void *pb, void *p)
+{
+ return strcmp (((const enc_entry *) pa)->name,
+ ((const enc_entry *) pb)->name);
+}
+
+enc_entry *add_enc (char *s)
+{
+ int i;
+ enc_entry tmp, *p;
+ void **aa;
+
+ assert (s != NULL);
+ if (enc_tree == NULL) {
+ enc_tree = avl_create (comp_enc_entry, NULL, &avl_xallocator);
+ assert (enc_tree != NULL);
+ }
+ tmp.name = s;
+ p = (enc_entry *) avl_find (enc_tree, &tmp);
+ if (p != NULL) /* encoding already registered */
+ return p;
+ p = xtalloc (1, enc_entry);
+ p->loaded = false;
+ p->name = xstrdup (s);
+ p->objnum = 0;
+ p->tounicode = 0;
+ p->glyph_names = xtalloc (256, char *);
+ for (i = 0; i < 256; i++)
+ p->glyph_names[i] = (char *) notdef;
+ aa = avl_probe (enc_tree, p);
+ assert (aa != NULL);
+ return p;
+}
+
+/**********************************************************************/
+/* cleaning up... */
+
+static void destroy_enc_entry (void *pa, void *pb)
+{
+ enc_entry *p;
+ int i;
+
+ p = (enc_entry *) pa;
+ xfree (p->name);
+ if (p->glyph_names != NULL)
+ for (i = 0; i < 256; i++)
+ if (p->glyph_names[i] != notdef)
+ xfree (p->glyph_names[i]);
+ xfree (p->glyph_names);
+ xfree (p);
+}
+
+void enc_free ()
+{
+ if (enc_tree != NULL)
+ avl_destroy (enc_tree, destroy_enc_entry);
+}
+
+/**********************************************************************/
diff --git a/Build/source/texk/web2c/mpdir/writefont.c b/Build/source/texk/web2c/mpdir/writefont.c
new file mode 100644
index 00000000000..e88b4dbab7d
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/writefont.c
@@ -0,0 +1,244 @@
+/*
+Copyright (c) 1996-2006 Han The Thanh, <thanh@pdftex.org>
+
+This file is part of pdfTeX.
+
+pdfTeX is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+pdfTeX is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with pdfTeX; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id: writefont.c,v 1.3 2005/12/27 19:04:42 hahe Exp $
+*/
+
+#include "mplib.h"
+
+static const char perforce_id[] =
+ "$Id: writefont.c,v 1.3 2005/12/27 19:04:42 hahe Exp $";
+
+boolean fontfile_found;
+boolean is_otf_font;
+char fontname_buf[FONTNAME_BUF_SIZE];
+
+boolean fontisreencoded (int f) {
+ fm_entry *fm;
+ if (fontsizes[f]!=0 && hasfmentry (f)) {
+ fm = (fm_entry *) mpfontmap[f];
+ if (fm != NULL
+ && (fm->ps_name != NULL)
+ && is_reencoded (fm))
+ return 1;
+ }
+ return 0;
+}
+
+boolean fontisincluded (int f) {
+ fm_entry *fm;
+ if (fontsizes[f]!=0 && hasfmentry (f)) {
+ fm = (fm_entry *) mpfontmap[f];
+ if (fm != NULL
+ && (fm->ps_name != NULL && fm->ff_name != NULL)
+ && is_included (fm))
+ return 1;
+ }
+ return 0;
+}
+
+boolean fontissubsetted (int f) {
+ fm_entry *fm;
+ if (fontsizes[f]!=0 && hasfmentry (f)) {
+ fm = (fm_entry *) mpfontmap[f];
+ if (fm != NULL
+ && (fm->ps_name != NULL && fm->ff_name != NULL)
+ && is_included (fm) && is_subsetted (fm))
+ return 1;
+ }
+ return 0;
+}
+
+
+strnumber fmencodingname (int f) {
+ enc_entry *e;
+ fm_entry *fm;
+ if (hasfmentry (f)) {
+ fm = (fm_entry *) mpfontmap[f];
+ if (fm != NULL && (fm->ps_name != NULL)) {
+ if (is_reencoded (fm)) {
+ e = fm->encoding;
+ if (e->encname!=NULL) {
+ return maketexstring(e->encname);
+ }
+ } else {
+ return 0;
+ }
+ }
+ }
+ pdftex_fail ("fontmap encoding problems for font %s",makecstring (fontname[f]));
+ return 0;
+}
+
+strnumber fmfontname (int f) {
+ fm_entry *fm;
+ if (hasfmentry (f)) {
+ fm = (fm_entry *) mpfontmap[f];
+ if (fm != NULL && (fm->ps_name != NULL)) {
+ if (fontisincluded(f) && !fontpsnamefixed[f]) {
+ /* find the real fontname, and update ps_name and subset_tag if needed */
+ if(t1_updatefm(f,fm)) {
+ fontpsnamefixed[f] = true;
+ } else {
+ pdftex_fail ("font loading problems for font %s",makecstring (fontname[f]));
+ }
+ }
+ return maketexstring(fm->ps_name);
+ }
+ }
+ pdftex_fail ("fontmap name problems for font %s",makecstring (fontname[f]));
+ return 0;
+}
+
+strnumber fmfontsubsetname (int f) {
+ fm_entry *fm;
+ char *s;
+ if (hasfmentry (f)) {
+ fm = (fm_entry *) mpfontmap[f];
+ if (fm != NULL && (fm->ps_name != NULL)) {
+ if (is_subsetted(fm)) {
+ s = xmalloc(strlen(fm->ps_name)+8);
+ snprintf(s,strlen(fm->ps_name)+8,"%s-%s",fm->subset_tag,fm->ps_name);
+ return maketexstring(s);
+ } else {
+ return maketexstring(fm->ps_name);
+ }
+ }
+ }
+ pdftex_fail ("fontmap name problems for font %s",makecstring (fontname[f]));
+ return 0;
+}
+
+
+
+integer fmfontslant (int f) {
+ fm_entry *fm;
+ if (hasfmentry (f)) {
+ fm = (fm_entry *) mpfontmap[f];
+ if (fm != NULL && (fm->ps_name != NULL)) {
+ return fm->slant;
+ }
+ }
+ return 0;
+}
+
+integer fmfontextend (int f) {
+ fm_entry *fm;
+ if (hasfmentry (f)) {
+ fm = (fm_entry *) mpfontmap[f];
+ if (fm != NULL && (fm->ps_name != NULL)) {
+ return fm->extend;
+ }
+ }
+ return 0;
+}
+
+
+
+void mploadencodings (int lastfnum) {
+ int nullfont;
+ int f;
+ enc_entry *e;
+ fm_entry *fm_cur;
+ nullfont = getnullfont();
+ for (f=nullfont+1;f<=lastfnum;f++) {
+ if (fontsizes[f]!=0 && hasfmentry (f)) {
+ fm_cur = (fm_entry *) mpfontmap[f];
+ if (fm_cur != NULL &&
+ fm_cur->ps_name != NULL &&
+ is_reencoded (fm_cur)) {
+ e = fm_cur->encoding;
+ read_enc (e);
+ }
+ }
+ }
+}
+
+void mpfontencodings (int lastfnum, int encodings_only) {
+ int nullfont;
+ int f,ff;
+ enc_entry *e;
+ fm_entry *fm;
+ nullfont = getnullfont();
+ for (f=nullfont+1;f<=lastfnum;f++) {
+ if (fontsizes[f]!=0 && hasfmentry (f)) {
+ fm = (fm_entry *) mpfontmap[f];
+ if (fm != NULL && (fm->ps_name != NULL)) {
+ if (is_reencoded (fm)) {
+ if (encodings_only || (!is_subsetted (fm))) {
+ e = fm->encoding;
+ write_enc (NULL, e, 0);
+ }
+ }
+ }
+ }
+ }
+ for (f=nullfont+1;f<=lastfnum;f++) {
+ if (fontsizes[f]!=0 && hasfmentry (f)) {
+ fm = (fm_entry *) mpfontmap[f];
+ if (fm != NULL && (fm->ps_name != NULL)) {
+ if (is_reencoded (fm)) {
+ if (encodings_only || (!is_subsetted (fm))) {
+ /* clear for next run */
+ e->objnum = 0;
+ }
+ }
+ }
+ }
+ }
+}
+
+boolean dopsfont (fontnumber f)
+{
+ int i;
+ fm_entry *fm_cur;
+ if (mpfontmap[f] == NULL)
+ pdftex_fail ("pdffontmap not initialized for font %s",
+ makecstring (fontname[f]));
+ if (hasfmentry (f))
+ fm_cur = (fm_entry *) mpfontmap[f];
+ else
+ fm_cur = NULL;
+ if (fm_cur == NULL)
+ return 1;
+ if (is_truetype(fm_cur) ||
+ (fm_cur->ps_name == NULL && fm_cur->ff_name == NULL)) {
+ return 0;
+ }
+
+ if (is_included(fm_cur)) {
+ printnl(maketexstring("%%BeginResource: font "));
+ flushstr (last_tex_string);
+ if (is_subsetted(fm_cur)) {
+ print(maketexstring(fm_cur->subset_tag));
+ flushstr (last_tex_string);
+ print(maketexstring("-"));
+ flushstr (last_tex_string);
+ }
+ print(maketexstring(fm_cur->ps_name));
+ flushstr (last_tex_string);
+ println();
+ writet1 (f,fm_cur);
+ printnl(maketexstring("%%EndResource"));
+ flushstr (last_tex_string);
+ println();
+ }
+ return 1;
+}
+
diff --git a/Build/source/texk/web2c/mpdir/writet1.c b/Build/source/texk/web2c/mpdir/writet1.c
new file mode 100644
index 00000000000..bbfd398aa3b
--- /dev/null
+++ b/Build/source/texk/web2c/mpdir/writet1.c
@@ -0,0 +1,1736 @@
+/* Copyright (c) 2006 Taco Hoekwater <taco@elvenkind.com>
+
+This file is part of MetaPost.
+
+MetaPost is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+MetaPost is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with MetaPost; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id$
+
+*/
+
+static const char perforce_id[] =
+ "$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/writet1.c#25 $";
+
+# include "mplib.h"
+# define t1_open() \
+ open_input(&t1_file, kpse_type1_format, FOPEN_RBIN_MODE)
+# define enc_open() \
+ open_input(&enc_file, kpse_enc_format, FOPEN_RBIN_MODE)
+# define external_enc() (fm_cur->encoding)->glyph_names
+
+# define full_file_name() cur_file_name
+# define get_length1()
+# define get_length2()
+# define get_length3()
+# define is_used_char(c) mpcharmarked(tex_font, c)
+# define out_eexec_char t1_outhex
+# define save_offset()
+# define end_last_eexec_line() \
+ hexline_length = HEXLINE_WIDTH; \
+ end_hexline(); \
+ t1_eexec_encrypt = false
+# define t1_log(s) mp_printf(s)
+# define t1_putchar(c) fputc(c, bitfile)
+# define embed_all_glyphs(tex_font) false
+# undef pdfmovechars
+# ifdef SHIFTLOWCHARS
+extern char errbuf[];
+extern Boolean shiftlowchars;
+# define pdfmovechars shiftlowchars
+# define t1_char(c) T1Char(c)
+# else /* SHIFTLOWCHARS */
+# define t1_char(c) c
+# define pdfmovechars 0
+# endif /* SHIFTLOWCHARS */
+# define extra_charset() dvips_extra_charset
+# define update_subset_tag()
+
+# define fixedcontent true
+
+static char *dvips_extra_charset;
+static char *cur_enc_name;
+static unsigned char *grid;
+static char *ext_glyph_names[256];
+static char print_buf[PRINTF_BUF_SIZE];
+static int hexline_length;
+const char notdef[] = ".notdef";
+/* static size_t last_ptr_index; */
+
+#include <kpathsea/c-vararg.h>
+#include <kpathsea/c-proto.h>
+#include <string.h>
+
+#define t1_getchar() getc(t1_file)
+#define t1_ungetchar(c) ungetc(c, t1_file)
+#define t1_eof() feof(t1_file)
+#define t1_close() xfclose(t1_file, cur_file_name)
+
+#define enc_getchar() getc(enc_file)
+#define enc_eof() feof(enc_file)
+#define enc_close() xfclose(enc_file, cur_file_name)
+
+#define valid_code(c) (c >= 0 && c < 256)
+
+static const char *standard_glyph_names[256] =
+ { notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
+ notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
+ notdef, notdef, notdef, notdef, notdef, notdef,
+ notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
+ "space", "exclam", "quotedbl", "numbersign",
+ "dollar", "percent", "ampersand", "quoteright", "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",
+ "quoteleft", "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",
+ notdef, notdef, notdef, notdef, notdef, notdef, notdef,
+ notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
+ notdef, notdef, notdef, notdef, notdef, notdef,
+ notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
+ notdef, notdef, notdef, "exclamdown", "cent",
+ "sterling", "fraction", "yen", "florin", "section", "currency",
+ "quotesingle", "quotedblleft", "guillemotleft",
+ "guilsinglleft", "guilsinglright", "fi", "fl", notdef, "endash",
+ "dagger", "daggerdbl", "periodcentered", notdef,
+ "paragraph", "bullet", "quotesinglbase", "quotedblbase",
+ "quotedblright", "guillemotright", "ellipsis", "perthousand",
+ notdef, "questiondown", notdef, "grave", "acute", "circumflex",
+ "tilde", "macron", "breve", "dotaccent", "dieresis", notdef,
+ "ring", "cedilla", notdef, "hungarumlaut", "ogonek", "caron", "emdash",
+ notdef, notdef, notdef, notdef, notdef, notdef,
+ notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef, notdef,
+ notdef, "AE", notdef, "ordfeminine", notdef, notdef,
+ notdef, notdef, "Lslash", "Oslash", "OE", "ordmasculine", notdef,
+ notdef, notdef, notdef, notdef, "ae", notdef, notdef,
+ notdef, "dotlessi", notdef, notdef, "lslash", "oslash", "oe",
+ "germandbls", notdef, notdef, notdef, notdef
+};
+
+static char charstringname[] = "/CharStrings";
+
+char **t1_glyph_names;
+char *t1_builtin_glyph_names[256];
+char charsetstr[0x4000];
+static boolean read_encoding_only;
+static int t1_encoding;
+
+#define T1_BUF_SIZE 0x10
+#define ENC_BUF_SIZE 0x1000
+
+#define ENC_STANDARD 0
+#define ENC_BUILTIN 1
+
+#define CS_HSTEM 1
+#define CS_VSTEM 3
+#define CS_VMOVETO 4
+#define CS_RLINETO 5
+#define CS_HLINETO 6
+#define CS_VLINETO 7
+#define CS_RRCURVETO 8
+#define CS_CLOSEPATH 9
+#define CS_CALLSUBR 10
+#define CS_RETURN 11
+#define CS_ESCAPE 12
+#define CS_HSBW 13
+#define CS_ENDCHAR 14
+#define CS_RMOVETO 21
+#define CS_HMOVETO 22
+#define CS_VHCURVETO 30
+#define CS_HVCURVETO 31
+#define CS_1BYTE_MAX (CS_HVCURVETO + 1)
+
+#define CS_DOTSECTION CS_1BYTE_MAX + 0
+#define CS_VSTEM3 CS_1BYTE_MAX + 1
+#define CS_HSTEM3 CS_1BYTE_MAX + 2
+#define CS_SEAC CS_1BYTE_MAX + 6
+#define CS_SBW CS_1BYTE_MAX + 7
+#define CS_DIV CS_1BYTE_MAX + 12
+#define CS_CALLOTHERSUBR CS_1BYTE_MAX + 16
+#define CS_POP CS_1BYTE_MAX + 17
+#define CS_SETCURRENTPOINT CS_1BYTE_MAX + 33
+#define CS_2BYTE_MAX (CS_SETCURRENTPOINT + 1)
+#define CS_MAX CS_2BYTE_MAX
+
+typedef unsigned char byte;
+
+typedef struct {
+ byte nargs; /* number of arguments */
+ boolean bottom; /* take arguments from bottom of stack? */
+ boolean clear; /* clear stack? */
+ boolean valid;
+} cc_entry; /* CharString Command */
+
+typedef struct {
+ char *name; /* glyph name (or notdef for Subrs entry) */
+ byte *data;
+ unsigned short len; /* length of the whole string */
+ unsigned short cslen; /* length of the encoded part of the string */
+ boolean used;
+ boolean valid;
+} cs_entry;
+
+static unsigned short t1_dr, t1_er;
+static const unsigned short t1_c1 = 52845, t1_c2 = 22719;
+static unsigned short t1_cslen;
+static short t1_lenIV;
+static char enc_line[ENC_BUF_SIZE];
+
+/* define t1_line_ptr, t1_line_array & t1_line_limit */
+typedef char t1_line_entry;
+define_array (t1_line);
+
+/* define t1_buf_ptr, t1_buf_array & t1_buf_limit */
+typedef char t1_buf_entry;
+define_array (t1_buf);
+
+static int cs_start;
+
+static cs_entry *cs_tab, *cs_ptr, *cs_notdef;
+static char *cs_dict_start, *cs_dict_end;
+static int cs_count, cs_size, cs_size_pos;
+
+static cs_entry *subr_tab;
+static char *subr_array_start, *subr_array_end;
+static int subr_max, subr_size, subr_size_pos;
+
+/* This list contains the begin/end tokens commonly used in the */
+/* /Subrs array of a Type 1 font. */
+static const char *cs_token_pairs_list[][2] = {
+ {" RD", "NP"},
+ {" -|", "|"},
+ {" RD", "noaccess put"},
+ {" -|", "noaccess put"},
+ {NULL, NULL}
+};
+static const char **cs_token_pair;
+
+static boolean t1_pfa, t1_cs, t1_scan, t1_eexec_encrypt, t1_synthetic;
+static int t1_in_eexec; /* 0 before eexec-encrypted, 1 during, 2 after */
+static long t1_block_length;
+static int last_hexbyte;
+static FILE *t1_file;
+static FILE *enc_file;
+
+#define t1_prefix(s) str_prefix(t1_line_array, s)
+#define t1_buf_prefix(s) str_prefix(t1_buf_array, s)
+#define t1_suffix(s) str_suffix(t1_line_array, t1_line_ptr, s)
+#define t1_buf_suffix(s) str_suffix(t1_buf_array, t1_buf_ptr, s)
+#define t1_charstrings() strstr(t1_line_array, charstringname)
+#define t1_subrs() t1_prefix("/Subrs")
+#define t1_end_eexec() t1_suffix("mark currentfile closefile")
+#define t1_cleartomark() t1_prefix("cleartomark")
+
+
+#ifndef pdfTeX
+# define HEXLINE_WIDTH 64
+
+static void end_hexline ()
+{
+ if (hexline_length == HEXLINE_WIDTH) {
+ fputs ("\n", bitfile);
+ hexline_length = 0;
+ }
+}
+
+static void t1_outhex (byte b)
+{
+ static char *hexdigits = "0123456789ABCDEF";
+ t1_putchar (hexdigits[b / 16]);
+ t1_putchar (hexdigits[b % 16]);
+ hexline_length += 2;
+ end_hexline ();
+}
+#endif /* pdfTeX */
+
+
+static void enc_getline (void)
+{
+ char *p;
+ int c;
+ restart:
+ if (enc_eof ())
+ pdftex_fail ("unexpected end of file");
+ p = enc_line;
+ do {
+ c = enc_getchar ();
+ append_char_to_buf (c, p, enc_line, ENC_BUF_SIZE);
+ }
+ while (c != 10);
+ append_eol (p, enc_line, ENC_BUF_SIZE);
+ if (p - enc_line < 2 || *enc_line == '%')
+ goto restart;
+}
+
+void load_enc (char *enc_name, char **enc_encname, char **glyph_names)
+{
+ char buf[ENC_BUF_SIZE], *p, *r;
+ int names_count;
+ char *myname;
+ set_cur_file_name (enc_name);
+ if (!enc_open ()) {
+ pdftex_warn ("cannot open encoding file for reading");
+ cur_file_name = NULL;
+ return;
+ }
+ t1_log ("{");
+ t1_log (cur_file_name = full_file_name ());
+ enc_getline ();
+ if (*enc_line != '/' || (r = strchr (enc_line, '[')) == NULL) {
+ remove_eol (r, enc_line);
+ pdftex_fail
+ ("invalid encoding vector (a name or `[' missing): `%s'", enc_line);
+ }
+ while (*(r-1)==' ') r--; /* strip trailing spaces from encoding name */
+ myname = xmalloc(r-enc_line);
+ memcpy(myname,enc_line+1,(r-enc_line)-1);
+ *(myname+(r-enc_line-1))=0;
+ *enc_encname = myname;
+ while (*r!='[') r++;
+ r++; /* skip '[' */
+ names_count = 0;
+ skip (r, ' ');
+ for (;;) {
+ while (*r == '/') {
+ for (p = buf, r++;
+ *r != ' ' && *r != 10 && *r != ']' && *r != '/'; *p++ = *r++);
+ *p = 0;
+ skip (r, ' ');
+ if (names_count > 256)
+ pdftex_fail ("encoding vector contains more than 256 names");
+ if (strcmp (buf, notdef) != 0)
+ glyph_names[names_count] = xstrdup (buf);
+ names_count++;
+ }
+ if (*r != 10 && *r != '%') {
+ if (str_prefix (r, "] def"))
+ goto done;
+ else {
+ remove_eol (r, enc_line);
+ pdftex_fail
+ ("invalid encoding vector: a name or `] def' expected: `%s'",
+ enc_line);
+ }
+ }
+ enc_getline ();
+ r = enc_line;
+ }
+ done:
+ enc_close ();
+ t1_log ("}");
+ cur_file_name = NULL;
+}
+
+static void t1_check_pfa (void)
+{
+ const int c = t1_getchar ();
+ t1_pfa = (c != 128) ? true : false;
+ t1_ungetchar (c);
+}
+
+static int t1_getbyte (void)
+{
+ int c = t1_getchar ();
+ if (t1_pfa)
+ return c;
+ if (t1_block_length == 0) {
+ if (c != 128)
+ pdftex_fail ("invalid marker");
+ c = t1_getchar ();
+ if (c == 3) {
+ while (!t1_eof ())
+ t1_getchar ();
+ return EOF;
+ }
+ t1_block_length = t1_getchar () & 0xff;
+ t1_block_length |= (t1_getchar () & 0xff) << 8;
+ t1_block_length |= (t1_getchar () & 0xff) << 16;
+ t1_block_length |= (t1_getchar () & 0xff) << 24;
+ c = t1_getchar ();
+ }
+ t1_block_length--;
+ return c;
+}
+
+static int hexval (int c)
+{
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ else if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+ else if (c >= '0' && c <= '9')
+ return c - '0';
+ else
+ return -1;
+}
+
+static byte edecrypt (byte cipher)
+{
+ byte plain;
+ if (t1_pfa) {
+ while (cipher == 10 || cipher == 13)
+ cipher = t1_getbyte ();
+ last_hexbyte = cipher = (hexval (cipher) << 4) + hexval (t1_getbyte ());
+ }
+ plain = (cipher ^ (t1_dr >> 8));
+ t1_dr = (cipher + t1_dr) * t1_c1 + t1_c2;
+ return plain;
+}
+
+static byte cdecrypt (byte cipher, unsigned short *cr)
+{
+ const byte plain = (cipher ^ (*cr >> 8));
+ *cr = (cipher + *cr) * t1_c1 + t1_c2;
+ return plain;
+}
+
+static byte eencrypt (byte plain)
+{
+ const byte cipher = (plain ^ (t1_er >> 8));
+ t1_er = (cipher + t1_er) * t1_c1 + t1_c2;
+ return cipher;
+}
+
+static byte cencrypt (byte plain, unsigned short *cr)
+{
+ const byte cipher = (plain ^ (*cr >> 8));
+ *cr = (cipher + *cr) * t1_c1 + t1_c2;
+ return cipher;
+}
+
+static char *eol (char *s)
+{
+ char *p = strend (s);
+ if (p - s > 1 && p[-1] != 10) {
+ *p++ = 10;
+ *p = 0;
+ }
+ return p;
+}
+
+static float t1_scan_num (char *p, char **r)
+{
+ float f;
+ skip (p, ' ');
+ if (sscanf (p, "%g", &f) != 1) {
+ remove_eol (p, t1_line_array);
+ pdftex_fail ("a number expected: `%s'", t1_line_array);
+ }
+ if (r != NULL) {
+ for (; isdigit (*p) || *p == '.' ||
+ *p == 'e' || *p == 'E' || *p == '+' || *p == '-'; p++);
+ *r = p;
+ }
+ return f;
+}
+
+static boolean str_suffix (const char *begin_buf, const char *end_buf,
+ const char *s)
+{
+ const char *s1 = end_buf - 1, *s2 = strend (s) - 1;
+ if (*s1 == 10)
+ s1--;
+ while (s1 >= begin_buf && s2 >= s) {
+ if (*s1-- != *s2--)
+ return false;
+ }
+ return s2 < s;
+}
+
+static void t1_getline (void)
+{
+ int c, l, eexec_scan;
+ char *p;
+ static const char eexec_str[] = "currentfile eexec";
+ static int eexec_len = 17; /* strlen(eexec_str) */
+ restart:
+ if (t1_eof ())
+ pdftex_fail ("unexpected end of file");
+ t1_line_ptr = t1_line_array;
+ alloc_array (t1_line, 1, T1_BUF_SIZE);
+ t1_cslen = 0;
+ eexec_scan = 0;
+ c = t1_getbyte ();
+ if (c == EOF)
+ goto exit;
+ while (!t1_eof ()) {
+ if (t1_in_eexec == 1)
+ c = edecrypt (c);
+ alloc_array (t1_line, 1, T1_BUF_SIZE);
+ append_char_to_buf (c, t1_line_ptr, t1_line_array, t1_line_limit);
+ if (t1_in_eexec == 0 && eexec_scan >= 0 && eexec_scan < eexec_len) {
+ if (t1_line_array[eexec_scan] == eexec_str[eexec_scan])
+ eexec_scan++;
+ else
+ eexec_scan = -1;
+ }
+ if (c == 10 || (t1_pfa && eexec_scan == eexec_len && c == 32))
+ break;
+ if (t1_cs && t1_cslen == 0 && (t1_line_ptr - t1_line_array > 4) &&
+ (t1_suffix (" RD ") || t1_suffix (" -| "))) {
+ p = t1_line_ptr - 5;
+ while (*p != ' ')
+ p--;
+ t1_cslen = l = t1_scan_num (p + 1, 0);
+ cs_start = t1_line_ptr - t1_line_array; /* cs_start is an index now */
+ alloc_array (t1_line, l, T1_BUF_SIZE);
+ while (l-- > 0)
+ *t1_line_ptr++ = edecrypt (t1_getbyte ());
+ }
+ c = t1_getbyte ();
+ }
+ alloc_array (t1_line, 2, T1_BUF_SIZE); /* append_eol can append 2 chars */
+ append_eol (t1_line_ptr, t1_line_array, t1_line_limit);
+ if (t1_line_ptr - t1_line_array < 2)
+ goto restart;
+ if (eexec_scan == eexec_len)
+ t1_in_eexec = 1;
+ exit:
+ /* ensure that t1_buf_array has as much room as t1_line_array */
+ t1_buf_ptr = t1_buf_array;
+ alloc_array (t1_buf, t1_line_limit, t1_line_limit);
+}
+
+static void t1_putline (void)
+{
+ char *p = t1_line_array;
+ if (t1_line_ptr - t1_line_array <= 1)
+ return;
+ if (t1_eexec_encrypt) {
+ while (p < t1_line_ptr)
+ out_eexec_char (eencrypt (*p++));
+ } else {
+ while (p < t1_line_ptr)
+ t1_putchar (*p++);
+ }
+}
+
+static void t1_puts (const char *s)
+{
+ if (s != t1_line_array)
+ strcpy (t1_line_array, s);
+ t1_line_ptr = strend (t1_line_array);
+ t1_putline ();
+}
+
+static void t1_printf (const char *fmt, ...)
+{
+ va_list args;
+ va_start (args, fmt);
+ vsprintf (t1_line_array, fmt, args);
+ t1_puts (t1_line_array);
+ va_end (args);
+}
+
+static void t1_init_params (const char *open_name_prefix)
+{
+ if ((open_name_prefix != NULL) && strlen(open_name_prefix)) {
+ t1_log (open_name_prefix);
+ t1_log (cur_file_name);
+ }
+ t1_lenIV = 4;
+ t1_dr = 55665;
+ t1_er = 55665;
+ t1_in_eexec = 0;
+ t1_cs = false;
+ t1_scan = true;
+ t1_synthetic = false;
+ t1_eexec_encrypt = false;
+ t1_block_length = 0;
+ t1_check_pfa ();
+}
+
+static void t1_close_font_file (const char *close_name_suffix)
+{
+ if ((close_name_suffix != NULL) && strlen(close_name_suffix)) {
+ t1_log (close_name_suffix);
+ }
+ t1_close ();
+ cur_file_name = NULL;
+}
+
+static void t1_check_block_len (boolean decrypt)
+{
+ int l, c;
+ if (t1_block_length == 0)
+ return;
+ c = t1_getbyte ();
+ if (decrypt)
+ c = edecrypt (c);
+ l = t1_block_length;
+ if (!(l == 0 && (c == 10 || c == 13))) {
+ pdftex_warn ("%i bytes more than expected were ignored", l + 1);
+ while (l-- > 0)
+ t1_getbyte ();
+ }
+}
+
+static void t1_start_eexec (fm_entry *fm_cur)
+{
+ int i;
+ if (is_included (fm_cur)) {
+ get_length1 ();
+ save_offset ();
+ }
+ if (!t1_pfa)
+ t1_check_block_len (false);
+ for (t1_line_ptr = t1_line_array, i = 0; i < 4; i++) {
+ edecrypt (t1_getbyte ());
+ *t1_line_ptr++ = 0;
+ }
+ t1_eexec_encrypt = true;
+ if (!read_encoding_only)
+ if (is_included (fm_cur))
+ t1_putline (); /* to put the first four bytes */
+}
+
+static void t1_stop_eexec (fm_entry *fm_cur)
+{
+ int c;
+ if (is_included (fm_cur)) {
+ get_length2 ();
+ save_offset ();
+ }
+ end_last_eexec_line ();
+ if (!t1_pfa)
+ t1_check_block_len (true);
+ else {
+ c = edecrypt (t1_getbyte ());
+ if (!(c == 10 || c == 13)) {
+ if (last_hexbyte == 0)
+ t1_puts ("00");
+ else
+ pdftex_warn ("unexpected data after eexec");
+ }
+ }
+ t1_cs = false;
+ t1_in_eexec = 2;
+}
+
+#ifdef pdfTeX
+/* macros for various transforms; currently only slant and extend are used */
+# define do_xshift(x,a) {x[4]+=a;}
+# define do_yshift(x,a) {x[5]+=a;}
+# define do_xscale(x,a) {x[0]*=a; x[2]*=a; x[4]*=a;}
+# define do_yscale(x,a) {x[1]*=a; x[3]*=a; x[5]*=a;}
+# define do_extend(x,a) {do_xscale(x,a);}
+# define do_scale(x,a) {do_xscale(x,a); do_yscale(x,a);}
+# define do_slant(x,a) {x[0]+=x[1]*(a); x[2]+=x[3]*(a); x[4]+=x[5]*(a);}
+# define do_shear(x,a) {x[1]+=x[0]*(a); x[3]+=x[2]*(a); x[5]+=x[4]*(a);}
+# define do_rotate(x,a) \
+ {float t, u=cos(a), v=sin(a); \
+ t =x[0]*u+x[1]*-v; \
+ x[1] =x[0]*v+x[1]* u; x[0]=t; \
+ t =x[2]*u+x[3]*-v; \
+ x[3] =x[2]*v+x[3]* u; x[2]=t; \
+ t =x[4]*u+x[5]*-v; \
+ x[5] =x[4]*v+x[5]* u; x[4]=t;}
+
+static void t1_modify_fm (void)
+{
+ /*
+ * font matrix is given as six numbers a0..a5, which stands for the matrix
+ *
+ * a0 a1 0
+ * M = a2 a3 0
+ * a4 a5 1
+ *
+ * ExtendFont is given as
+ *
+ * e 0 0
+ * E = 0 1 0
+ * 0 0 1
+ *
+ * SlantFont is given as
+ *
+ * 1 0 0
+ * S = s 1 0
+ * 0 0 1
+ *
+ * The slant transform must be done _before_ the extend transform
+ * for compatibility!
+ */
+ float a[6];
+ int i, c;
+ char *p, *q, *r;
+ if ((p = strchr (t1_line_array, '[')) == 0)
+ if ((p = strchr (t1_line_array, '{')) == 0) {
+ remove_eol (p, t1_line_array);
+ pdftex_fail ("FontMatrix: an array expected: `%s'", t1_line_array);
+ }
+ c = *p++; /* save the character '[' resp. '{' */
+ strncpy (t1_buf_array, t1_line_array, (size_t) (p - t1_line_array));
+ r = t1_buf_array + (p - t1_line_array);
+ for (i = 0; i < 6; i++) {
+ a[i] = t1_scan_num (p, &q);
+ p = q;
+ }
+ if (fm_slant (fm_cur) != 0)
+ do_slant (a, fm_slant (fm_cur) * 1E-3);
+ if (fm_extend (fm_cur) != 0)
+ do_extend (a, fm_extend (fm_cur) * 1E-3);
+ for (i = 0; i < 6; i++) {
+ sprintf (r, "%g ", a[i]);
+ r = strend (r);
+ }
+ if (c == '[') {
+ while (*p != ']' && *p != 0)
+ p++;
+ } else {
+ while (*p != '}' && *p != 0)
+ p++;
+ }
+ if (*p == 0) {
+ remove_eol (p, t1_line_array);
+ pdftex_fail
+ ("FontMatrix: cannot find the corresponding character to '%c': `%s'",
+ c, t1_line_array);
+ }
+ strcpy (r, p);
+ strcpy (t1_line_array, t1_buf_array);
+ t1_line_ptr = eol (t1_line_array);
+}
+
+static void t1_modify_italic (void)
+{
+ float a;
+ char *p, *r;
+ if (fm_slant (fm_cur) == 0)
+ return;
+ p = strchr (t1_line_array, ' ');
+ strncpy (t1_buf_array, t1_line_array, (size_t) (p - t1_line_array + 1));
+ a = t1_scan_num (p + 1, &r);
+ a -= atan (fm_slant (fm_cur) * 1E-3) * (180 / M_PI);
+ sprintf (t1_buf_array + (p - t1_line_array + 1), "%g", a);
+ strcpy (strend (t1_buf_array), r);
+ strcpy (t1_line_array, t1_buf_array);
+ t1_line_ptr = eol (t1_line_array);
+ font_keys[ITALIC_ANGLE_CODE].value = round (a);
+ font_keys[ITALIC_ANGLE_CODE].valid = true;
+}
+
+#else
+
+static void t1_modify_fm (void)
+{
+ // t1_line_ptr = eol (t1_line_array);
+}
+
+static void t1_modify_italic (void)
+{
+ // t1_line_ptr = eol (t1_line_array);
+}
+
+#endif /* pdfTeX */
+
+key_entry font_keys[FONT_KEYS_NUM] = {
+ {"Ascent", "Ascender", 0, false},
+ {"CapHeight", "CapHeight", 0, false},
+ {"Descent", "Descender", 0, false},
+ {"FontName", "FontName", 0, false},
+ {"ItalicAngle", "ItalicAngle", 0, false},
+ {"StemV", "StdVW", 0, false},
+ {"XHeight", "XHeight", 0, false},
+ {"FontBBox", "FontBBox", 0, false},
+ {"", "", 0, false},
+ {"", "", 0, false},
+ {"", "", 0, false}
+};
+
+
+static void t1_scan_keys (int tex_font,fm_entry *fm_cur)
+{
+ int i, k;
+ char *p, *q, *r;
+ key_entry *key;
+ if (fm_extend (fm_cur) != 0 || fm_slant (fm_cur) != 0) {
+ if (t1_prefix ("/FontMatrix")) {
+ t1_modify_fm ();
+ return;
+ }
+ if (t1_prefix ("/ItalicAngle")) {
+ t1_modify_italic ();
+ return;
+ }
+ }
+ if (t1_prefix ("/FontType")) {
+ p = t1_line_array + strlen ("FontType") + 1;
+ if ((i = t1_scan_num (p, 0)) != 1)
+ pdftex_fail ("Type%d fonts unsupported by metapost", i);
+ return;
+ }
+ for (key = font_keys; key - font_keys < MAX_KEY_CODE; key++)
+ if (str_prefix (t1_line_array + 1, key->t1name))
+ break;
+ if (key - font_keys == MAX_KEY_CODE)
+ return;
+ key->valid = true;
+ p = t1_line_array + strlen (key->t1name) + 1;
+ skip (p, ' ');
+ if ((k = key - font_keys) == FONTNAME_CODE) {
+ if (*p != '/') {
+ remove_eol (p, t1_line_array);
+ pdftex_fail ("a name expected: `%s'", t1_line_array);
+ }
+ r = ++p; /* skip the slash */
+ if (is_included (fm_cur)) {
+ /* save the fontname */
+ strncpy (fontname_buf, p, FONTNAME_BUF_SIZE);
+ for (i=0; fontname_buf[i] != 10; i++);
+ fontname_buf[i]=0;
+
+ if(is_subsetted (fm_cur)) {
+ if (fm_cur->encoding!=NULL && fm_cur->encoding->glyph_names!=NULL)
+ make_subset_tag (fm_cur, fm_cur->encoding->glyph_names, tex_font);
+ else
+ make_subset_tag (fm_cur, t1_builtin_glyph_names, tex_font);
+
+ alloc_array (t1_line, (r-t1_line_array+6+1+strlen(fontname_buf)+1), T1_BUF_SIZE);
+ strncpy (r, fm_cur->subset_tag , 6);
+ *(r+6) = '-';
+ strncpy (r+7, fontname_buf, strlen(fontname_buf)+1);
+ t1_line_ptr = eol (r);
+ } else {
+ /* for (q = p; *q != ' ' && *q != 10; *q++);*/
+ /**q = 0;*/
+ t1_line_ptr = eol (r);
+ }
+ }
+ return;
+ }
+ if ((k == STEMV_CODE || k == FONTBBOX1_CODE)
+ && (*p == '[' || *p == '{'))
+ p++;
+ if (k == FONTBBOX1_CODE) {
+ for (i = 0; i < 4; i++) {
+ key[i].value = t1_scan_num (p, &r);
+ p = r;
+ }
+ return;
+ }
+ key->value = t1_scan_num (p, 0);
+}
+
+static void t1_scan_param (int tex_font,fm_entry *fm_cur)
+{
+ static const char *lenIV = "/lenIV";
+ if (!t1_scan || *t1_line_array != '/')
+ return;
+ if (t1_prefix (lenIV)) {
+ t1_lenIV = t1_scan_num (t1_line_array + strlen (lenIV), 0);
+ return;
+ }
+ t1_scan_keys (tex_font,fm_cur);
+}
+
+static void copy_glyph_names (char **glyph_names, int a, int b)
+{
+ if (glyph_names[b] != notdef) {
+ free (glyph_names[b]);
+ glyph_names[b] = (char *) notdef;
+ }
+ if (glyph_names[a] != notdef) {
+ glyph_names[b] = xstrdup (glyph_names[a]);
+ }
+}
+
+static void t1_builtin_enc (void)
+{
+ int i, a, b, c, counter = 0;
+ char *r, *p;
+ /*
+ * At this moment "/Encoding" is the prefix of t1_line_array
+ */
+ if (t1_suffix ("def")) { /* predefined encoding */
+ sscanf (t1_line_array + strlen ("/Encoding"), "%256s", t1_buf_array);
+ if (strcmp (t1_buf_array, "StandardEncoding") == 0) {
+ for (i = 0; i < 256; i++)
+ if (standard_glyph_names[i] == notdef)
+ t1_builtin_glyph_names[i] = (char *) notdef;
+ else
+ t1_builtin_glyph_names[i] =
+ xstrdup (standard_glyph_names[i]);
+ t1_encoding = ENC_STANDARD;
+ } else
+ pdftex_fail
+ ("cannot subset font (unknown predefined encoding `%s')",
+ t1_buf_array);
+ return;
+ } else
+ t1_encoding = ENC_BUILTIN;
+ /*
+ * At this moment "/Encoding" is the prefix of t1_line_array, and the encoding is
+ * not a predefined encoding
+ *
+ * We have two possible forms of Encoding vector. The first case is
+ *
+ * /Encoding [/a /b /c...] readonly def
+ *
+ * and the second case can look like
+ *
+ * /Encoding 256 array 0 1 255 {1 index exch /.notdef put} for
+ * dup 0 /x put
+ * dup 1 /y put
+ * ...
+ * readonly def
+ */
+ for (i = 0; i < 256; i++)
+ t1_builtin_glyph_names[i] = (char *) notdef;
+ if (t1_prefix ("/Encoding [") || t1_prefix ("/Encoding[")) { /* the first case */
+ r = strchr (t1_line_array, '[') + 1;
+ skip (r, ' ');
+ for (;;) {
+ while (*r == '/') {
+ for (p = t1_buf_array, r++;
+ *r != 32 && *r != 10 && *r != ']' && *r != '/';
+ *p++ = *r++);
+ *p = 0;
+ skip (r, ' ');
+ if (counter > 255)
+ pdftex_fail
+ ("encoding vector contains more than 256 names");
+ if (strcmp (t1_buf_array, notdef) != 0)
+ t1_builtin_glyph_names[counter] = xstrdup (t1_buf_array);
+ counter++;
+ }
+ if (*r != 10 && *r != '%') {
+ if (str_prefix (r, "] def")
+ || str_prefix (r, "] readonly def"))
+ break;
+ else {
+ remove_eol (r, t1_line_array);
+ pdftex_fail
+ ("a name or `] def' or `] readonly def' expected: `%s'",
+ t1_line_array);
+ }
+ }
+ t1_getline ();
+ r = t1_line_array;
+ }
+ } else { /* the second case */
+ p = strchr (t1_line_array, 10);
+ for (;;) {
+ if (*p == 10) {
+ t1_getline ();
+ p = t1_line_array;
+ }
+ /*
+ check for `dup <index> <glyph> put'
+ */
+ if (sscanf (p, "dup %i%256s put", &i, t1_buf_array) == 2 &&
+ *t1_buf_array == '/' && valid_code (i)) {
+ if (strcmp (t1_buf_array + 1, notdef) != 0)
+ t1_builtin_glyph_names[i] = xstrdup (t1_buf_array + 1);
+ p = strstr (p, " put") + strlen (" put");
+ skip (p, ' ');
+ }
+ /*
+ check for `dup dup <to> exch <from> get put'
+ */
+ else if (sscanf (p, "dup dup %i exch %i get put", &b, &a) == 2
+ && valid_code (a) && valid_code (b)) {
+ copy_glyph_names (t1_builtin_glyph_names, a, b);
+ p = strstr (p, " get put") + strlen (" get put");
+ skip (p, ' ');
+ }
+ /*
+ check for `dup dup <from> <size> getinterval <to> exch putinterval'
+ */
+ else if (sscanf
+ (p, "dup dup %i %i getinterval %i exch putinterval",
+ &a, &c, &b) == 3 && valid_code (a) && valid_code (b)
+ && valid_code (c)) {
+ for (i = 0; i < c; i++)
+ copy_glyph_names (t1_builtin_glyph_names, a + i, b + i);
+ p = strstr (p, " putinterval") + strlen (" putinterval");
+ skip (p, ' ');
+ }
+ /*
+ check for `def' or `readonly def'
+ */
+ else if ((p == t1_line_array || (p > t1_line_array && p[-1] == ' '))
+ && strcmp (p, "def\n") == 0)
+ return;
+ /*
+ skip an unrecognizable word
+ */
+ else {
+ while (*p != ' ' && *p != 10)
+ p++;
+ skip (p, ' ');
+ }
+ }
+ }
+}
+
+static void t1_check_end (void)
+{
+ if (t1_eof ())
+ return;
+ t1_getline ();
+ if (t1_prefix ("{restore}"))
+ t1_putline ();
+}
+
+static boolean t1_open_fontfile (fm_entry *fm_cur,const char *open_name_prefix)
+{
+ ff_entry *ff;
+ ff = check_ff_exist (fm_cur);
+ if (ff->ff_path != NULL)
+ t1_file = xfopen (cur_file_name = ff->ff_path, FOPEN_RBIN_MODE);
+ else {
+ set_cur_file_name (fm_cur->ff_name);
+ pdftex_warn ("cannot open Type 1 font file for reading");
+ return false;
+ }
+ t1_init_params (open_name_prefix);
+ fontfile_found = true;
+ return true;
+}
+
+static void t1_scan_only (int tex_font, fm_entry *fm_cur)
+{
+ do {
+ t1_getline ();
+ t1_scan_param (tex_font, fm_cur);
+ }
+ while (t1_in_eexec == 0);
+ t1_start_eexec (fm_cur);
+ do {
+ t1_getline ();
+ t1_scan_param (tex_font, fm_cur);
+ }
+ while (!(t1_charstrings () || t1_subrs ()));
+}
+
+static void t1_include (int tex_font, fm_entry *fm_cur)
+{
+ do {
+ t1_getline ();
+ t1_scan_param (tex_font, fm_cur);
+ t1_putline ();
+ }
+ while (t1_in_eexec == 0);
+ t1_start_eexec (fm_cur);
+ do {
+ t1_getline ();
+ t1_scan_param (tex_font, fm_cur);
+ t1_putline ();
+ }
+ while (!(t1_charstrings () || t1_subrs ()));
+ t1_cs = true;
+ do {
+ t1_getline ();
+ t1_putline ();
+ }
+ while (!t1_end_eexec ());
+ t1_stop_eexec (fm_cur);
+ if (fixedcontent) { /* copy 512 zeros (not needed for PDF) */
+ do {
+ t1_getline ();
+ t1_putline ();
+ }
+ while (!t1_cleartomark ());
+ t1_check_end (); /* write "{restore}if" if found */
+ }
+ get_length3 ();
+}
+
+#define check_subr(subr) \
+ if (subr >= subr_size || subr < 0) \
+ pdftex_fail("Subrs array: entry index out of range (%i)", subr);
+
+static const char **check_cs_token_pair ()
+{
+ const char **p = (const char **) cs_token_pairs_list;
+ for (; p[0] != NULL; ++p)
+ if (t1_buf_prefix (p[0]) && t1_buf_suffix (p[1]))
+ return p;
+ return NULL;
+}
+
+static void cs_store (boolean is_subr)
+{
+ char *p;
+ cs_entry *ptr;
+ int subr;
+ for (p = t1_line_array, t1_buf_ptr = t1_buf_array; *p != ' ';
+ *t1_buf_ptr++ = *p++);
+ *t1_buf_ptr = 0;
+ if (is_subr) {
+ subr = t1_scan_num (p + 1, 0);
+ check_subr (subr);
+ ptr = subr_tab + subr;
+ } else {
+ ptr = cs_ptr++;
+ if (cs_ptr - cs_tab > cs_size)
+ pdftex_fail
+ ("CharStrings dict: more entries than dict size (%i)", cs_size);
+ if (strcmp (t1_buf_array + 1, notdef) == 0) /* skip the slash */
+ ptr->name = (char *) notdef;
+ else
+ ptr->name = xstrdup (t1_buf_array + 1);
+ }
+ /* copy " RD " + cs data to t1_buf_array */
+ memcpy (t1_buf_array, t1_line_array + cs_start - 4,
+ (unsigned) (t1_cslen + 4));
+ /* copy the end of cs data to t1_buf_array */
+ for (p = t1_line_array + cs_start + t1_cslen, t1_buf_ptr =
+ t1_buf_array + t1_cslen + 4; *p != 10; *t1_buf_ptr++ = *p++);
+ *t1_buf_ptr++ = 10;
+ if (is_subr && cs_token_pair == NULL)
+ cs_token_pair = check_cs_token_pair ();
+ ptr->len = t1_buf_ptr - t1_buf_array;
+ ptr->cslen = t1_cslen;
+ ptr->data = xtalloc (ptr->len, byte);
+ memcpy (ptr->data, t1_buf_array, ptr->len);
+ ptr->valid = true;
+}
+
+#define store_subr() cs_store(true)
+#define store_cs() cs_store(false)
+
+#define CC_STACK_SIZE 24
+
+static integer cc_stack[CC_STACK_SIZE], *stack_ptr = cc_stack;
+static cc_entry cc_tab[CS_MAX];
+static boolean is_cc_init = false;
+
+
+#define cc_pop(N) \
+ if (stack_ptr - cc_stack < (N)) \
+ stack_error(N); \
+ stack_ptr -= N
+
+#define stack_error(N) { \
+ pdftex_warn("CharString: invalid access (%i) to stack (%i entries)", \
+ (int) N, (int)(stack_ptr - cc_stack)); \
+ goto cs_error; \
+}
+
+/*
+static integer cc_get(integer index)
+{
+ if (index < 0) {
+ if (stack_ptr + index < cc_stack )
+ stack_error(stack_ptr - cc_stack + index);
+ return *(stack_ptr + index);
+ }
+ else {
+ if (cc_stack + index >= stack_ptr)
+ stack_error(index);
+ return cc_stack[index];
+ }
+}
+*/
+
+#define cc_get(N) ((N) < 0 ? *(stack_ptr + (N)) : *(cc_stack + (N)))
+
+#define cc_push(V) *stack_ptr++ = V
+#define cc_clear() stack_ptr = cc_stack
+
+#define set_cc(N, B, A, C) \
+ cc_tab[N].nargs = A; \
+ cc_tab[N].bottom = B; \
+ cc_tab[N].clear = C; \
+ cc_tab[N].valid = true
+
+static void cc_init (void)
+{
+ int i;
+ if (is_cc_init)
+ return;
+ for (i = 0; i < CS_MAX; i++)
+ cc_tab[i].valid = false;
+ set_cc (CS_HSTEM, true, 2, true);
+ set_cc (CS_VSTEM, true, 2, true);
+ set_cc (CS_VMOVETO, true, 1, true);
+ set_cc (CS_RLINETO, true, 2, true);
+ set_cc (CS_HLINETO, true, 1, true);
+ set_cc (CS_VLINETO, true, 1, true);
+ set_cc (CS_RRCURVETO, true, 6, true);
+ set_cc (CS_CLOSEPATH, false, 0, true);
+ set_cc (CS_CALLSUBR, false, 1, false);
+ set_cc (CS_RETURN, false, 0, false);
+ /*
+ set_cc(CS_ESCAPE, false, 0, false);
+ */
+ set_cc (CS_HSBW, true, 2, true);
+ set_cc (CS_ENDCHAR, false, 0, true);
+ set_cc (CS_RMOVETO, true, 2, true);
+ set_cc (CS_HMOVETO, true, 1, true);
+ set_cc (CS_VHCURVETO, true, 4, true);
+ set_cc (CS_HVCURVETO, true, 4, true);
+ set_cc (CS_DOTSECTION, false, 0, true);
+ set_cc (CS_VSTEM3, true, 6, true);
+ set_cc (CS_HSTEM3, true, 6, true);
+ set_cc (CS_SEAC, true, 5, true);
+ set_cc (CS_SBW, true, 4, true);
+ set_cc (CS_DIV, false, 2, false);
+ set_cc (CS_CALLOTHERSUBR, false, 0, false);
+ set_cc (CS_POP, false, 0, false);
+ set_cc (CS_SETCURRENTPOINT, true, 2, true);
+ is_cc_init = true;
+}
+
+#define cs_getchar() cdecrypt(*data++, &cr)
+
+#define mark_subr(n) cs_mark(0, n)
+#define mark_cs(s) cs_mark(s, 0)
+
+static void cs_warn (const char *cs_name, int subr, const char *fmt, ...)
+{
+ char buf[SMALL_BUF_SIZE];
+ va_list args;
+ va_start (args, fmt);
+ vsprintf (buf, fmt, args);
+ va_end (args);
+ if (cs_name == NULL)
+ pdftex_warn ("Subr (%i): %s", (int) subr, buf);
+ else
+ pdftex_warn ("CharString (/%s): %s", cs_name, buf);
+}
+
+static void cs_mark (const char *cs_name, int subr)
+{
+ byte *data;
+ int i, b, cs_len;
+ integer a, a1, a2;
+ unsigned short cr;
+ static integer lastargOtherSubr3 = 3; /* the argument of last call to
+ OtherSubrs[3] */
+ cs_entry *ptr;
+ cc_entry *cc;
+ if (cs_name == NULL) {
+ check_subr (subr);
+ ptr = subr_tab + subr;
+ if (!ptr->valid)
+ return;
+ } else {
+ if (cs_notdef != NULL &&
+ (cs_name == notdef || strcmp (cs_name, notdef) == 0))
+ ptr = cs_notdef;
+ else {
+ for (ptr = cs_tab; ptr < cs_ptr; ptr++)
+ if (strcmp (ptr->name, cs_name) == 0)
+ break;
+ if (ptr == cs_ptr) {
+ pdftex_warn ("glyph `%s' undefined", cs_name);
+ return;
+ }
+ if (ptr->name == notdef)
+ cs_notdef = ptr;
+ }
+ }
+ /* only marked CharString entries and invalid entries can be skipped;
+ valid marked subrs must be parsed to keep the stack in sync */
+ if (!ptr->valid || (ptr->used && cs_name != NULL))
+ return;
+ ptr->used = true;
+ cr = 4330;
+ cs_len = ptr->cslen;
+ data = ptr->data + 4;
+ for (i = 0; i < t1_lenIV; i++, cs_len--)
+ cs_getchar ();
+ while (cs_len > 0) {
+ --cs_len;
+ b = cs_getchar ();
+ if (b >= 32) {
+ if (b <= 246)
+ a = b - 139;
+ else if (b <= 250) {
+ --cs_len;
+ a = ((b - 247) << 8) + 108 + cs_getchar ();
+ } else if (b <= 254) {
+ --cs_len;
+ a = -((b - 251) << 8) - 108 - cs_getchar ();
+ } else {
+ cs_len -= 4;
+ a = (cs_getchar () & 0xff) << 24;
+ a |= (cs_getchar () & 0xff) << 16;
+ a |= (cs_getchar () & 0xff) << 8;
+ a |= (cs_getchar () & 0xff) << 0;
+ if (sizeof (integer) > 4 && (a & 0x80000000))
+ a |= ~0x7FFFFFFF;
+ }
+ cc_push (a);
+ } else {
+ if (b == CS_ESCAPE) {
+ b = cs_getchar () + CS_1BYTE_MAX;
+ cs_len--;
+ }
+ if (b >= CS_MAX) {
+ cs_warn (cs_name, subr, "command value out of range: %i",
+ (int) b);
+ goto cs_error;
+ }
+ cc = cc_tab + b;
+ if (!cc->valid) {
+ cs_warn (cs_name, subr, "command not valid: %i", (int) b);
+ goto cs_error;
+ }
+ if (cc->bottom) {
+ if (stack_ptr - cc_stack < cc->nargs)
+ cs_warn (cs_name, subr,
+ "less arguments on stack (%i) than required (%i)",
+ (int) (stack_ptr - cc_stack), (int) cc->nargs);
+ else if (stack_ptr - cc_stack > cc->nargs)
+ cs_warn (cs_name, subr,
+ "more arguments on stack (%i) than required (%i)",
+ (int) (stack_ptr - cc_stack), (int) cc->nargs);
+ }
+ switch (cc - cc_tab) {
+ case CS_CALLSUBR:
+ a1 = cc_get (-1);
+ cc_pop (1);
+ mark_subr (a1);
+ if (!subr_tab[a1].valid) {
+ cs_warn (cs_name, subr, "cannot call subr (%i)", (int) a1);
+ goto cs_error;
+ }
+ break;
+ case CS_DIV:
+ cc_pop (2);
+ cc_push (0);
+ break;
+ case CS_CALLOTHERSUBR:
+ if (cc_get (-1) == 3)
+ lastargOtherSubr3 = cc_get (-3);
+ a1 = cc_get (-2) + 2;
+ cc_pop (a1);
+ break;
+ case CS_POP:
+ cc_push (lastargOtherSubr3);
+ /* the only case when we care about the value being pushed onto
+ stack is when POP follows CALLOTHERSUBR (changing hints by
+ OtherSubrs[3])
+ */
+ break;
+ case CS_SEAC:
+ a1 = cc_get (3);
+ a2 = cc_get (4);
+ cc_clear ();
+ mark_cs (standard_glyph_names[a1]);
+ mark_cs (standard_glyph_names[a2]);
+ break;
+ default:
+ if (cc->clear)
+ cc_clear ();
+ }
+ }
+ }
+ return;
+ cs_error: /* an error occured during parsing */
+ cc_clear ();
+ ptr->valid = false;
+ ptr->used = false;
+}
+
+static void t1_subset_ascii_part (int tex_font, fm_entry *fm_cur)
+{
+ int i, j;
+ t1_getline ();
+ while (!t1_prefix ("/Encoding")) {
+ t1_scan_param (tex_font, fm_cur);
+ t1_putline ();
+ t1_getline ();
+ }
+ t1_builtin_enc ();
+ if (is_reencoded (fm_cur))
+ t1_glyph_names = external_enc ();
+ else
+ t1_glyph_names = t1_builtin_glyph_names;
+ /*
+ if (is_included (fm_cur) && is_subsetted (fm_cur)) {
+ make_subset_tag (fm_cur, t1_glyph_names, tex_font);
+ update_subset_tag ();
+ }
+ */
+ if ((!is_subsetted (fm_cur)) && t1_encoding == ENC_STANDARD)
+ t1_puts ("/Encoding StandardEncoding def\n");
+ else {
+ t1_puts
+ ("/Encoding 256 array\n0 1 255 {1 index exch /.notdef put} for\n");
+ for (i = 0, j = 0; i < 256; i++) {
+ if (is_used_char (i) && t1_glyph_names[i] != notdef) {
+ j++;
+ t1_printf ("dup %i /%s put\n", (int) t1_char (i),
+ t1_glyph_names[i]);
+ }
+ }
+ /* We didn't mark anything for the Encoding array. */
+ /* We add "dup 0 /.notdef put" for compatibility */
+ /* with Acrobat 5.0. */
+ if (j == 0)
+ t1_puts ("dup 0 /.notdef put\n");
+ t1_puts ("readonly def\n");
+ }
+ do {
+ t1_getline ();
+ t1_scan_param (tex_font, fm_cur);
+ if (!t1_prefix ("/UniqueID")) /* ignore UniqueID for subsetted fonts */
+ t1_putline ();
+ }
+ while (t1_in_eexec == 0);
+}
+
+#define t1_subr_flush() t1_flush_cs(true)
+#define t1_cs_flush() t1_flush_cs(false)
+
+static void t1_flush_cs (boolean);
+
+static void cs_init (void)
+{
+ cs_ptr = cs_tab = NULL;
+ cs_dict_start = cs_dict_end = NULL;
+ cs_count = cs_size = cs_size_pos = 0;
+ cs_token_pair = NULL;
+ subr_tab = NULL;
+ subr_array_start = subr_array_end = NULL;
+ subr_max = subr_size = subr_size_pos = 0;
+}
+
+static void init_cs_entry (cs_entry * cs)
+{
+ cs->data = NULL;
+ cs->name = NULL;
+ cs->len = 0;
+ cs->cslen = 0;
+ cs->used = false;
+ cs->valid = false;
+}
+
+static void t1_mark_glyphs (int tex_font);
+
+static void t1_read_subrs (int tex_font, fm_entry *fm_cur)
+{
+ int i, s;
+ cs_entry *ptr;
+ t1_getline ();
+ while (!(t1_charstrings () || t1_subrs ())) {
+ t1_scan_param (tex_font, fm_cur);
+ t1_putline ();
+ t1_getline ();
+ }
+ found:
+ t1_cs = true;
+ t1_scan = false;
+ if (!t1_subrs ())
+ return;
+ subr_size_pos = strlen ("/Subrs") + 1;
+ /* subr_size_pos points to the number indicating dict size after "/Subrs" */
+ subr_size = t1_scan_num (t1_line_array + subr_size_pos, 0);
+ if (subr_size == 0) {
+ while (!t1_charstrings ())
+ t1_getline ();
+ return;
+ }
+ // subr_tab = xtalloc (subr_size, cs_entry);
+ subr_tab = (cs_entry *)malloc (subr_size*sizeof (cs_entry));
+ for (ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
+ init_cs_entry (ptr);
+ subr_array_start = xstrdup (t1_line_array);
+ t1_getline ();
+ while (t1_cslen) {
+ store_subr ();
+ t1_getline ();
+ }
+ /* mark the first four entries without parsing */
+ for (i = 0; i < subr_size && i < 4; i++)
+ subr_tab[i].used = true;
+ /* the end of the Subrs array might have more than one line so we need to
+ concatnate them to subr_array_end. Unfortunately some fonts don't have
+ the Subrs array followed by the CharStrings dict immediately (synthetic
+ fonts). If we cannot find CharStrings in next POST_SUBRS_SCAN lines then
+ we will treat the font as synthetic and ignore everything until next
+ Subrs is found
+ */
+#define POST_SUBRS_SCAN 5
+ s = 0;
+ *t1_buf_array = 0;
+ for (i = 0; i < POST_SUBRS_SCAN; i++) {
+ if (t1_charstrings ())
+ break;
+ s += t1_line_ptr - t1_line_array;
+ alloc_array (t1_buf, s, T1_BUF_SIZE);
+ strcat (t1_buf_array, t1_line_array);
+ t1_getline ();
+ }
+ subr_array_end = xstrdup (t1_buf_array);
+ if (i == POST_SUBRS_SCAN) { /* CharStrings not found;
+ suppose synthetic font */
+ for (ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
+ if (ptr->valid)
+ xfree (ptr->data);
+ xfree (subr_tab);
+ xfree (subr_array_start);
+ xfree (subr_array_end);
+ cs_init ();
+ t1_cs = false;
+ t1_synthetic = true;
+ while (!(t1_charstrings () || t1_subrs ()))
+ t1_getline ();
+ goto found;
+ }
+}
+
+static void t1_flush_cs (boolean is_subr)
+{
+ char *p;
+ byte *r, *return_cs = NULL;
+ cs_entry *tab, *end_tab, *ptr;
+ char *start_line, *line_end;
+ int count, size_pos;
+ unsigned short cr, cs_len = 0; /* to avoid warning about uninitialized use of cs_len */
+ if (is_subr) {
+ start_line = subr_array_start;
+ line_end = subr_array_end;
+ size_pos = subr_size_pos;
+ tab = subr_tab;
+ count = subr_max + 1;
+ end_tab = subr_tab + count;
+ } else {
+ start_line = cs_dict_start;
+ line_end = cs_dict_end;
+ size_pos = cs_size_pos;
+ tab = cs_tab;
+ end_tab = cs_ptr;
+ count = cs_count;
+ }
+ t1_line_ptr = t1_line_array;
+ for (p = start_line; p - start_line < size_pos;)
+ *t1_line_ptr++ = *p++;
+ while (isdigit (*p))
+ p++;
+ sprintf (t1_line_ptr, "%u", count);
+ strcat (t1_line_ptr, p);
+ t1_line_ptr = eol (t1_line_array);
+ t1_putline ();
+
+ /* create return_cs to replace unsused subr's */
+ if (is_subr) {
+ cr = 4330;
+ cs_len = 0;
+ return_cs = xtalloc (t1_lenIV + 1, byte);
+ if (t1_lenIV > 0) {
+ for (cs_len = 0, r = return_cs; cs_len < t1_lenIV; cs_len++, r++)
+ *r = cencrypt (0x00, &cr);
+ *r = cencrypt (CS_RETURN, &cr);
+ } else {
+ *return_cs = CS_RETURN;
+ }
+ cs_len++;
+ }
+
+ for (ptr = tab; ptr < end_tab; ptr++) {
+ if (ptr->used) {
+ if (is_subr)
+ sprintf (t1_line_array, "dup %i %u", (int) (ptr - tab),
+ ptr->cslen);
+ else
+ sprintf (t1_line_array, "/%s %u", ptr->name, ptr->cslen);
+ p = strend (t1_line_array);
+ memcpy (p, ptr->data, ptr->len);
+ t1_line_ptr = p + ptr->len;
+ t1_putline ();
+ } else {
+ /* replace unsused subr's by return_cs */
+ if (is_subr) {
+ sprintf (t1_line_array, "dup %i %u%s ", (int) (ptr - tab),
+ cs_len, cs_token_pair[0]);
+ p = strend (t1_line_array);
+ memcpy (p, return_cs, cs_len);
+ t1_line_ptr = p + cs_len;
+ t1_putline ();
+ sprintf (t1_line_array, " %s", cs_token_pair[1]);
+ t1_line_ptr = eol (t1_line_array);
+ t1_putline ();
+ }
+ }
+ xfree (ptr->data);
+ if (ptr->name != notdef)
+ xfree (ptr->name);
+ }
+ sprintf (t1_line_array, "%s", line_end);
+ t1_line_ptr = eol (t1_line_array);
+ t1_putline ();
+ if (is_subr)
+ xfree (return_cs);
+ xfree (tab);
+ xfree (start_line);
+ xfree (line_end);
+}
+
+static void t1_mark_glyphs (int tex_font)
+{
+ int i;
+ char *charset = extra_charset ();
+ char *g, *s, *r;
+ cs_entry *ptr;
+ if (t1_synthetic || embed_all_glyphs (tex_font)) { /* mark everything */
+ if (cs_tab != NULL)
+ for (ptr = cs_tab; ptr < cs_ptr; ptr++)
+ if (ptr->valid)
+ ptr->used = true;
+ if (subr_tab != NULL) {
+ for (ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
+ if (ptr->valid)
+ ptr->used = true;
+ subr_max = subr_size - 1;
+ }
+ return;
+ }
+ mark_cs (notdef);
+ for (i = 0; i < 256; i++)
+ if (is_used_char (i)) {
+ if (t1_glyph_names[i] == notdef)
+ pdftex_warn ("character %i is mapped to %s", i, notdef);
+ else
+ mark_cs (t1_glyph_names[i]);
+ }
+ if (charset == NULL)
+ goto set_subr_max;
+ g = s = charset + 1; /* skip the first '/' */
+ r = strend (g);
+ while (g < r) {
+ while (*s != '/' && s < r)
+ s++;
+ *s = 0; /* terminate g by rewriting '/' to 0 */
+ mark_cs (g);
+ g = s + 1;
+ }
+ set_subr_max:
+ if (subr_tab != NULL)
+ for (subr_max = -1, ptr = subr_tab; ptr - subr_tab < subr_size; ptr++)
+ if (ptr->used && ptr - subr_tab > subr_max)
+ subr_max = ptr - subr_tab;
+}
+
+static void t1_subset_charstrings (int tex_font)
+{
+ cs_entry *ptr;
+ cs_size_pos =
+ strstr (t1_line_array, charstringname) + strlen (charstringname)
+ - t1_line_array + 1;
+ /* cs_size_pos points to the number indicating
+ dict size after "/CharStrings" */
+ cs_size = t1_scan_num (t1_line_array + cs_size_pos, 0);
+ cs_ptr = cs_tab = xtalloc (cs_size, cs_entry);
+ for (ptr = cs_tab; ptr - cs_tab < cs_size; ptr++)
+ init_cs_entry (ptr);
+ cs_notdef = NULL;
+ cs_dict_start = xstrdup (t1_line_array);
+ t1_getline ();
+ while (t1_cslen) {
+ store_cs ();
+ t1_getline ();
+ }
+ cs_dict_end = xstrdup (t1_line_array);
+ t1_mark_glyphs (tex_font);
+ if (subr_tab != NULL) {
+ if (cs_token_pair == NULL)
+ pdftex_fail
+ ("This Type 1 font uses mismatched subroutine begin/end token pairs.");
+ t1_subr_flush ();
+ }
+ for (cs_count = 0, ptr = cs_tab; ptr < cs_ptr; ptr++)
+ if (ptr->used)
+ cs_count++;
+ t1_cs_flush ();
+}
+
+static void t1_subset_end (fm_entry *fm_cur)
+{
+ if (t1_synthetic) { /* copy to "dup /FontName get exch definefont pop" */
+ while (!strstr (t1_line_array, "definefont")) {
+ t1_getline ();
+ t1_putline ();
+ }
+ while (!t1_end_eexec ())
+ t1_getline (); /* ignore the rest */
+ t1_putline (); /* write "mark currentfile closefile" */
+ } else
+ while (!t1_end_eexec ()) { /* copy to "mark currentfile closefile" */
+ t1_getline ();
+ t1_putline ();
+ }
+ t1_stop_eexec (fm_cur);
+ if (fixedcontent) { /* copy 512 zeros (not needed for PDF) */
+ while (!t1_cleartomark ()) {
+ t1_getline ();
+ t1_putline ();
+ }
+ if (!t1_synthetic) /* don't check "{restore}if" for synthetic fonts */
+ t1_check_end (); /* write "{restore}if" if found */
+ }
+ get_length3 ();
+}
+
+int t1_updatefm (int f, fm_entry *fm)
+{
+ char *s, *p;
+ read_encoding_only = true;
+ if (!t1_open_fontfile (fm,NULL)) {
+ return 0;
+ }
+ t1_scan_only (f, fm);
+ s = xstrdup(fontname_buf);
+ for (p=s; *p != ' ' && *p != 0; *p++);
+ *p=0;
+ fm->ps_name = s;
+ t1_close_font_file ("");
+ return 1;
+}
+
+
+void writet1 (int tex_font, fm_entry *fm_cur)
+{
+ read_encoding_only = false;
+ if (!is_included (fm_cur)) { /* scan parameters from font file */
+ if (!t1_open_fontfile (fm_cur,"{"))
+ return;
+ t1_scan_only (tex_font, fm_cur);
+ t1_close_font_file ("}");
+ return;
+ }
+ if (!is_subsetted (fm_cur)) { /* include entire font */
+ if (!t1_open_fontfile (fm_cur,"<<"))
+ return;
+ t1_include (tex_font,fm_cur);
+ t1_close_font_file (">>");
+ return;
+ }
+ /* partial downloading */
+ if (!t1_open_fontfile (fm_cur,"<"))
+ return;
+ t1_subset_ascii_part (tex_font,fm_cur);
+ t1_start_eexec (fm_cur);
+ cc_init ();
+ cs_init ();
+ t1_read_subrs (tex_font, fm_cur);
+ t1_subset_charstrings (tex_font);
+ t1_subset_end (fm_cur);
+ t1_close_font_file (">");
+}
+
+void t1_free ()
+{
+ xfree (t1_line_array);
+ xfree (t1_buf_array);
+}