diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
commit | 487ca4806cc046076293cf6cc5fbba0db282bac7 (patch) | |
tree | 847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/dvipos | |
parent | a3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff) |
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipos')
-rw-r--r-- | Build/source/texk/dvipos/depend.mak | 169 | ||||
-rw-r--r-- | Build/source/texk/dvipos/dvicore.c | 1133 | ||||
-rw-r--r-- | Build/source/texk/dvipos/dvicore.h | 153 | ||||
-rw-r--r-- | Build/source/texk/dvipos/dvipos.c | 128 | ||||
-rw-r--r-- | Build/source/texk/dvipos/tfm.c | 785 | ||||
-rw-r--r-- | Build/source/texk/dvipos/tfm.h | 63 | ||||
-rw-r--r-- | Build/source/texk/dvipos/win32.mak | 58 |
7 files changed, 2489 insertions, 0 deletions
diff --git a/Build/source/texk/dvipos/depend.mak b/Build/source/texk/dvipos/depend.mak new file mode 100644 index 00000000000..ff66d554120 --- /dev/null +++ b/Build/source/texk/dvipos/depend.mak @@ -0,0 +1,169 @@ +$(objdir)/dvipos.obj: \ + dvicore.h \ + ../kpathsea/c-auto.h \ + ../kpathsea/kpathsea.h \ + ../kpathsea/config.h \ + ../kpathsea/c-std.h \ + ../kpathsea/c-unistd.h \ + ../kpathsea/systypes.h \ + ../kpathsea/c-memstr.h \ + ../kpathsea/c-errno.h \ + ../kpathsea/c-minmax.h \ + ../kpathsea/c-limits.h \ + ../kpathsea/c-proto.h \ + $(gnuw32dir)/win32lib.h \ + ../kpathsea/debug.h \ + ../kpathsea/types.h \ + ../kpathsea/lib.h \ + ../kpathsea/progname.h \ + ../kpathsea/absolute.h \ + ../kpathsea/c-ctype.h \ + $(gnuw32dir)/oldnames.h \ + ../kpathsea/c-dir.h \ + ../kpathsea/c-fopen.h \ + ../kpathsea/c-namemx.h \ + ../kpathsea/c-pathch.h \ + ../kpathsea/c-pathmx.h \ + ../kpathsea/c-stat.h \ + ../kpathsea/c-vararg.h \ + ../kpathsea/cnf.h \ + ../kpathsea/concatn.h \ + ../kpathsea/db.h \ + ../kpathsea/str-list.h \ + ../kpathsea/default.h \ + ../kpathsea/expand.h \ + ../kpathsea/fn.h \ + ../kpathsea/fontmap.h \ + ../kpathsea/hash.h \ + ../kpathsea/getopt.h \ + ../kpathsea/line.h \ + ../kpathsea/magstep.h \ + ../kpathsea/paths.h \ + ../kpathsea/pathsearch.h \ + ../kpathsea/str-llist.h \ + ../kpathsea/proginit.h \ + ../kpathsea/readable.h \ + ../kpathsea/remote.h \ + ../kpathsea/tex-file.h \ + ../kpathsea/tex-glyph.h \ + ../kpathsea/tex-hush.h \ + ../kpathsea/tex-make.h \ + ../kpathsea/tilde.h \ + ../kpathsea/truncate.h \ + ../kpathsea/variable.h \ + ../kpathsea/xopendir.h \ + ../kpathsea/xstat.h + +$(objdir)/dvicore.obj: \ + dvicore.h \ + ../kpathsea/c-auto.h \ + ../kpathsea/kpathsea.h \ + ../kpathsea/config.h \ + ../kpathsea/c-std.h \ + ../kpathsea/c-unistd.h \ + ../kpathsea/systypes.h \ + ../kpathsea/c-memstr.h \ + ../kpathsea/c-errno.h \ + ../kpathsea/c-minmax.h \ + ../kpathsea/c-limits.h \ + ../kpathsea/c-proto.h \ + $(gnuw32dir)/win32lib.h \ + ../kpathsea/debug.h \ + ../kpathsea/types.h \ + ../kpathsea/lib.h \ + ../kpathsea/progname.h \ + ../kpathsea/absolute.h \ + ../kpathsea/c-ctype.h \ + $(gnuw32dir)/oldnames.h \ + ../kpathsea/c-dir.h \ + ../kpathsea/c-fopen.h \ + ../kpathsea/c-namemx.h \ + ../kpathsea/c-pathch.h \ + ../kpathsea/c-pathmx.h \ + ../kpathsea/c-stat.h \ + ../kpathsea/c-vararg.h \ + ../kpathsea/cnf.h \ + ../kpathsea/concatn.h \ + ../kpathsea/db.h \ + ../kpathsea/str-list.h \ + ../kpathsea/default.h \ + ../kpathsea/expand.h \ + ../kpathsea/fn.h \ + ../kpathsea/fontmap.h \ + ../kpathsea/hash.h \ + ../kpathsea/getopt.h \ + ../kpathsea/line.h \ + ../kpathsea/magstep.h \ + ../kpathsea/paths.h \ + ../kpathsea/pathsearch.h \ + ../kpathsea/str-llist.h \ + ../kpathsea/proginit.h \ + ../kpathsea/readable.h \ + ../kpathsea/remote.h \ + ../kpathsea/tex-file.h \ + ../kpathsea/tex-glyph.h \ + ../kpathsea/tex-hush.h \ + ../kpathsea/tex-make.h \ + ../kpathsea/tilde.h \ + ../kpathsea/truncate.h \ + ../kpathsea/variable.h \ + ../kpathsea/xopendir.h \ + ../kpathsea/xstat.h \ + tfm.h + +$(objdir)/tfm.obj: \ + dvicore.h \ + ../kpathsea/c-auto.h \ + ../kpathsea/kpathsea.h \ + ../kpathsea/config.h \ + ../kpathsea/c-std.h \ + ../kpathsea/c-unistd.h \ + ../kpathsea/systypes.h \ + ../kpathsea/c-memstr.h \ + ../kpathsea/c-errno.h \ + ../kpathsea/c-minmax.h \ + ../kpathsea/c-limits.h \ + ../kpathsea/c-proto.h \ + $(gnuw32dir)/win32lib.h \ + ../kpathsea/debug.h \ + ../kpathsea/types.h \ + ../kpathsea/lib.h \ + ../kpathsea/progname.h \ + ../kpathsea/absolute.h \ + ../kpathsea/c-ctype.h \ + $(gnuw32dir)/oldnames.h \ + ../kpathsea/c-dir.h \ + ../kpathsea/c-fopen.h \ + ../kpathsea/c-namemx.h \ + ../kpathsea/c-pathch.h \ + ../kpathsea/c-pathmx.h \ + ../kpathsea/c-stat.h \ + ../kpathsea/c-vararg.h \ + ../kpathsea/cnf.h \ + ../kpathsea/concatn.h \ + ../kpathsea/db.h \ + ../kpathsea/str-list.h \ + ../kpathsea/default.h \ + ../kpathsea/expand.h \ + ../kpathsea/fn.h \ + ../kpathsea/fontmap.h \ + ../kpathsea/hash.h \ + ../kpathsea/getopt.h \ + ../kpathsea/line.h \ + ../kpathsea/magstep.h \ + ../kpathsea/paths.h \ + ../kpathsea/pathsearch.h \ + ../kpathsea/str-llist.h \ + ../kpathsea/proginit.h \ + ../kpathsea/readable.h \ + ../kpathsea/remote.h \ + ../kpathsea/tex-file.h \ + ../kpathsea/tex-glyph.h \ + ../kpathsea/tex-hush.h \ + ../kpathsea/tex-make.h \ + ../kpathsea/tilde.h \ + ../kpathsea/truncate.h \ + ../kpathsea/variable.h \ + ../kpathsea/xopendir.h \ + ../kpathsea/xstat.h + diff --git a/Build/source/texk/dvipos/dvicore.c b/Build/source/texk/dvipos/dvicore.c new file mode 100644 index 00000000000..3974a45cd0e --- /dev/null +++ b/Build/source/texk/dvipos/dvicore.c @@ -0,0 +1,1133 @@ +/* $Header + + dvipos-20030225 + + Copyright (C) 2003 by Jin-Hwan <chofchof@ktug.or.kr> + + 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. +*/ + +#include "dvicore.h" +#include "tfm.h" + +/* Global variables */ +int dvi_pages = 0; +extern FILE *tuo_file; + +/* Internal variables */ +static FILE *dvi_file = NULL; +static SIGNED_QUAD dvi_filesize; +static SIGNED_QUAD post_location, dvi_location, *page_location = NULL; +static int current_page; + +#define DVI_MAX_STACK_DEPTH 256 +static int dvi_stack_depth = 0; +static struct dvi_register { + SIGNED_QUAD h, v, w, x, y, z, d; +} dvi_state, dvi_stack[DVI_MAX_STACK_DEPTH]; + +static int dvi_current_font = -1, num_dvi_fonts = 0, max_dvi_fonts = 0; +static struct dvi_font { + SIGNED_QUAD size, id; int tfm_id, used; char *name; +} *dvi_fonts = NULL; + +static SIGNED_QUAD numerator, denominator, mag, max_v, max_h; +static double tfm_conv, true_conv, conv, resolution = 300.0; +static SIGNED_PAIR max_s, total_pages; + +/* Internal buffer */ +#ifdef DEBUG +#define DVI_BUFFER_SIZE 1024 +static int dvi_buffer_len = 0; +static unsigned char dvi_buffer[DVI_BUFFER_SIZE]; +#endif + +static SIGNED_QUAD sqxfw (SIGNED_QUAD z, SIGNED_QUAD b) +{ + SIGNED_QUAD alpha, beta, result; + UNSIGNED_BYTE b0, b1, b2, b3; + + alpha = 16; + while (z >= 0x800000L) { + z = z / 2; + alpha = alpha + alpha; + } + beta = 256 / alpha; + alpha = alpha * z; + + b0 = (b >> 24) & 0xFF; b1 = (b >> 16) & 0xFF; + b2 = (b >> 8) & 0xFF; b3 = b & 0xFF; + + result = (((((b3 * z) / 0x100) + (b2 * z)) / 0x100) + (b1 * z)) / beta; + + if (b0 == 0) return result; + else if (b0 == 255) return (result - alpha); + + fprintf(stderr, "[fatal] sqxfw(): TFM file is bad.\n"); + exit(1); +} + +static UNSIGNED_BYTE get_unsigned_byte (void) +{ +#ifdef DEBUG + dvi_location++; +#endif + return (UNSIGNED_BYTE)(fgetc(dvi_file) & 0xFF); +} + +static SIGNED_BYTE get_signed_byte (void) +{ + register UNSIGNED_BYTE byte = get_unsigned_byte(); + return (SIGNED_BYTE)(byte & 0x80 ? byte - 0x100 : byte); +} + +static UNSIGNED_PAIR get_unsigned_pair (void) +{ + register UNSIGNED_PAIR pair = get_unsigned_byte(); + /* Read the second byte */ + pair = pair << 8; pair += get_unsigned_byte(); + return pair; +} + +static SIGNED_PAIR get_signed_pair (void) +{ + register UNSIGNED_PAIR pair; + register UNSIGNED_BYTE byte = get_unsigned_byte(); + pair = (byte & 0x80 ? byte - 0x100 : byte); + /* Read the second byte */ + pair = pair << 8; pair += get_unsigned_byte(); + return (SIGNED_PAIR)pair; +} + +static UNSIGNED_TRIPLE get_unsigned_triple (void) +{ + register UNSIGNED_TRIPLE triple = get_unsigned_byte(); + /* Read the second, the third byte */ + triple = triple << 8; triple += get_unsigned_byte(); + triple = triple << 8; triple += get_unsigned_byte(); + return triple; +} + +static SIGNED_TRIPLE get_signed_triple (void) +{ + register UNSIGNED_TRIPLE triple; + /* Read the first byte and check the sign */ + register UNSIGNED_BYTE byte = get_unsigned_byte(); + triple = (byte & 0x80 ? byte - 0x100 : byte); + /* Read the second, the third byte */ + triple = triple << 8; triple += get_unsigned_byte(); + triple = triple << 8; triple += get_unsigned_byte(); + return (SIGNED_TRIPLE)triple; +} + +static UNSIGNED_QUAD get_unsigned_quad (void) +{ + register UNSIGNED_QUAD quad = get_unsigned_byte(); + /* Read the second, the third, and the fourth byte */ + quad = quad << 8; quad += get_unsigned_byte(); + quad = quad << 8; quad += get_unsigned_byte(); + quad = quad << 8; quad += get_unsigned_byte(); + return quad; +} + +static SIGNED_QUAD get_signed_quad (void) +{ + register UNSIGNED_QUAD quad; + /* Read the first byte and check the sign */ + register UNSIGNED_BYTE byte = get_unsigned_byte(); + quad = (byte & 0x80 ? byte - 0x100 : byte); + /* Read the second, the third, and the fourth byte */ + quad = quad << 8; quad += get_unsigned_byte(); + quad = quad << 8; quad += get_unsigned_byte(); + quad = quad << 8; quad += get_unsigned_byte(); + return (SIGNED_QUAD)quad; +} + +static void dvi_clear_state (void) +{ + dvi_state.h = 0; dvi_state.v = 0; dvi_state.w = 0; + dvi_state.x = 0; dvi_state.y = 0; dvi_state.z = 0; + dvi_state.d = 0; /* direction for ASCII pTeX */ + dvi_stack_depth = 0; dvi_current_font = -1; +} + +static void do_space (UNSIGNED_BYTE opcode) +{ + SIGNED_QUAD x; + + switch (opcode) { + case RIGHT1: + x = get_signed_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: right1 %ld ", dvi_location-1, x); + dvi_buffer[dvi_buffer_len++] = ' '; +#endif + break; + case RIGHT2: + x = get_signed_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: right2 %ld ", dvi_location-2, x); + dvi_buffer[dvi_buffer_len++] = ' '; +#endif + break; + case RIGHT3: + x = get_signed_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: right3 %ld ", dvi_location-3, x); + dvi_buffer[dvi_buffer_len++] = ' '; +#endif + break; + case RIGHT4: + x = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: right4 %ld ", dvi_location-4, x); + dvi_buffer[dvi_buffer_len++] = ' '; +#endif + break; + case W0: + x = dvi_state.w; +#ifdef DEBUG + fprintf(stderr, "%ld: w0 %ld ", dvi_location, x); + dvi_buffer[dvi_buffer_len++] = ' '; +#endif + break; + case W1: + x = dvi_state.w = get_signed_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: w1 %ld ", dvi_location-1, x); + dvi_buffer[dvi_buffer_len++] = ' '; +#endif + break; + case W2: + x = dvi_state.w = get_signed_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: w2 %ld ", dvi_location-2, x); + dvi_buffer[dvi_buffer_len++] = ' '; +#endif + break; + case W3: + x = dvi_state.w = get_signed_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: w3 %ld ", dvi_location-3, x); + dvi_buffer[dvi_buffer_len++] = ' '; +#endif + break; + case W4: + x = dvi_state.w = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: w4 %ld ", dvi_location-4, x); + dvi_buffer[dvi_buffer_len++] = ' '; +#endif + break; + case X0: + x = dvi_state.x; +#ifdef DEBUG + fprintf(stderr, "%ld: x0 %ld ", dvi_location, x); +#endif + break; + case X1: + x = dvi_state.x = get_signed_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: x1 %ld ", dvi_location-1, x); +#endif + break; + case X2: + x = dvi_state.x = get_signed_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: x2 %ld ", dvi_location-2, x); +#endif + break; + case X3: + x = dvi_state.x = get_signed_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: x3 %ld ", dvi_location-3, x); +#endif + break; + case X4: + x = dvi_state.x = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: x4 %ld ", dvi_location-4, x); +#endif + break; + } + + if (!dvi_state.d) { +#ifdef DEBUG + fprintf(stderr, "h:=%ld+%ld=%ld, hh:=xx\n", dvi_state.h, x, dvi_state.h+x); +#endif + dvi_state.h += x; + } else { +#ifdef DEBUG + fprintf(stderr, "v:=%ld+%ld=%ld, vv:=xx\n", dvi_state.v, x, dvi_state.v+x); +#endif + dvi_state.v += x; + } +} + +static void do_vmove (UNSIGNED_BYTE opcode) +{ + SIGNED_QUAD y; + + switch (opcode) { + case DOWN1: + y = get_signed_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: down1 %ld ", dvi_location-1, y); +#endif + break; + case DOWN2: + y = get_signed_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: down2 %ld ", dvi_location-2, y); +#endif + break; + case DOWN3: + y = get_signed_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: down3 %ld ", dvi_location-3, y); +#endif + break; + case DOWN4: + y = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: down4 %ld ", dvi_location-4, y); +#endif + break; + case Y0: + y = dvi_state.y; +#ifdef DEBUG + fprintf(stderr, "%ld: y0 %ld ", dvi_location, y); +#endif + break; + case Y1: + y = dvi_state.y = get_signed_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: y1 %ld ", dvi_location-1, y); +#endif + break; + case Y2: + y = dvi_state.y = get_signed_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: y2 %ld ", dvi_location-2, y); +#endif + break; + case Y3: + y = dvi_state.y = get_signed_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: y3 %ld ", dvi_location-3, y); +#endif + break; + case Y4: + y = dvi_state.y = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: y4 %ld ", dvi_location-4, y); +#endif + break; + case Z0: + y = dvi_state.z; +#ifdef DEBUG + fprintf(stderr, "%ld: z0 %ld ", dvi_location, y); +#endif + break; + case Z1: + y = dvi_state.z = get_signed_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: z1 %ld ", dvi_location-1, y); +#endif + break; + case Z2: + y = dvi_state.z = get_signed_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: z2 %ld ", dvi_location-2, y); +#endif + break; + case Z3: + y = dvi_state.z = get_signed_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: z3 %ld ", dvi_location-3, y); +#endif + break; + case Z4: + y = dvi_state.z = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: z4 %ld ", dvi_location-4, y); +#endif + break; + } + + if (!dvi_state.d) { +#ifdef DEBUG + fprintf(stderr, "v:=%ld+%ld=%ld, vv:=xx\n", dvi_state.v, y, dvi_state.v+y); +#endif + dvi_state.v += y; + } else { +#ifdef DEBUG + fprintf(stderr, "h:=%ld-%ld=%ld, hh:=xx\n", dvi_state.h, y, dvi_state.h-y); +#endif + dvi_state.h -= y; + } +} + +static void do_rule (UNSIGNED_BYTE opcode) +{ + SIGNED_QUAD width, height; + + switch (opcode) { + case SET_RULE: +#ifdef DEBUG + fprintf(stderr, "%ld: setrule ", dvi_location); +#endif + break; + case PUT_RULE: +#ifdef DEBUG + fprintf(stderr, "%ld: putrule ", dvi_location); +#endif + break; + } + + height = get_signed_quad(); width = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "height %ld width %ld ", height, width); +#endif + + /* + * SET_RULE: Typeset a solid black rectangle of height |a| and width |b|, + * with its bottom left corner at |(h,v)|. Then set |h:=h+b|. If either + * |a<=0| or |b<=0|, nothing should be typeset. Note that if |b<0|, the + * value of |h| will decrease even though nothing else happens. + */ + if (opcode == SET_RULE) { + dvi_state.h += width; +#ifdef DEBUG + fprintf(stderr, "h:=%ld+%ld=%ld, hh:=xx\n", dvi_state.h, width, dvi_state.h+width); +#endif + } +} + +static void do_set (UNSIGNED_BYTE opcode) +{ + SIGNED_QUAD ch, width; + struct dvi_font *fnt; + + switch (opcode) { + case SET1: + ch = get_unsigned_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: set1 %ld ", dvi_location-1, ch); +#endif + break; + case SET2: + ch = get_unsigned_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: set2 %ld ", dvi_location-2, ch); +#endif + break; + case SET3: + ch = get_unsigned_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: set3 %ld ", dvi_location-3, ch); +#endif + break; + case SET4: + ch = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: set4 %ld ", dvi_location-4, ch); +#endif + break; + } + + if (dvi_current_font < 0) { + fprintf(stderr, "[fatal] dvi_set(): No font selected.\n"); + exit(1); + } + + fnt = dvi_fonts + dvi_current_font; + width = sqxfw(fnt->size, tfm_get_fw_width(fnt->tfm_id, ch)); + + if (!dvi_state.d) { +#ifdef DEBUG + fprintf(stderr, "h:=%ld+%ld=%ld, hh:=xx\n", dvi_state.h, width, dvi_state.h+width); +#endif + dvi_state.h += width; + } else { +#ifdef DEBUG + fprintf(stderr, "v:=%ld+%ld=%ld, vv:=xx\n", dvi_state.v, width, dvi_state.v+width); +#endif + dvi_state.v += width; + } +} + +static void do_put (UNSIGNED_BYTE opcode) +{ + SIGNED_QUAD ch; + + switch (opcode) { + case PUT1: + ch = get_unsigned_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: put1 %ld ", dvi_location-1, ch); +#endif + break; + case PUT2: + ch = get_unsigned_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: put2 %ld ", dvi_location-2, ch); +#endif + break; + case PUT3: + ch = get_unsigned_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: put3 %ld ", dvi_location-3, ch); +#endif + break; + case PUT4: + ch = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: put4 %ld ", dvi_location-4, ch); +#endif + break; + } +} + +static void do_push (void) +{ + if (dvi_stack_depth < DVI_MAX_STACK_DEPTH) + dvi_stack[dvi_stack_depth++] = dvi_state; + else { + fprintf(stderr, "[fatal] do_push(): DVI stack exceeded.\n"); + exit(1); + } +#ifdef DEBUG + fprintf(stderr, "%ld: push\nlevel %d:(h=%ld,v=%ld,w=%ld,x=%ld,y=%ld,z=%ld,hh=xx,vv=xx)\n", dvi_location, dvi_stack_depth-1, dvi_state.h, dvi_state.v, dvi_state.w, dvi_state.x, dvi_state.y, dvi_state.z); +#endif +} + +static void do_pop (void) +{ + if (dvi_stack_depth > 0) + dvi_state = dvi_stack[--dvi_stack_depth]; + else { + fprintf(stderr, "[fatal] do_pop(): Tried to pop an empty stack.\n"); + exit(1); + } +#ifdef DEBUG + if (dvi_buffer_len > 0) { + dvi_buffer[dvi_buffer_len] = 0; + fprintf(stderr, "[%s]\n", dvi_buffer); + dvi_buffer_len = 0; + } + fprintf(stderr, "%ld: pop\nlevel %d:(h=%ld,v=%ld,w=%ld,x=%ld,y=%ld,z=%ld,hh=xx,vv=xx)\n", dvi_location, dvi_stack_depth, dvi_state.h, dvi_state.v, dvi_state.w, dvi_state.x, dvi_state.y, dvi_state.z); +#endif +} + +static void do_fnt_num (UNSIGNED_BYTE opcode) +{ + register int i; + SIGNED_QUAD id; + + if (opcode >= FNT_NUM_0 && opcode <= FNT_NUM_63) { + id = opcode - FNT_NUM_0; +#ifdef DEBUG + fprintf(stderr, "%ld: fntnum%d ", dvi_location, id); +#endif + } else switch (opcode) { + case FNT1: + id = get_unsigned_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: fnt1 %ld ", dvi_location-1, id); +#endif + break; + case FNT2: + id = get_unsigned_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: fnt2 %ld ", dvi_location-2, id); +#endif + break; + case FNT3: + id = get_unsigned_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: fnt3 %ld ", dvi_location-3, id); +#endif + break; + case FNT4: + id = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: fnt4 %ld ", dvi_location-4, id); +#endif + break; + } + + for (i = 0; i < num_dvi_fonts; i++) + if (dvi_fonts[i].id == id) break; + + if (i == num_dvi_fonts) { + fprintf(stderr, "[fatal] do_fnt_num(): Tried to select a font (ID %ld) that hasn't been defined.\n", id); + exit(1); + } + +#ifdef DEBUG + fprintf(stderr, "current font is %s\n", dvi_fonts[i].name); +#endif + + if (!dvi_fonts[i].used) { + dvi_fonts[i].tfm_id = tfm_open(dvi_fonts[i].name, 1); + dvi_fonts[i].used = 1; + } + + dvi_current_font = i; +} + +static void do_setchar (UNSIGNED_BYTE opcode) +{ + SIGNED_QUAD width; + struct dvi_font *fnt; + + if (dvi_current_font < 0) { + fprintf(stderr, "[fatal] dvi_string(): No font selected.\n"); + exit(1); + } + + fnt = dvi_fonts + dvi_current_font; + width = tfm_get_fw_width(fnt->tfm_id, opcode-SET_CHAR_0); + width = sqxfw(fnt->size, width); + +#ifdef DEBUG + fprintf(stderr, "%ld: setchar%d ", dvi_location, opcode-SET_CHAR_0); +#endif + if (!dvi_state.d) { +#ifdef DEBUG + fprintf(stderr, "h:=%ld+%ld=%ld, hh:=xx\n", dvi_state.h, width, dvi_state.h+width); +#endif + dvi_state.h += width; + } else { +#ifdef DEBUG + fprintf(stderr, "v:=%ld+%ld=%ld, vv:=xx\n", dvi_state.v, width, dvi_state.v+width); +#endif + dvi_state.v += width; + } +#ifdef DEBUG + dvi_buffer[dvi_buffer_len++] = opcode - SET_CHAR_0; +#endif +} + +static void do_pos_special (unsigned char *buffer, SIGNED_QUAD buffer_len) +{ + unsigned char *cmd, *ident, *p; + SIGNED_QUAD x, y, w, h, d, list; + + for (p = buffer; p - buffer < buffer_len && isspace(*p); p++) + ; /* skip white chars */ + if (strncmp(p, "pos:", 4)) return; + + for (cmd = p; p - buffer < buffer_len && !isspace(*p); p++) + ; /* retrieve POS command */ + + for (*p++ = 0; p - buffer < buffer_len && isspace(*p); p++) + ; /* skip white chars */ + + if (*p == '"') p++; + for (ident = p; p - buffer < buffer_len && !isspace(*p); p++) + ; /* retrieve POS identification */ + if (*(p-1) == '"') *(p-1) = 0; else *p = 0; + + for (p++; p - buffer < buffer_len && isspace(*p); p++) + ; /* skip white chars */ + if (p - buffer < buffer_len) + sscanf(p, "%ld %ld %ld %ld", &w, &h, &d, &list); + + x = dvi_state.h + denominator / 100; + y = max_v - dvi_state.v; + + if (strcmp(cmd, "pos:pxy") == 0) + fprintf(tuo_file, "\\pospxy{%s}{%d}{%ld}{%ld}\n", ident, current_page, x, y); + else if (strcmp(cmd, "pos:pxywhd") == 0) + fprintf(tuo_file, "\\pospxywhd{%s}{%d}{%ld}{%ld}{%ld}{%ld}{%ld}\n", ident, current_page, x, y, w, h, d); + else if (strcmp(cmd, "pos:pxyplus") == 0) + fprintf(tuo_file, "\\pospxyplus{%s}{%d}{%ld}{%ld}{%ld}{%ld}{%ld}{%ld}\n", ident, current_page, x, y, w, h, d, list); +} + +static void do_xxx (UNSIGNED_BYTE opcode) +{ + SIGNED_QUAD size; + unsigned char *sp_buf; + +#ifdef DEBUG + if (dvi_buffer_len > 0) { + dvi_buffer[dvi_buffer_len] = 0; + fprintf(stderr, "[%s]\n", dvi_buffer); + dvi_buffer_len = 0; + } +#endif + + switch (opcode) { + case XXX1: + size = get_unsigned_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: xxx ", dvi_location-1); +#endif + break; + case XXX2: + size = get_unsigned_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: xxx ", dvi_location-2); +#endif + break; + case XXX3: + size = get_unsigned_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: xxx ", dvi_location-3); +#endif + break; + case XXX4: + size = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: xxx ", dvi_location-4); +#endif + break; + } + + sp_buf = (unsigned char *)calloc(size+1, sizeof(unsigned char)); + if (fread(sp_buf, sizeof(unsigned char), size, dvi_file) != size) { + fprintf(stderr, "[fatal] do_xxx(): Failed to read the special commands with size %d.\n", size); + exit(1); + } + +#ifdef DEBUG + fprintf(stderr, "'%s'\n", sp_buf); + dvi_location += size; +#endif + + do_pos_special(sp_buf, size); /* defined in dvispec.c */ + + free(sp_buf); +} + +static void find_post_opcode (void) +{ + UNSIGNED_BYTE opcode; + SIGNED_QUAD current_location; + + /* Calculate the file size of the DVI file */ + fseek(dvi_file, 0L, SEEK_END); + dvi_filesize = current_location = ftell(dvi_file); + rewind(dvi_file); + + /* Scan backwards through PADDING */ + do { + current_location--; + fseek(dvi_file, current_location, SEEK_SET); + } while((opcode = get_unsigned_byte()) == PADDING && current_location > 0); + + /* current_location now points to last non padding character or beginning of file */ + if (dvi_filesize - current_location < 4 || current_location == 0 || + !(opcode == DVI_ID || opcode == DVIV_ID)) { + fprintf(stderr, "[fatal] Invalid signature: (%d).\n", opcode); + exit(1); + } + + current_location -= 5; + fseek(dvi_file, current_location, SEEK_SET); + if ((opcode = get_unsigned_byte()) != POST_POST) { + fprintf (stderr, "[fatal] Found (%d) where POST_POST should be.\n", opcode); + exit(1); + } + + current_location = get_signed_quad(); + fseek(dvi_file, current_location, SEEK_SET); + if ((opcode = get_unsigned_byte()) != POST) { + fprintf (stderr, "[fatal] Found (%d) where POST should be\n", opcode); + exit(1); + } + + post_location = current_location; +} + +/* + * The last page in a DVI file is followed by `post'; this command + * introduces the postamble, which summarizes important facts that TeX has + * accumulated about the file, making it possible to print subsets of the data + * with reasonable efficiency. The postamble has the form + * + * post p[4] num[4] den[4] mag[4] l[4] u[4] s[2] t[2] + * (font definitions) + * post_post q[4] i[1] 223's[>=4] + * + * Here p is a pointer to the final bop in the file. The next three + * parameters, num, den, and mag, are duplicates of the quantities that + * appeared in the preamble. + */ + + +static void read_dvi_info (void) +{ +#ifdef DEBUG + fprintf(stderr, "Options selected: Starting page = *\n Maximum number of pages = 1000000\n Output level = 4 (the works)\n Resolution = %g\n", resolution); +#endif + + /* Skip the first five bytes; post and p[4] */ + fseek(dvi_file, post_location+5, SEEK_SET); + + if ((numerator = get_signed_quad()) <= 0) { + fprintf(stderr, "Bad DVI file: numerator is %d!\n", numerator); + exit(1); + } + + if ((denominator = get_signed_quad()) <= 0) { + fprintf(stderr, "Bad DVI file: denominator is %d!\n", denominator); + exit(1); + } + +#ifdef DEBUG + fprintf(stderr, "numerator/denomination=%ld/%ld\n", numerator, denominator); +#endif + + if ((mag = get_signed_quad()) <= 0) { + fprintf(stderr, "Bad DVI file: magnification is %d!\n", mag); + exit(1); + } + + tfm_conv = ((double)25400000.0/numerator)*(denominator/(double)473628672)/16.0; + true_conv = (numerator/(double)254000.0)*(resolution/denominator); + conv = true_conv*(mag/(double)1000.0); + +#ifdef DEBUG + fprintf(stderr, "magnification=%ld; %17.8f pixels per DVI unit\n", mag, conv); + fprintf(stderr, "Postamble start at byte %ld.\n", post_location); +#endif + + max_v = get_signed_quad(); + max_h = get_signed_quad(); + if ((max_s = get_signed_pair()) > DVI_MAX_STACK_DEPTH) { + fprintf(stderr, "[fatal] read_dvi_info(): maxstackdepth %d exceeds DVI_MAX_STACK_DEPTH %d\n", max_s, DVI_MAX_STACK_DEPTH); + exit(1); + } + total_pages = get_signed_pair(); + +#ifdef DEUBG + fprintf(stderr, "maxv=%ld, maxh=%ld, maxstackdepth=%d, totalpages=%d\n", + max_v, max_h, max_s, total_pages); +#endif +} + +static void read_dvi_comment (void) +{ + static char dvi_comment[257]; + fseek(dvi_file, 14, SEEK_SET); + dvi_comment[fread(dvi_comment, sizeof(char), get_unsigned_byte(), dvi_file)] = 0; +#ifdef DEBUG + fprintf(stderr, "'%s'\n", dvi_comment); +#endif +} + +static void find_page_location (void) +{ + register int i; + + /* Read the total page number */ + fseek(dvi_file, post_location+27, SEEK_SET); + if ((dvi_pages = get_unsigned_pair()) == 0) { + fprintf(stderr, "[fatal] Total page number is zero.\n"); + exit(1); + } + + /* Read the location of each page */ + page_location = (SIGNED_QUAD *)calloc(dvi_pages, sizeof(SIGNED_QUAD)); + fseek(dvi_file, post_location+1, SEEK_SET); + page_location[dvi_pages-1] = get_signed_quad(); + if (page_location[dvi_pages-1] + 41 > dvi_filesize) { + fprintf(stderr, "[fatal] The location of the page %d was broken.\n", dvi_pages); + exit(1); + } + for (i = dvi_pages-2; i >= 0; i--) { + fseek(dvi_file, page_location[i+1] + 41, SEEK_SET); + page_location[i] = get_signed_quad(); + if (page_location[i] + 41 > dvi_filesize) { + fprintf(stderr, "[fatal] The location of the page %d was broken.\n", i+1); + exit(1); + } + } +} + +static void read_dvi_fonts (void) +{ + UNSIGNED_BYTE opcode; + SIGNED_QUAD id, size; + + int dir_len, name_len; + char *dir, *name; + + fseek(dvi_file, post_location+29, SEEK_SET); + + while ((opcode = get_unsigned_byte()) != POST_POST) { + + switch (opcode) { + case FNT_DEF1: id = get_unsigned_byte(); break; + case FNT_DEF2: id = get_unsigned_pair(); break; + case FNT_DEF3: id = get_unsigned_triple(); break; + case FNT_DEF4: id = get_signed_quad(); break; + default: + fprintf(stderr, "[fatal] read_dvi_fonts(): Unexpected opcode (%ld).\n", opcode); + exit(1); + } + + /* Retrieve a font record */ + if (num_dvi_fonts >= max_dvi_fonts) { + max_dvi_fonts += MAX_FONTS_STEP; + dvi_fonts = (struct dvi_font *)realloc(dvi_fonts, max_dvi_fonts * sizeof(struct dvi_font)); + } + + get_signed_quad(); /* checksum */ + size = get_signed_quad(); /* scale factor */ + get_signed_quad(); /* designed size */ + + dir_len = get_unsigned_byte(); + name_len = get_unsigned_byte(); + + /* Retrieve the directory name and check the size and then discard it */ + dir = (char *)calloc(dir_len+1, sizeof(char)); + if (fread(dir, sizeof(char), dir_len, dvi_file) != dir_len) { + fprintf(stderr, "[fatal] read_dvi_fonts(): Failed to retrieve a directory name.\n"); + exit(1); + } + free(dir); + + /* Retrieve the font name */ + name = (char *)calloc(name_len+1, sizeof(char)); + if (fread(name, sizeof(char), name_len, dvi_file) != name_len) { + fprintf(stderr, "[fatal] read_dvi_fonts(): Failed to retrieve a font name.\n"); + exit(1); + } + name[name_len] = 0; + +#ifdef DEBUG + fprintf(stderr, "Font %d: %s---loaded at size %ld DVI units\n", id, name, size); +#endif + dvi_fonts[num_dvi_fonts].name = name; + dvi_fonts[num_dvi_fonts].size = size; + dvi_fonts[num_dvi_fonts].id = id; + dvi_fonts[num_dvi_fonts].used = 0; + num_dvi_fonts++; + } +} + +static void do_bop (void) +{ + register int i; +#ifdef DEBUG + fprintf(stderr, "\n%ld: beginning of page %d\n", dvi_location, current_page); +#endif + for (i = 0; i < 11; i++) get_signed_quad(); + dvi_clear_state(); +} + +static void do_eop (void) +{ +#ifdef DEBUG + fprintf(stderr, "%ld: eop\n", dvi_location); +#endif +} + +static void do_dir (void) +{ + dvi_state.d = get_unsigned_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: dir %d\n", dvi_location-1, dvi_state.d); +#endif +} + +static void do_fnt_def (UNSIGNED_BYTE opcode) +{ + register int len; + SIGNED_QUAD id; + char *fnt_buf; + +#ifdef DEBUG + if (dvi_buffer_len > 0) { + dvi_buffer[dvi_buffer_len] = 0; + fprintf(stderr, "[%s]\n", dvi_buffer); + dvi_buffer_len = 0; + } +#endif + + switch (opcode) { + case FNT_DEF1: + id = get_unsigned_byte(); +#ifdef DEBUG + fprintf(stderr, "%ld: fntdef1 %ld: ", dvi_location-1, id); +#endif + break; + case FNT_DEF2: + id = get_unsigned_pair(); +#ifdef DEBUG + fprintf(stderr, "%ld: fntdef2 %ld: ", dvi_location-2, id); +#endif + break; + case FNT_DEF3: + id = get_unsigned_triple(); +#ifdef DEBUG + fprintf(stderr, "%ld: fntdef3 %ld: ", dvi_location-3, id); +#endif + break; + case FNT_DEF4: + id = get_signed_quad(); +#ifdef DEBUG + fprintf(stderr, "%ld: fntdef4 %ld: ", dvi_location-4, id); +#endif + break; + } + + /* the checksum that TeX found in the TFM file for this font */ + get_signed_quad(); + /* a fixed-point scale factor */ + get_signed_quad(); + /* the "design size" */ + get_signed_quad(); + /* the length of the "area" or directory */ + len = get_unsigned_byte(); + /* the length of the font name itself */ + len += get_unsigned_byte(); + + /* the external name of the font */ + fnt_buf = (char *)calloc(len+1, sizeof(char)); + len = fread(fnt_buf, sizeof(char), len, dvi_file); + fnt_buf[len] = 0; +#ifdef DEBUG + fprintf(stderr, "%s\n", fnt_buf); + dvi_location += len; +#endif +} + +void dvi_init (char *filename) +{ + /* Open the input DVI file */ + if ((dvi_file = fopen(filename, "rb")) == NULL) { + fprintf(stderr, "[fatal] Could not open %s.", filename); + exit(1); + } + /* Find the post opcode */ + find_post_opcode(); + read_dvi_info(); + find_page_location(); + read_dvi_comment(); + read_dvi_fonts(); + dvi_clear_state(); +} + +void dvi_close (void) +{ + register int i; + tfm_close_all(); + fclose(dvi_file); + free(page_location); + for (i = 0; i < num_dvi_fonts; i++) free(dvi_fonts[i].name); + if (dvi_fonts) free(dvi_fonts); +} + + +void dvi_do_page (int n) +{ +#ifdef DEBUG + dvi_location = page_location[n] - 1; +#endif + + current_page = n + 1; + + /* Position to beginning of page */ + fseek(dvi_file, page_location[n], SEEK_SET); + + dvi_clear_state(); + + for (;;) { /* until finding EOP opcode */ + UNSIGNED_BYTE opcode = get_unsigned_byte(); + + /* SET_CHAR_0 - SET_CHAR_127 */ + if (opcode >= SET_CHAR_0 && opcode <= SET_CHAR_127) { + do_setchar(opcode); + continue; + } + + /* FNT_NUM_0 - FNT_NUM_63 */ + if (opcode >= FNT_NUM_0 && opcode <= FNT_NUM_63) { + do_fnt_num(opcode); + continue; + } + + switch (opcode) { + case SET1: + case SET2: + case SET3: + case SET4: do_set(opcode); break; + case PUT1: + case PUT2: + case PUT3: + case PUT4: do_put(opcode); break; + case SET_RULE: + case PUT_RULE: do_rule(opcode); break; + case NOP: break; + case BOP: do_bop(); break; + case EOP: do_eop(); return; + case PUSH: do_push(); break; + case POP: do_pop(); break; + case RIGHT1: + case RIGHT2: + case RIGHT3: + case RIGHT4: + case W0: + case W1: + case W2: + case W3: + case W4: + case X0: + case X1: + case X2: + case X3: + case X4: do_space(opcode); break; + case DOWN1: + case DOWN2: + case DOWN3: + case DOWN4: + case Y0: + case Y1: + case Y2: + case Y3: + case Y4: + case Z0: + case Z1: + case Z2: + case Z3: + case Z4: do_vmove(opcode); break; + case FNT1: + case FNT2: + case FNT3: + case FNT4: do_fnt_num(opcode); break; + case XXX1: + case XXX2: /* Not used in general */ + case XXX3: /* Not used in general */ + case XXX4: do_xxx(opcode); break; + case FNT_DEF1: + case FNT_DEF2: + case FNT_DEF3: + case FNT_DEF4: do_fnt_def(opcode); break; + case DIR: do_dir(); break; + case PRE: + case POST: + case POST_POST: + default: + fprintf(stderr, "[fatal] Unexpected opcode (%d).", opcode); + exit(1); + } + } +} + diff --git a/Build/source/texk/dvipos/dvicore.h b/Build/source/texk/dvipos/dvicore.h new file mode 100644 index 00000000000..30b1a835e50 --- /dev/null +++ b/Build/source/texk/dvipos/dvicore.h @@ -0,0 +1,153 @@ +/* $Header + + dvipos-20030225 + + Copyright (C) 2003 by Jin-Hwan <chofchof@ktug.or.kr> + + 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. +*/ + +#ifndef _DVICORE_H_ +#define _DVICORE_H_ + +#include <stdio.h> +#include <stdlib.h> + +#ifdef MIKTEX +#include "miktex.h" +#include "web2c-miktex.h" +#else /* KPATHSEA */ +#include <kpathsea/c-auto.h> +#include <kpathsea/kpathsea.h> +#endif + +/* DVI opcodes */ +#define SET_CHAR_0 0 +#define SET_CHAR_1 1 +/* etc. */ +#define SET_CHAR_127 127 +#define SET1 128 /* Typesets its single operand between 128 and 255 */ +#define SET2 129 /* Typesets its single two byte unsigned operand */ +#define SET3 130 /* Typesets its single three byte unsigned operand */ +#define SET4 131 /* Typesets its single four byte unsigned operand */ +/* Sets a rule of height param1(four bytes) and width param2(four bytes) + * These are *signed*. Nothing typeset for nonpositive values + * However, negative value *do* change current point */ +#define SET_RULE 132 +#define PUT1 133 /* Like SET1, but point doesn't change */ +#define PUT2 134 /* Like SET2 */ +#define PUT3 135 /* Like SET3 */ +#define PUT4 136 /* Like SET4 */ +#define PUT_RULE 137 /* Like SET_RULE */ +#define NOP 138 +/* Followed by 10 four byte count registers (signed?). + * Last parameter points to previous BOP (backward linked, first BOP has -1). + * BOP clears stack and resets current point. */ +#define BOP 139 +#define EOP 140 +#define PUSH 141 /* Pushes h,v,w,x,y,z */ +#define POP 142 /* Opposite of push */ +#define RIGHT1 143 /* Move right by one byte signed operand */ +#define RIGHT2 144 /* Move right by two byte signed operand */ +#define RIGHT3 145 /* Move right by three byte signed operand */ +#define RIGHT4 146 /* Move right by four byte signed operand */ +#define W0 147 /* Move right w */ +#define W1 148 /* w single byte signed operand. Move right by same amount */ +#define W2 149 /* Same as W1 with two byte signed operand */ +#define W3 150 /* Three byte signed operand */ +#define W4 151 /* Four byte signed operand */ +#define X0 152 /* Move right x */ +#define X1 153 /* Like W1 */ +#define X2 154 /* Like W2 */ +#define X3 155 /* Like W3 */ +#define X4 156 /* Like W4 */ +#define DOWN1 157 /* Move down by one byte signed operand */ +#define DOWN2 158 /* Two byte signed operand */ +#define DOWN3 159 /* Three byte signed operand */ +#define DOWN4 160 /* Four byte signed operand */ +#define Y0 161 /* Move down by y */ +#define Y1 162 /* Move down by one byte signed operand, which replaces Y */ +#define Y2 163 /* Two byte signed operand */ +#define Y3 164 /* Three byte signed operand */ +#define Y4 165 /* Four byte signed operand */ +#define Z0 166 /* Like Y0, but use z */ +#define Z1 167 /* Like Y1 */ +#define Z2 168 /* Like Y2 */ +#define Z3 169 /* Like Y3 */ +#define Z4 170 /* Like Y4 */ +#define FNT_NUM_0 171 /* Switch to font 0 */ +#define FNT_NUM_1 172 /* Switch to font 1 */ +/* etc. */ +#define FNT_NUM_63 234 /* Switch to font 63 */ +/* Switch to font described by single byte unsigned operand */ +#define FNT1 235 +/* Switch to font described by two byte unsigned operand */ +#define FNT2 236 +/* Switch to font described by three byte unsigned operand */ +#define FNT3 237 +/* Four byte operator (Knuth says signed, but what would be the point?) */ +#define FNT4 238 +/* Special. Operand is one byte length. Special follows immediately */ +#define XXX1 239 +/* Two byte operand */ +#define XXX2 240 +/* Three byte operand */ +#define XXX3 241 +/* Four byte operand (Knuth says TeX uses only XXX1 and XXX4 */ +#define XXX4 242 +/* One byte font number, four byte checksum, four byte magnified size + * (DVI units), four byte designed size, single byte directory length, + * single byte name length, followed by complete name (area+name) */ +#define FNT_DEF1 243 +#define FNT_DEF2 244 /* Same for two byte font number */ +#define FNT_DEF3 245 /* Same for three byte font number */ +#define FNT_DEF4 246 /* Four byte font number (Knuth says signed) */ +/* Preamble: one byte DVI version (should be 2) + * four byte unsigned numerator + * four byte unsigned denominator -- one DVI unit = den/num*10^(-7) m + * four byte magnification (multiplied by 1000) + * one byte unsigned comment length followed by comment. */ +#define PRE 247 +/* Postamble: similar to preamble + * four byte pointer to final bop + * four byte numerator + * four byte denominator + * four byte mag + * four byte maximum height (signed?) + * four byte maximum width + * two byte max stack depth required to process file + * two byte number of pages */ +#define POST 248 +/* End of postamble: + * four byte pointer to POST command + * Version byte (same as preamble) + * Padded by four or more 223's to the end of the file. */ +#define POST_POST 249 +#define DIR 255 /* Ascii pTeX DIR command */ + +#define DVI_ID 2 /* ID Byte for current DVI file */ +#define DVIV_ID 3 /* with Ascii pTeX VW mode extension */ + +#define PADDING 223 + +#define MAX_FONTS_STEP 10 + +typedef int UNSIGNED_BYTE, SIGNED_BYTE, SIGNED_PAIR; +typedef unsigned UNSIGNED_PAIR; +typedef long UNSIGNED_TRIPLE, SIGNED_TRIPLE, SIGNED_QUAD; +typedef unsigned long UNSIGNED_QUAD; + +#endif /* _DVICORE_H_ */ + diff --git a/Build/source/texk/dvipos/dvipos.c b/Build/source/texk/dvipos/dvipos.c new file mode 100644 index 00000000000..80bd669aa66 --- /dev/null +++ b/Build/source/texk/dvipos/dvipos.c @@ -0,0 +1,128 @@ +/* $Header + + dvipos-20030225 + + Copyright (C) 2003 by Jin-Hwan <chofchof@ktug.or.kr> + + 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. +*/ + +#include "dvicore.h" + +#ifdef KPATHSEA +string progname; +unsigned dpi = 600; +string mode = NULL; +extern KPSEDLL char *kpathsea_version_string; +#endif + +/* To be called from dvicore.c */ +extern void dvi_init (char *filename); +extern void dvi_close (void); +extern void dvi_do_page (int n); + +/* Global variables */ +FILE *tuo_file = NULL; +extern int dvi_pages; + +/* Internal variables */ +static char *dvi_filename = NULL, *tuo_filename = NULL; + +static void set_default_tuo_filename(void) +{ + if (strlen(dvi_filename) < 5 || strncmp(".dvi", dvi_filename+strlen(dvi_filename)-4, 4)) { + tuo_filename = (char *)calloc(strlen(dvi_filename)+5, sizeof(char)); + strcpy(tuo_filename, dvi_filename); + strcat(tuo_filename, ".tuo"); + } else { + tuo_filename = (char *)calloc(strlen(dvi_filename)+1, sizeof(char)); + strncpy(tuo_filename, dvi_filename, strlen(dvi_filename)-4); + strcpy(tuo_filename+strlen(dvi_filename)-4, ".tuo"); + } +} + +#ifdef MIKTEX +#define PLATFORM "(MiKTeX 2.2)" +#else +#define PLATFORM kpathsea_version_string +#endif +#define VERSION "20030225" + +static void title() +{ + fprintf(stderr, "This is DVIpos, Version %s %s\nby Jin-Hwan Cho <chofchof@ktug.or.kr>\n\n", VERSION, PLATFORM); +} + +static void usage() +{ + fprintf(stderr, "Usage: dvipos infile[.dvi] [outfile]\n\nDVIpos appends output to infile.tuo if no outfile is specified.\n\n"); +} + +int main (int argc, char *argv[]) +{ + register int i; + + if (argc < 2) { + title(); + usage(); + fprintf(stderr, "No DVI filename specified.\n"); + exit(1); + } + + if (strncmp(".dvi", argv[1]+strlen(argv[1])-4, 4)) { + dvi_filename = (char *)calloc(strlen(argv[1])+5, sizeof(char)); + strcpy(dvi_filename, argv[1]); + strcat(dvi_filename, ".dvi"); + } else + dvi_filename = argv[1]; + + if (argc > 2) + tuo_filename = argv[2]; + else + set_default_tuo_filename(); + + /* Open the output TUO file */ + if ((tuo_file = fopen(tuo_filename, "at")) == NULL) { + fprintf(stderr, "Could not open %s.\n", tuo_filename); + exit(1); + } + +#ifdef MIKTEX + miktex_initialize(); +#endif + +#ifdef KPATHSEA + progname = argv[0]; + kpse_set_program_name (argv[0], progname); + /* NULL for no fallback font. */ + kpse_init_prog (uppercasify (kpse_program_name), dpi, mode, NULL); +#endif + + dvi_init(dvi_filename); + + for (i = 0; i < dvi_pages; i++) + dvi_do_page(i); + + dvi_close(); + + fclose(tuo_file); + +#ifdef MIKTEX + miktex_uninitialize (); +#endif + + exit(0); +} + diff --git a/Build/source/texk/dvipos/tfm.c b/Build/source/texk/dvipos/tfm.c new file mode 100644 index 00000000000..b99f6017aea --- /dev/null +++ b/Build/source/texk/dvipos/tfm.c @@ -0,0 +1,785 @@ +/* $Header + + dvipos-20030225 + + Copyright (C) 2003 by Jin-Hwan Cho <chofchof@ktug.or.kr> + + Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team <dvipdfmx@project.ktug.or.kr> + + Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> + + 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. +*/ + +#include <stdio.h> + +#include "dvicore.h" + +static FILE *tfm_file; +static UNSIGNED_QUAD tfm_filesize; + +static UNSIGNED_BYTE get_unsigned_byte (void) +{ + return (UNSIGNED_BYTE)(fgetc(tfm_file) & 0xFF); +} + +static UNSIGNED_PAIR get_unsigned_pair (void) +{ + register UNSIGNED_PAIR pair = get_unsigned_byte(); + /* Read the second byte */ + pair = pair << 8; pair += get_unsigned_byte(); + return pair; +} + +static UNSIGNED_QUAD get_unsigned_quad (void) +{ + register UNSIGNED_QUAD quad = get_unsigned_byte(); + /* Read the second, the third, and the fourth byte */ + quad = quad << 8; quad += get_unsigned_byte(); + quad = quad << 8; quad += get_unsigned_byte(); + quad = quad << 8; quad += get_unsigned_byte(); + return quad; +} + +static SIGNED_QUAD get_signed_quad (void) +{ + register UNSIGNED_QUAD quad; + /* Read the first byte and check the sign */ + register UNSIGNED_BYTE byte = get_unsigned_byte(); + quad = (byte & 0x80 ? byte - 0x100 : byte); + /* Read the second, the third, and the fourth byte */ + quad = quad << 8; quad += get_unsigned_byte(); + quad = quad << 8; quad += get_unsigned_byte(); + quad = quad << 8; quad += get_unsigned_byte(); + return (SIGNED_QUAD)quad; +} + +#define FWBASE ((double) (1<<20)) +#define JFM_ID 11 +#define JFMV_ID 9 /* vertical version of JFM */ + +typedef signed long fixword; + +/* TFM record structure */ +struct a_tfm { + UNSIGNED_BYTE id; /* id = 11(9) for jfm(vertical) */ + UNSIGNED_BYTE nt; /* number of charcter types for jfm */ + UNSIGNED_QUAD wlenfile, wlenheader; + UNSIGNED_QUAD bc, ec; + UNSIGNED_QUAD nwidths, nheights, ndepths; + UNSIGNED_QUAD nitcor, nlig, nkern, nextens; + UNSIGNED_QUAD nfonparm; + UNSIGNED_QUAD font_direction; /* Used only in OFMs. TFMs don't have this field*/ + UNSIGNED_QUAD nco, ncw, npc; + SIGNED_QUAD *header; + UNSIGNED_QUAD *char_info; + UNSIGNED_PAIR *width_index; + UNSIGNED_BYTE *height_index; + UNSIGNED_BYTE *depth_index; + SIGNED_QUAD *width; + SIGNED_QUAD *height; + SIGNED_QUAD *depth; + char *tex_name; + UNSIGNED_PAIR *chartypes; + fixword *unpacked_widths; + fixword *unpacked_heights; + fixword *unpacked_depths; +}; + +void a_tfm_init (struct a_tfm *a_tfm) +{ + a_tfm->id = 0; + a_tfm->nt = 0; + a_tfm->header = NULL; + a_tfm->char_info = NULL; + a_tfm->width_index = NULL; + a_tfm->height_index = NULL; + a_tfm->depth_index = NULL; + a_tfm->width = NULL; + a_tfm->height = NULL; + a_tfm->depth = NULL; + a_tfm->chartypes = NULL; + a_tfm->unpacked_widths = NULL; + a_tfm->unpacked_heights = NULL; + a_tfm->unpacked_depths = NULL; +} + +struct a_tfm *tfm = NULL; +static unsigned numtfms = 0, max_tfms = 0; /* numtfms should equal numfonts in dvi.c */ + +static UNSIGNED_PAIR sum_of_tfm_sizes (struct a_tfm *a_tfm) +{ + unsigned long result = 6; + result += (a_tfm -> ec - a_tfm -> bc + 1); + result += a_tfm -> wlenheader; + result += a_tfm -> nwidths; + result += a_tfm -> nheights; + result += a_tfm -> ndepths; + result += a_tfm -> nitcor; + result += a_tfm -> nlig; + result += a_tfm -> nkern; + result += a_tfm -> nextens; + result += a_tfm -> nfonparm; + if (a_tfm->id == JFM_ID || a_tfm->id == JFMV_ID) { + result += a_tfm -> nt + 1; + } + return result; +} + +static SIGNED_QUAD sum_of_ofm_sizes (struct a_tfm *a_tfm) +{ + unsigned long result = 14; + result += 2*(a_tfm -> ec - a_tfm -> bc + 1); + result += a_tfm -> wlenheader; + result += a_tfm -> nwidths; + result += a_tfm -> nheights; + result += a_tfm -> ndepths; + result += a_tfm -> nitcor; + result += 2*(a_tfm -> nlig); + result += a_tfm -> nkern; + result += 2*(a_tfm -> nextens); + result += a_tfm -> nfonparm; + return result; +} + + +static void get_sizes (struct a_tfm *a_tfm) +{ + UNSIGNED_PAIR tfm_id; + + tfm_id = get_unsigned_pair(); + if (tfm_id == JFM_ID || tfm_id == JFMV_ID) { /* is jfm */ + a_tfm -> id = tfm_id; + a_tfm -> nt = get_unsigned_pair(); + a_tfm -> wlenfile = get_unsigned_pair(); +#ifdef DEBUG + fprintf (stderr, "size: %ld\n", a_tfm->wlenfile); +#endif + } else { + a_tfm->wlenfile = tfm_id; + } + a_tfm->wlenheader = get_unsigned_pair(); + a_tfm->bc = get_unsigned_pair(); + a_tfm->ec = get_unsigned_pair(); + if (a_tfm -> ec < a_tfm -> bc) { + fprintf(stderr, "TFM file error (ec < bc)\n"); + exit(1); + } + a_tfm->nwidths = get_unsigned_pair(); + a_tfm->nheights = get_unsigned_pair(); + a_tfm->ndepths = get_unsigned_pair(); + a_tfm->nitcor = get_unsigned_pair(); + a_tfm->nlig = get_unsigned_pair(); + a_tfm->nkern = get_unsigned_pair(); + a_tfm->nextens = get_unsigned_pair(); + a_tfm->nfonparm = get_unsigned_pair(); +#ifdef DEBUG + fprintf(stderr, "\nComputed size (words)%d\n", sum_of_tfm_sizes(a_tfm)); + fprintf(stderr, "Stated size (words)%ld\n", a_tfm->wlenfile); + fprintf(stderr, "Actual size (bytes)%ld\n", tfm_filesize); +#endif + if (a_tfm->wlenfile != tfm_filesize/4 || + sum_of_tfm_sizes(a_tfm) != a_tfm->wlenfile) { + if (tfm_filesize/4 > a_tfm->wlenfile) { + fprintf(stderr, "\nHmm. A TFM file is larger than it says it is!"); + fprintf(stderr, "\nProceeding nervously...\n"); + } else { + fprintf(stderr, "TFM file problem. Table sizes don't agree.\n"); + exit(1); + } + } +} + +static int ofm_get_sizes (struct a_tfm *a_tfm) +{ + SIGNED_QUAD level; + level = get_signed_quad(); + a_tfm -> wlenfile = get_signed_quad(); + a_tfm -> wlenheader = get_signed_quad(); + a_tfm -> bc = get_signed_quad(); + a_tfm -> ec = get_signed_quad(); + if (a_tfm -> ec < a_tfm -> bc) { + fprintf(stderr, "OFM file error (ec < bc)\n"); + exit(1); + } + a_tfm -> nwidths = get_signed_quad(); + a_tfm -> nheights = get_signed_quad(); + a_tfm -> ndepths = get_signed_quad(); + a_tfm -> nitcor = get_signed_quad(); + a_tfm -> nlig = get_signed_quad(); + a_tfm -> nkern = get_signed_quad(); + a_tfm -> nextens = get_signed_quad(); + a_tfm -> nfonparm = get_signed_quad(); + a_tfm -> font_direction = get_signed_quad(); + if (a_tfm->font_direction) { + fprintf (stderr, "Warning: I may be interpreting a font direction incorrectly.\n"); + } + if (level == 0) { + if (a_tfm -> wlenfile != tfm_filesize/4 || + sum_of_ofm_sizes (a_tfm) != a_tfm -> wlenfile) { + fprintf(stderr, "OFM file problem. Table sizes don't agree.\n"); + exit(1); + } +#ifdef DEBUG + fprintf (stderr, "Computed size (words)%ld\n", sum_of_ofm_sizes (a_tfm)); + fprintf (stderr, "Stated size (words)%ld\n", a_tfm -> wlenfile); + fprintf (stderr, "Actual size (bytes)%ld\n", tfm_filesize); +#endif + } else if (level == 1) { + a_tfm -> nco = get_signed_quad(); + a_tfm -> ncw = get_signed_quad(); + a_tfm -> npc = get_signed_quad(); + fseek(tfm_file, 4*(a_tfm -> nco), SEEK_SET); + } else { + fprintf(stderr, "Can't handle OFM files with level > 1"); + exit(1); + } + return (int) (level); +} + +static void dump_sizes (struct a_tfm *a_tfm) +{ + fprintf (stderr, "\nwlenfile: %ld, ", a_tfm -> wlenfile); + fprintf (stderr, "wlenheader: %ld\n", a_tfm -> wlenheader); + fprintf (stderr, "bc: %ld, ", a_tfm -> bc); + fprintf (stderr, "ec: %ld, ", a_tfm -> ec); + fprintf (stderr, "nwidths: %ld, ", a_tfm -> nwidths); + fprintf (stderr, "nheights: %ld, ", a_tfm -> nheights); + fprintf (stderr, "ndepths: %ld\n", a_tfm -> ndepths); + fprintf (stderr, "nitcor: %ld, ", a_tfm -> nitcor); + fprintf (stderr, "nlig: %ld, ", a_tfm -> nlig); + fprintf (stderr, "nkern: %ld, ", a_tfm -> nkern); + fprintf (stderr, "nextens: %ld, ", a_tfm -> nextens); + fprintf (stderr, "nfonparm: %ld\n", a_tfm -> nfonparm); + return; +} + + +static void get_fix_word_array (SIGNED_QUAD *a_word, SIGNED_QUAD length) +{ + register SIGNED_QUAD i; + for (i = 0; i < length; i++) + a_word[i] = get_signed_quad(); +} + +static void get_unsigned_quad_array (UNSIGNED_QUAD *a_word, SIGNED_QUAD length) +{ + register SIGNED_QUAD i; + for (i = 0; i < length; i++) + a_word[i] = get_unsigned_quad(); +} + +static void do_fix_word_array (SIGNED_QUAD **a, SIGNED_QUAD len) +{ + if (len != 0) { + *a = (SIGNED_QUAD *)calloc(len, sizeof(SIGNED_QUAD)); + get_fix_word_array(*a, len); + } else + *a = NULL; +} + +static void do_unsigned_quad_array (UNSIGNED_QUAD **a, UNSIGNED_PAIR len) +{ + if (len != 0) { + *a = (UNSIGNED_QUAD *)calloc(len, sizeof(UNSIGNED_QUAD)); + get_unsigned_quad_array(*a, len); + } else + *a = NULL; +} + +static void do_char_type_array(struct a_tfm *a_tfm) +{ + UNSIGNED_PAIR charcode; + UNSIGNED_PAIR chartype; + register int i; + + a_tfm -> chartypes = (UNSIGNED_PAIR *)calloc(65536, sizeof(UNSIGNED_PAIR)); + for (i = 0; i < 65536; i++) (a_tfm->chartypes)[i] = 0; + for (i = 0; i < a_tfm->nt; i++) { + charcode = get_unsigned_pair(); + chartype = get_unsigned_pair(); + (a_tfm->chartypes)[charcode] = chartype; + } +} + +static void unpack_widths(struct a_tfm *a_tfm) +{ + UNSIGNED_QUAD charinfo; + UNSIGNED_PAIR width_index; + register int i; + + a_tfm -> unpacked_widths = (fixword *)calloc(256, sizeof(fixword)); + for (i = 0; i < 256; i++) (a_tfm ->unpacked_widths)[i] = 0; + for (i = (a_tfm->bc); i <= (a_tfm->ec); i++) { + charinfo = (a_tfm->char_info)[i-(a_tfm->bc)]; + width_index = (charinfo / 16777216UL); + (a_tfm->unpacked_widths)[i] = (a_tfm->width)[width_index]; + } +} + +static void unpack_heights(struct a_tfm *a_tfm) +{ + UNSIGNED_QUAD charinfo; + UNSIGNED_PAIR height_index; + register int i; + + a_tfm -> unpacked_heights = (fixword *)calloc(256, sizeof(fixword)); + for (i = 0; i < 256; i++) (a_tfm ->unpacked_heights)[i] = 0; + for (i = (a_tfm->bc); i <= (a_tfm->ec); i++) { + charinfo = (a_tfm->char_info)[i-(a_tfm->bc)]; + height_index = (charinfo / 0x100000UL) & 0x0F; + (a_tfm->unpacked_heights)[i] = (a_tfm->height)[height_index]; + } +} + +static void unpack_depths(struct a_tfm *a_tfm) +{ + UNSIGNED_QUAD charinfo; + UNSIGNED_PAIR depth_index; + register int i; + + a_tfm -> unpacked_depths = (fixword *)calloc(256, sizeof(fixword)); + for (i = 0; i < 256; i++) (a_tfm ->unpacked_depths)[i] = 0; + for (i = (a_tfm->bc); i <= (a_tfm->ec); i++) { + charinfo = (a_tfm->char_info)[i-(a_tfm->bc)]; + depth_index = (charinfo / 0x10000UL) & 0x0F; + (a_tfm->unpacked_depths)[i] = (a_tfm->depth)[depth_index]; + } +} + +static void get_arrays (struct a_tfm *a_tfm) +{ +#ifdef DEBUG + fprintf (stderr, "Reading %ld word header\n", a_tfm->wlenheader); +#endif + do_fix_word_array(&(a_tfm->header), a_tfm->wlenheader); + if (a_tfm->id == JFM_ID || a_tfm->id == JFMV_ID) + do_char_type_array(a_tfm); +#ifdef DEBUG + fprintf (stderr, "Reading %ld char_infos\n", (a_tfm->ec)-(a_tfm->bc)+1); +#endif + do_unsigned_quad_array(&(a_tfm->char_info), (a_tfm->ec)-(a_tfm->bc)+1); +#ifdef DEBUG + fprintf (stderr, "Reading %ld widths\n", a_tfm->nwidths); +#endif + do_fix_word_array(&(a_tfm->width), a_tfm->nwidths); +#ifdef DEBUG + fprintf (stderr, "Reading %ld heights\n", a_tfm->nheights); +#endif + do_fix_word_array(&(a_tfm->height), a_tfm->nheights); +#ifdef DEBUG + fprintf (stderr, "Reading %ld depths\n", a_tfm->ndepths); +#endif + do_fix_word_array(&(a_tfm->depth), a_tfm->ndepths); + unpack_widths(a_tfm); + unpack_heights(a_tfm); + unpack_depths(a_tfm); +} + +static void do_ofm_zero_char_info (struct a_tfm *a_tfm) +{ + UNSIGNED_QUAD num_chars; + register int i; + + num_chars = a_tfm->ec - a_tfm->bc + 1; + if (num_chars != 0) { + a_tfm->width_index = (UNSIGNED_PAIR *)calloc(num_chars, sizeof(UNSIGNED_PAIR)); + a_tfm->height_index = (UNSIGNED_BYTE *)calloc(num_chars, sizeof(UNSIGNED_BYTE)); + a_tfm->depth_index = (UNSIGNED_BYTE *)calloc(num_chars, sizeof(UNSIGNED_BYTE)); + a_tfm->unpacked_widths = (fixword *)calloc(a_tfm->bc+num_chars, sizeof(fixword)); + a_tfm->unpacked_heights = (fixword *)calloc(a_tfm->bc+num_chars, sizeof(fixword)); + a_tfm->unpacked_depths = (fixword *)calloc(a_tfm->bc+num_chars, sizeof(fixword)); + } + for (i = 0; i < num_chars; i++) { + (a_tfm->width_index)[i] = get_unsigned_pair(); + (a_tfm->height_index)[i] = get_unsigned_byte(); + (a_tfm->depth_index)[i] = get_unsigned_byte(); + get_signed_quad(); /* Ignore remaining quad */ + } +} + +static void do_ofm_one_char_info (struct a_tfm *a_tfm) +{ + UNSIGNED_QUAD num_char_infos, char_infos_read; + UNSIGNED_QUAD num_chars; + UNSIGNED_QUAD char_info_size; + UNSIGNED_QUAD i; + + char_info_size = 3 + (a_tfm->npc/2); + num_char_infos = (a_tfm->ncw) / char_info_size; + num_chars = (a_tfm->ec - a_tfm->bc) + 1; +#ifdef DEBUG + fprintf (stderr, "\nReading %ld level 1 chars\n", num_chars); +#endif + if (num_chars != 0) { + a_tfm->width_index = (UNSIGNED_PAIR *)calloc(num_chars, sizeof(UNSIGNED_PAIR)); + a_tfm->height_index = (UNSIGNED_BYTE *)calloc(num_chars, sizeof(UNSIGNED_BYTE)); + a_tfm->depth_index = (UNSIGNED_BYTE *)calloc(num_chars, sizeof(UNSIGNED_BYTE)); + a_tfm->unpacked_widths = (fixword *)calloc(a_tfm->bc+num_chars, sizeof(fixword)); + a_tfm->unpacked_heights = (fixword *)calloc(a_tfm->bc+num_chars, sizeof(fixword)); + a_tfm->unpacked_depths = (fixword *)calloc(a_tfm->bc+num_chars, sizeof(fixword)); + } + for (i = 0, char_infos_read = 0; i < num_chars && char_infos_read < num_char_infos; i++) { + register int repeats, j; + (a_tfm->width_index)[i] = get_unsigned_pair(); + (a_tfm->height_index)[i] = get_unsigned_byte(); + (a_tfm->depth_index)[i] = get_unsigned_byte(); + get_signed_quad(); /* Ignore next quad */ + repeats = get_unsigned_pair(); + /* Skip params */ + for (j = 0; j < a_tfm->npc; j++) get_unsigned_pair(); + /* Remove word padding if necessary */ + if ((a_tfm->npc / 2) * 2 == a_tfm->npc) get_unsigned_pair(); + char_infos_read += 1; + if (i+repeats > num_chars) { + fprintf(stderr, "repeats causes number of characters to be exceeded"); + exit(1); + } + for (j = 0; j < repeats; j++) { + a_tfm->width_index[i+j+1] = a_tfm->width_index[i]; + a_tfm->height_index[i+j+1] = a_tfm->height_index[i]; + a_tfm->depth_index[i+j+1] = a_tfm->depth_index[i]; + } + /* Skip ahead because we have already handled repeats */ + i += repeats; + } +#ifdef DEBUG + fprintf (stderr, "\npackets read = %ld/%ld\n", char_infos_read, num_char_infos); + fprintf (stderr, "\ncharacters defined = %ld/%ld\n", i, num_chars); +#endif +} + +static void ofm_unpack_arrays (struct a_tfm *a_tfm, UNSIGNED_QUAD num_chars) +{ + register int i; + for (i = 0; i < num_chars; i++) { + (a_tfm->unpacked_widths)[a_tfm->bc+i] = (a_tfm->width)[(a_tfm->width_index)[i]]; + (a_tfm->unpacked_heights)[a_tfm->bc+i] = (a_tfm->height)[(a_tfm->height_index)[i]]; + (a_tfm->unpacked_depths)[a_tfm->bc+i] = (a_tfm->depth)[(a_tfm->depth_index)[i]]; + } +} + +static void ofm_get_arrays (struct a_tfm *a_tfm, int level) +{ + switch (level) { + case 0: +#ifdef DEBUG + fprintf(stderr, "Reading %ld word header\n", a_tfm->wlenheader); +#endif + do_fix_word_array(&(a_tfm -> header), a_tfm -> wlenheader); +#ifdef DEBUG + fprintf(stderr, "Reading %ld char_infos\n", (a_tfm->ec)-(a_tfm->bc)+1); +#endif + do_ofm_zero_char_info(a_tfm); + break; + case 1: +#ifdef DEBUG + fprintf (stderr, "Reading %ld char_infos words\n", a_tfm->ncw); +#endif + do_ofm_one_char_info(a_tfm); + break; + default: + fprintf(stderr, "level != 0 or 1 in ofm_get_arrays()"); + exit(1); + } +#ifdef DEBUG + fprintf (stderr, "Reading %ld widths\n", a_tfm -> nwidths); +#endif + do_fix_word_array(&(a_tfm -> width), a_tfm -> nwidths); +#ifdef DEBUG + fprintf (stderr, "Reading %ld heights\n", a_tfm -> nheights); +#endif + do_fix_word_array(&(a_tfm -> height), a_tfm -> nheights); +#ifdef DEBUG + fprintf (stderr, "Reading %ld depths\n", a_tfm -> ndepths); +#endif + do_fix_word_array(&(a_tfm -> depth), a_tfm -> ndepths); + ofm_unpack_arrays(a_tfm, (a_tfm->ec)-(a_tfm->bc)+1); +} + +static void get_ofm (struct a_tfm *a_tfm) +{ + register int level; + level = ofm_get_sizes(a_tfm); + ofm_get_arrays(a_tfm, level); +} + +static void get_tfm (struct a_tfm *a_tfm) +{ + get_sizes(a_tfm); + get_arrays(a_tfm); +} + +/* External Routine */ +#define TFM_FORMAT 1 +#define OFM_FORMAT 2 + +int tfm_open (const char *tfm_name, int must_exist) +{ + int i, format; + char *file_name; + + for (i = 0; i < numtfms; i++) { + if (!strcmp(tfm_name, tfm[i].tex_name)) + return i; + } + + /* The procedure to search tfm or ofm files: + 1. Search tfm file with the given name with the must_exist flag unset. + 2. Search ofm file with the given name with the must_exist flag unset. + 3. If not found and must_exist flag is set, try again to search + tfm file with the must_exist flag set. + 4. If not found and must_exist flag is not set, return -1. */ + + if (file_name = kpse_find_file(tfm_name, kpse_tfm_format, 0)) + format = TFM_FORMAT; + else if (file_name = kpse_find_file(tfm_name, kpse_ofm_format, 0)) + format = OFM_FORMAT; + /* In case that must_exist is set, MiKTeX returns always non-NULL value + even if the tfm file is not found. */ + else if (must_exist) { + if (file_name = kpse_find_file(tfm_name, kpse_tfm_format, 1)) + format = TFM_FORMAT; + else { + fprintf(stderr, "\n** Fatal: Unable to find TFM file '%s'.\n", tfm_name); + exit(1); + } + } else + return -1; + + if (numtfms >= max_tfms) { + max_tfms += MAX_FONTS_STEP; + tfm = (struct a_tfm *)realloc(tfm, max_tfms * sizeof(struct a_tfm)); + } + + a_tfm_init(tfm + numtfms); + + if (!(tfm_file = fopen(file_name, "rb"))) { + fprintf(stderr, "\n** Fatal: Specified TFM/OFM file '%s' ", tfm_name); + fprintf(stderr, "cannot be opened.\n"); + exit(1); + } + + fseek(tfm_file, 0L, SEEK_END); + tfm_filesize = ftell(tfm_file); + rewind(tfm_file); + + if (tfm_filesize < 24) { + fprintf(stderr, "\n** Fatal: TFM/OFM file too small to be a valid file.\n"); + exit(1); + } + + if (format == OFM_FORMAT) get_ofm(&tfm[numtfms]); + else get_tfm(&tfm[numtfms]); + + tfm[numtfms].tex_name = (char *)calloc(strlen(tfm_name)+1, sizeof(char)); + strcpy(tfm[numtfms].tex_name, tfm_name); + fclose(tfm_file); + + return numtfms++; +} + +void tfm_close_all(void) +{ + int i; + for (i=0; i<numtfms; i++) { + if (tfm[i].header) + free(tfm[i].header); + if (tfm[i].char_info) + free(tfm[i].char_info); + if (tfm[i].width) + free(tfm[i].width); + if (tfm[i].height) + free(tfm[i].height); + if (tfm[i].depth) + free(tfm[i].depth); + free(tfm[i].tex_name); + free(tfm[i].unpacked_widths); + free(tfm[i].unpacked_heights); + free(tfm[i].unpacked_depths); + if (tfm[i].chartypes) + free(tfm[i].chartypes); + if (tfm[i].width_index) + free(tfm[i].width_index); + if (tfm[i].height_index) + free(tfm[i].height_index); + if (tfm[i].depth_index) + free(tfm[i].depth_index); + } + if (tfm) + free(tfm); +} + +/* tfm_get_width returns the width of the font + as a (double) fraction of the design size */ +double tfm_get_width (int font_id, UNSIGNED_QUAD ch) +{ + if (tfm[font_id].id == JFM_ID || tfm[font_id].id == JFMV_ID ) + ch = (tfm[font_id].chartypes)[ch]; + if (tfm[font_id].unpacked_widths && ch <= tfm[font_id].ec) + return (double) (tfm[font_id].unpacked_widths)[ch] / FWBASE; + else return 0.0; +} + +double tfm_get_height (int font_id, UNSIGNED_QUAD ch) +{ + if (tfm[font_id].id == JFM_ID || tfm[font_id].id == JFMV_ID ) + ch = (tfm[font_id].chartypes)[ch]; + if (tfm[font_id].unpacked_heights && ch <= tfm[font_id].ec) + return (double) (tfm[font_id].unpacked_heights)[ch] / FWBASE; + else return 0.0; +} + +double tfm_get_depth (int font_id, UNSIGNED_QUAD ch) +{ + if (tfm[font_id].id == JFM_ID || tfm[font_id].id == JFMV_ID ) + ch = (tfm[font_id].chartypes)[ch]; + if (tfm[font_id].unpacked_depths && ch <= tfm[font_id].ec) + return (tfm[font_id].unpacked_depths)[ch]/FWBASE; + else return 0.0; +} + +fixword tfm_get_fw_width (int font_id, UNSIGNED_QUAD ch) +{ + if (tfm[font_id].id == JFM_ID || tfm[font_id].id == JFMV_ID ) + ch = (tfm[font_id].chartypes)[ch]; + if (tfm[font_id].unpacked_widths && ch <= tfm[font_id].ec) { + return (tfm[font_id].unpacked_widths)[ch]; + } + return 0; +} + +fixword tfm_get_fw_height (int font_id, UNSIGNED_QUAD ch) +{ + if (tfm[font_id].id == JFM_ID || tfm[font_id].id == JFMV_ID ) + ch = (tfm[font_id].chartypes)[ch]; + if (tfm[font_id].unpacked_heights && ch <= tfm[font_id].ec) + return (tfm[font_id].unpacked_heights)[ch]; + return 0; +} + +fixword tfm_get_fw_depth (int font_id, UNSIGNED_QUAD ch) +{ + if (tfm[font_id].id == JFM_ID || tfm[font_id].id == JFMV_ID ) + ch = (tfm[font_id].chartypes)[ch]; + if (tfm[font_id].unpacked_depths && ch <= tfm[font_id].ec) + return (tfm[font_id].unpacked_depths)[ch]; + return 0; +} + +fixword tfm_string_width (int font_id, unsigned char *s, unsigned len) +{ + fixword result = 0; + unsigned i; + if (tfm[font_id].unpacked_widths) + for (i=0; i<len; i++) { + if (s[i] <= tfm[font_id].ec) + result += tfm[font_id].unpacked_widths[s[i]]; + } + return result; +} + +fixword tfm_string_depth (int font_id, unsigned char *s, unsigned len) +{ + fixword result = 0; + unsigned i; + if (tfm[font_id].unpacked_depths) + for (i=0; i<len; i++) { + if (s[i] <= tfm[font_id].ec) + result = (result > tfm[font_id].unpacked_depths[s[i]] ? result : tfm[font_id].unpacked_depths[s[i]]); + } + return result; +} + +fixword tfm_string_height (int font_id, unsigned char *s, unsigned len) +{ + fixword result = 0; + unsigned i; + if (tfm[font_id].unpacked_heights) + for (i=0; i<len; i++) { + if (s[i] <= tfm[font_id].ec) + result = (result > tfm[font_id].unpacked_heights[s[i]-tfm[font_id].bc] ? result : tfm[font_id].unpacked_heights[s[i]-tfm[font_id].bc]); + } + return result; +} + +UNSIGNED_PAIR tfm_get_firstchar (int font_id) +{ + return tfm[font_id].bc; +} + +UNSIGNED_PAIR tfm_get_lastchar (int font_id) +{ + return tfm[font_id].ec; +} + +double tfm_get_design_size (int font_id) +{ + return ((tfm[font_id].header))[1]/FWBASE*(72.0/72.27); +} + + +double tfm_get_max_width (int font_id) +{ + SIGNED_QUAD max = 0; + int i; + for (i=0; i<tfm[font_id].nwidths; i++) { + if ((tfm[font_id].width)[i] > max) + max = (tfm[font_id].width)[i]; + } + return (max/FWBASE); +} + +int tfm_is_fixed_width (int font_id) +{ + /* We always have two widths since width[0] = 0. + A fixed width font will have width[1] = something + and not have any other widths */ + return (tfm[font_id].nwidths == 2); +} + +double tfm_get_max_height (int font_id) +{ + SIGNED_QUAD max = 0; + int i; + for (i=0; i<tfm[font_id].nheights; i++) { + if ((tfm[font_id].height)[i] > max) + max = (tfm[font_id].height)[i]; + } + return (max/FWBASE); +} + +double tfm_get_max_depth (int font_id) +{ + SIGNED_QUAD max = 0; + int i; + for (i=0; i<tfm[font_id].ndepths; i++) { + if ((tfm[font_id].depth)[i] > max) + max = (tfm[font_id].depth)[i]; + } + return (max/FWBASE); +} + +char is_jfm (int font_id) +{ + return (tfm[font_id].id == JFM_ID || tfm[font_id].id == JFMV_ID) ? 1 : 0; +} + +char is_vertical (int font_id) /* Vertical version of JFM */ +{ + return (tfm[font_id].id == JFMV_ID) ? 1 : 0; +} + diff --git a/Build/source/texk/dvipos/tfm.h b/Build/source/texk/dvipos/tfm.h new file mode 100644 index 00000000000..3779ecc0a48 --- /dev/null +++ b/Build/source/texk/dvipos/tfm.h @@ -0,0 +1,63 @@ +/* $Header + + dvipos-20030225 + + Copyright (C) 2003 by Jin-Hwan Cho <chofchof@ktug.or.kr> + + Copyright (C) 2002 by Jin-Hwan Cho and Shunsaku Hirata, + the dvipdfmx project team <dvipdfmx@project.ktug.or.kr> + + Copyright (C) 1998, 1999 by Mark A. Wicks <mwicks@kettering.edu> + + 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. +*/ + +#ifndef _TFM_H_ +#define _TFM_H_ + +#include "dvicore.h" + +extern int tfm_open (const char * tex_name, int must_exist); +extern void tfm_close_all (void); + +extern double tfm_get_width (int font_id, UNSIGNED_QUAD ch); +extern double tfm_get_height (int font_id, UNSIGNED_QUAD ch); +extern double tfm_get_depth (int font_id, UNSIGNED_QUAD ch); +extern long tfm_get_fw_width (int font_id, UNSIGNED_QUAD ch); +extern long tfm_get_fw_height (int font_id, UNSIGNED_QUAD ch); +extern long tfm_get_fw_depth (int font_id, UNSIGNED_QUAD ch); +extern long tfm_string_width (int font_id, unsigned char *s, + unsigned len); +extern long tfm_string_depth (int font_id, unsigned char *s, + unsigned len); +extern long tfm_string_height (int font_id, unsigned char *s, + unsigned len); +extern double tfm_get_space (int font_id); +extern double tfm_get_it_slant (int font_id); +extern double tfm_get_x_height (int font_id); + +extern UNSIGNED_PAIR tfm_get_firstchar (int font_id); +extern UNSIGNED_PAIR tfm_get_lastchar (int font_id); + +extern double tfm_get_design_size (int font_id); +extern double tfm_get_max_height (int font_id); +extern double tfm_get_max_width (int font_id); +extern int tfm_is_fixed_width (int font_id); +extern double tfm_get_max_depth (int font_id); +extern char is_jfm (int font_id); +extern char is_vertical (int font_id); + +#endif /* _TFM_H_ */ + diff --git a/Build/source/texk/dvipos/win32.mak b/Build/source/texk/dvipos/win32.mak new file mode 100644 index 00000000000..dc4f1efc985 --- /dev/null +++ b/Build/source/texk/dvipos/win32.mak @@ -0,0 +1,58 @@ +################################################################################ +# +# Makefile : Dvipos +# Author : Fabrice Popineau <Fabrice.Popineau@supelec.fr> +# Platform : Win32, Microsoft VC++ 6.0, depends upon fpTeX 0.7 sources +# Time-stamp: <03/02/26 15:51:47 popineau> +# +################################################################################ +root_srcdir = ..\.. +!ifdef DEVELOPMENT +INCLUDE=$(INCLUDE);$(root_srcdir)\texk.development +!else +INCLUDE=$(INCLUDE);$(root_srcdir)\texk +!endif + +# Makefile for ttfdump + +USE_GNUW32 = 1 +USE_KPATHSEA = 1 + +!include <msvc/common.mak> + +DEFS = -I.. $(DEFS) -DHAVE_CONFIG_H \ + -I..\crypto +# -DWITHOUT_OPENSSL +# -DWITHOUT_TOUNICODE + +manfiles = +objects = \ + $(objdir)\dvicore.obj \ + $(objdir)\dvipos.obj \ + $(objdir)\tfm.obj + +program = $(objdir)\dvipos.exe +programs = $(program) + +default: all + +all: $(objdir) $(programs) + +$(program): $(objects) $(kpathsealib) + $(link) $(**) $(conlibs) + +!include <msvc/config.mak> +!include <msvc/install.mak> + +install:: install-exec install-man + +!include <msvc/clean.mak> + +!include <msvc/rdepend.mak> +!include "./depend.mak" + +# +# Local variables: +# page-delimiter: "^# \f" +# mode: Makefile +# End: |