diff options
author | Karl Berry <karl@freefriends.org> | 2007-01-10 16:51:06 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2007-01-10 16:51:06 +0000 |
commit | 6bbcb6d005d8788677d5e132889de498d5fd62fb (patch) | |
tree | ae6455b860725a73219151172af2064695938b27 /Build/source/texk/dvipos | |
parent | 906465a305515a397c4957e7241dfd57a0fcb9fc (diff) |
include dvipos for context
git-svn-id: svn://tug.org/texlive/trunk@3293 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/dvipos')
-rw-r--r-- | Build/source/texk/dvipos/Makefile | 95 | ||||
-rwxr-xr-x | Build/source/texk/dvipos/configure | 3 | ||||
-rw-r--r-- | Build/source/texk/dvipos/depend.mak | 173 | ||||
-rw-r--r-- | Build/source/texk/dvipos/dvicore.c | 1731 | ||||
-rw-r--r-- | Build/source/texk/dvipos/dvicore.h | 23 | ||||
-rw-r--r-- | Build/source/texk/dvipos/dvipos.1 | 136 | ||||
-rw-r--r-- | Build/source/texk/dvipos/dvipos.c | 271 | ||||
-rw-r--r-- | Build/source/texk/dvipos/miktex.mak | 95 | ||||
-rw-r--r-- | Build/source/texk/dvipos/tfm.c | 141 | ||||
-rw-r--r-- | Build/source/texk/dvipos/tfm.h | 1 | ||||
-rw-r--r-- | Build/source/texk/dvipos/utils.c | 215 | ||||
-rw-r--r-- | Build/source/texk/dvipos/utils.h | 87 | ||||
-rw-r--r-- | Build/source/texk/dvipos/win32.mak | 54 |
13 files changed, 1995 insertions, 1030 deletions
diff --git a/Build/source/texk/dvipos/Makefile b/Build/source/texk/dvipos/Makefile new file mode 100644 index 00000000000..79be969242d --- /dev/null +++ b/Build/source/texk/dvipos/Makefile @@ -0,0 +1,95 @@ +# Generated automatically from Makefile.in by configure. +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999, 2001, 2007 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = /bin/sh + +# UNIX/Linux (check /usr/local/share/texmf) +prefix = /usr/local +# SUN Solaris (check /usr/local/teTeX) +#prefix = /usr/local/teTeX +# CYGWIN (check /usr/share/texmf) +#prefix = /usr +exec_prefix = ${prefix} + +bindir = ${exec_prefix}/bin +libdir = ${exec_prefix}/lib +mandir = ${prefix}/man +includedir = ${prefix}/include + +INSTALL = /usr/bin/install -c +transform = s,x,x, + +NORMAL_INSTALL = : +NORMAL_UNINSTALL = : +CC = gcc +LN_S = ln -s +PACKAGE = dvipos +VERSION = 20070107 + +PROGRAMS = dvipos +SOURCES = dvicore.c dvipos.c tfm.c utils.c dvicore.h tfm.h utils.h + +#mkinstalldirs = $(SHELL) ./mkinstalldirs + +DEFS = -DKPATHSEA -I. +CPPFLAGS = -I${includedir} +LDFLAGS = -L${libdir} +kpathsea = ../kpathsea/.libs/libkpathsea.a +LIBS = ${kpathsea} -lm +OBJECTS = dvicore.o dvipos.o tfm.o utils.o + +CFLAGS = -g -O2 +COMPILE = $(CC) $(DEFS) $(CPPFLAGS) $(CFLAGS) +LINK = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ + +all: $(PROGRAMS) +.SUFFIXES: .c .o + +clean: + -rm -f *.o core *.core + -test -z "$(PROGRAMS)" || rm -f $(PROGRAMS) + +install: $(PROGRAMS) + @$(NORMAL_INSTALL) +# $(mkinstalldirs) $(DESTDIR)$(bindir) + @list='$(PROGRAMS)'; for p in $$list; do \ + if test -f $$p; then \ + echo " $(INSTALL) $$p $(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ + $(INSTALL) $$p $(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + else :; fi; \ + done + +install-man: dvipos.1 + $(INSTALL) dvipos.1 $(mandir)/man1/ + +uninstall: + @$(NORMAL_UNINSTALL) + list='$(PROGRAMS)'; for p in $$list; do \ + rm -f $(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \ + done + +uninstall-man: + rm -f $(mandir)/man1/dvipos.1 + +.c.o: + $(COMPILE) -c $< + +dvipos: $(OBJECTS) + @rm -f dvipos + $(LINK) $(LDFLAGS) $(OBJECTS) $(LDADD) $(LIBS) + +dvipos.o: dvipos.c dvicore.h utils.h +dvicore.o: dvicore.c dvicore.h tfm.h utils.h +tfm.o: tfm.c tfm.h dvicore.h utils.h +utils.o: utils.c utils.h diff --git a/Build/source/texk/dvipos/configure b/Build/source/texk/dvipos/configure new file mode 100755 index 00000000000..04a2e945cad --- /dev/null +++ b/Build/source/texk/dvipos/configure @@ -0,0 +1,3 @@ +#!/bin/sh +echo "dvipos configure is a no-op." +true diff --git a/Build/source/texk/dvipos/depend.mak b/Build/source/texk/dvipos/depend.mak index ff66d554120..e7be419f3c5 100644 --- a/Build/source/texk/dvipos/depend.mak +++ b/Build/source/texk/dvipos/depend.mak @@ -1,169 +1,4 @@ -$(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 - +dvipos.o: dvipos.c dvicore.h utils.h +dvicore.o: dvicore.c dvicore.h tfm.h utils.h +tfm.o: tfm.c tfm.h dvicore.h utils.h +utils.o: utils.c utils.h diff --git a/Build/source/texk/dvipos/dvicore.c b/Build/source/texk/dvipos/dvicore.c index 3974a45cd0e..6da32d1da90 100644 --- a/Build/source/texk/dvipos/dvicore.c +++ b/Build/source/texk/dvipos/dvicore.c @@ -1,6 +1,6 @@ -/* $Header +/* $Header: /home/cvsroot/dvipos/dvicore.c,v 1.8 2003/06/28 05:43:40 chofchof Exp $ - dvipos-20030225 + dvipos-20030628 Copyright (C) 2003 by Jin-Hwan <chofchof@ktug.or.kr> @@ -19,40 +19,318 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include "utils.h" #include "dvicore.h" #include "tfm.h" +#include <math.h> +#include <time.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; +static FILE *dvi_file; +static SIGNED_QUAD dvi_fsize, dvi_location; +static SIGNED_QUAD post_location, post_post_location, *page_location = NULL; +static SIGNED_QUAD prev_page_location = -1; +static int current_page, new_dvi_pages = 0; #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; + SIGNED_QUAD h, v, w, x, y, z, d, hh, vv; } dvi_state, dvi_stack[DVI_MAX_STACK_DEPTH]; -static int dvi_current_font = -1, num_dvi_fonts = 0, max_dvi_fonts = 0; +static int cur_font = -1, num_dvi_fonts = 0, max_dvi_fonts = 0; static struct dvi_font { - SIGNED_QUAD size, id; int tfm_id, used; char *name; + SIGNED_QUAD size, id; /* size == scaled_size */ + 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_QUAD numerator, denominator, dvi_mag, new_mag, mag; +static double tfm_conv, true_conv, conv, resolution; + +static UNSIGNED_BYTE id; +static SIGNED_QUAD max_v, max_h, max_v_so_far, max_h_so_far; static SIGNED_PAIR max_s, total_pages; +static SIGNED_PAIR max_s_so_far, page_count; + +typedef struct a_bbox { + SIGNED_QUAD h1, v1, h2, v2, fb, cb; /* first and current baseline */ + int type, lev_s; + unsigned char *tag; + struct a_bbox *next; +} BBOX; +static BBOX page_bbox; + +static char comment[257]; /* 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 void calc_bbox (SIGNED_QUAD width, SIGNED_QUAD height, SIGNED_QUAD depth) +{ + BBOX *bb = &page_bbox; + + if (do_smashchars) height = depth = 0; + + while (bb) { + if (bb->fb == -INFINITY) bb->fb = dvi_state.v; + bb->cb = dvi_state.v; + if (bb->h1 > dvi_state.h) bb->h1 = dvi_state.h; + if (bb->v1 > dvi_state.v - height) bb->v1 = dvi_state.v - height; + if (bb->h2 < dvi_state.h + width) bb->h2 = dvi_state.h + width; + if (bb->v2 < dvi_state.v + depth) bb->v2 = dvi_state.v + depth; + bb = bb->next; + } +} + +#define PAGE_TYPE 0 +#define BOX_TYPE 1 +#define LINES_TYPE 2 +#define LINES_TYPE_SUSPEND 3 + +static void draw_frame (BBOX *bb) +{ + SIGNED_QUAD width, height; + + width = bb->h2 - bb->h1 + 2 * rule_width; + height = bb->v2 - bb->v1 + 2 * rule_width; + + /* color special */ + put_unsigned_byte(XXX1, frmfp); + put_unsigned_byte(20, frmfp); + switch (bb->type) { + case BOX_TYPE: + fwrite("color push rgb 0 1 0", 1, 20, frmfp); + break; + case LINES_TYPE: + fwrite("color push rgb 0 0 1", 1, 20, frmfp); + break; + case PAGE_TYPE: + default: + fwrite("color push rgb 1 0 0", 1, 20, frmfp); + break; + } + dbg_location += 20; + + /* push the current state */ + put_unsigned_byte(PUSH, frmfp); + + /* move to ll corner plus (-rule_width,rule_width) */ + put_unsigned_byte(RIGHT4, frmfp); + put_signed_quad(-dvi_state.h + bb->h1 - rule_width, frmfp); + put_unsigned_byte(DOWN4, frmfp); + put_signed_quad(-dvi_state.v + bb->v2 + rule_width, frmfp); + + /* draw a horizontal line connecting ll corner to lr corner */ + put_unsigned_byte(PUT_RULE, frmfp); + put_signed_quad(rule_width, frmfp); + put_signed_quad(width, frmfp); + + /* draw a vertical line connecting ll corner to ul corner */ + put_unsigned_byte(PUT_RULE, frmfp); + put_signed_quad(height, frmfp); + put_signed_quad(rule_width, frmfp); + + /* push the location of ll corner */ + put_unsigned_byte(PUSH, frmfp); + + /* move to ul corner plus (-rule_width,0) */ + put_unsigned_byte(DOWN4, frmfp); + put_signed_quad(-bb->v2 + bb->v1 - rule_width, frmfp); + + /* draw a horizontal line connecting ul corner to ur corner */ + put_unsigned_byte(PUT_RULE, frmfp); + put_signed_quad(rule_width, frmfp); + put_signed_quad(width, frmfp); + + /* restore the location of ll corner */ + put_unsigned_byte(POP, frmfp); + + /* move to lr corner plus (0,rule_width) */ + put_unsigned_byte(RIGHT4, frmfp); + put_signed_quad(-bb->h1 + bb->h2 + rule_width, frmfp); + + /* draw a vertical line connecting ll corner to ul corner */ + put_unsigned_byte(PUT_RULE, frmfp); + put_signed_quad(height, frmfp); + put_signed_quad(rule_width, frmfp); + + /* restore the original location */ + put_unsigned_byte(POP, frmfp); + + /* restore color special */ + put_unsigned_byte(XXX1, frmfp); + put_unsigned_byte(9, frmfp); + fwrite("color pop", 1, 9, frmfp); + dbg_location += 9; +} + +static void reset_bbox (BBOX *bb) +{ + bb->h1 = bb->v1 = INFINITY; + bb->h2 = bb->v2 = -INFINITY; + bb->fb = bb->cb = -INFINITY; +} + +static void clear_bbox (int init) +{ + /* calculate bounding box of each page */ + reset_bbox(&page_bbox); + page_bbox.tag = "pagebb"; + page_bbox.type = PAGE_TYPE; + if (init) page_bbox.next = NULL; +} + +static void new_bbox (unsigned char *tag, int type) +{ + BBOX *bb = &page_bbox; + + while (bb->next) { +// if (strcmp(tag, (bb->next)->tag) == 0) { +// msg_out(M_WARNING, "Warning: Found an entry with the same tag (%s).\n", tag); +// return; +// } + bb = bb->next; + } + + /* allocate a new entry */ + bb = bb->next = (BBOX *)xmalloc(sizeof(BBOX)); + bb->tag = xstrdup(tag); + bb->next = NULL; + bb->lev_s = dvi_stack_depth; + bb->type = type; + + reset_bbox(bb); + + if (bbxfp && bb->type == LINES_TYPE) + fprintf(bbxfp, "\n## KEY & TAG\nbeglines & \"%s\"\n", bb->tag); +} + +static void write_bbox (BBOX *bb) +{ + if (bbxfp) { + fprintf(bbxfp, "\"%d.%04X & ", (bb->fb / 65536), (bb->fb < 0 ? -1 : 1) * (bb->fb % 65536)); + fprintf(bbxfp, "\"%d.%04X \"%d.%04X \"%d.%04X \"%d.%04X & ", + (bb->v1 / 65536), (bb->v1 < 0 ? -1 : 1) * (bb->v1 % 65536), + (bb->h1 / 65536), (bb->h1 < 0 ? -1 : 1) * (bb->h1 % 65536), + (bb->v2 / 65536), (bb->v2 < 0 ? -1 : 1) * (bb->v2 % 65536), + (bb->h2 / 65536), (bb->h2 < 0 ? -1 : 1) * (bb->h2 % 65536)); + fprintf(bbxfp, "\"%d.%04X\n", (bb->cb / 65536), (bb->cb < 0 ? -1 : 1) * (bb->cb % 65536)); +/* + fprintf(bbxfp, "\"%ld & ", bb->fb); + fprintf(bbxfp, "\"%ld \"%ld \"%ld \"%ld & ", bb->v1, bb->h1, bb->v2, bb->h2); + fprintf(bbxfp, "\"%ld\n", bb->cb); +*/ + } +} + +static void flush_bbox (BBOX *bb) +{ + if (bb == NULL) return; + if (frmfp) draw_frame(bb); + if (bbxfp) { + switch (bb->type) { + case PAGE_TYPE: + fprintf(bbxfp, "\n## KEY & PAGENO & ENTRY-V & TOP-V LEFT-H BOTTOM-V RIGHT-H & EXIT-V\n"); + fprintf(bbxfp, "%s & %d & ", "pagebb", current_page); + write_bbox(bb); + break; + case BOX_TYPE: + fprintf(bbxfp, "\n## KEY & TAG & ENTRY-V & TOP-V LEFT-H BOTTOM-V RIGHT-H & EXIT-V\n"); + fprintf(bbxfp, "%s & \"%s\" & ", "box", bb->tag); + write_bbox(bb); + break; + case LINES_TYPE: + fprintf(bbxfp, " %s & ", "line"); + write_bbox(bb); + break; + case LINES_TYPE_SUSPEND: + bb->type = LINES_TYPE; + fprintf(bbxfp, "\n[resume]lines & \"%s\"\n", bb->tag); + fprintf(bbxfp, " %s & ", "line"); + write_bbox(bb); + default: + break; + } + } +} + +static void close_bbox (char *tag) +{ + BBOX *obb = &page_bbox, *nbb = obb->next; + + /* find the entry with the same tag */ + while (nbb) + if (strcmp(nbb->tag, tag) == 0) { + flush_bbox(nbb); + if (bbxfp && nbb->type == LINES_TYPE) + fprintf(bbxfp, "endlines & \"%s\"\n", nbb->tag); + free(nbb->tag); + obb->next = (nbb->next ? nbb->next : NULL); + free(nbb); + break; + } else { + if (bbxfp && nbb->type == LINES_TYPE) { + fprintf(bbxfp, "[suspend]lines & \"%s\"\n", nbb->tag); + nbb->type = LINES_TYPE_SUSPEND; + } + obb = nbb; + nbb = nbb->next; + } +} + +static UNSIGNED_BYTE dvi_unsigned_byte (void) +{ + dvi_location++; + return get_unsigned_byte(dvi_file); +} + +static SIGNED_BYTE dvi_signed_byte (void) +{ + dvi_location++; + return get_signed_byte(dvi_file); +} + +static UNSIGNED_PAIR dvi_unsigned_pair (void) +{ + dvi_location += 2; + return get_unsigned_pair(dvi_file); +} + +static SIGNED_PAIR dvi_signed_pair (void) +{ + dvi_location += 2; + return get_signed_pair(dvi_file); +} + +static UNSIGNED_PAIR dvi_unsigned_triple (void) +{ + dvi_location += 3; + return get_unsigned_triple(dvi_file); +} + +static SIGNED_PAIR dvi_signed_triple (void) +{ + dvi_location += 3; + return get_signed_triple(dvi_file); +} + +static UNSIGNED_PAIR dvi_unsigned_quad (void) +{ + dvi_location += 4; + return get_unsigned_quad(dvi_file); +} + +static SIGNED_PAIR dvi_signed_quad (void) +{ + dvi_location += 4; + return get_signed_quad(dvi_file); +} static SIGNED_QUAD sqxfw (SIGNED_QUAD z, SIGNED_QUAD b) { @@ -75,332 +353,345 @@ static SIGNED_QUAD sqxfw (SIGNED_QUAD z, SIGNED_QUAD b) if (b0 == 0) return result; else if (b0 == 255) return (result - alpha); - fprintf(stderr, "[fatal] sqxfw(): TFM file is bad.\n"); - exit(1); + msg_out(M_FAIL, "[fatal] sqxfw(): TFM file is bad.\n"); } -static UNSIGNED_BYTE get_unsigned_byte (void) +static SIGNED_QUAD xround (double p) { -#ifdef DEBUG - dvi_location++; -#endif - return (UNSIGNED_BYTE)(fgetc(dvi_file) & 0xFF); + if (p < 0) + return (SIGNED_QUAD)ceil(p - .5); + else + return (SIGNED_QUAD)floor(p + .5); } -static SIGNED_BYTE get_signed_byte (void) +#define LINE_LENGTH 79 +/* 69. The flush_text procedure will empty the buffer if there is something + * in it. */ +static void flush_text (void) { - register UNSIGNED_BYTE byte = get_unsigned_byte(); - return (SIGNED_BYTE)(byte & 0x80 ? byte - 0x100 : byte); + if (dvi_buffer_len > 0) { + dvi_buffer[dvi_buffer_len] = 0; + msg_out(M_DEBUG, "[%s]\n", dvi_buffer); + dvi_buffer_len = 0; + } } -static UNSIGNED_PAIR get_unsigned_pair (void) +/* 70. And the out_text procedure puts something in it. */ +static void out_text (char c) { - register UNSIGNED_PAIR pair = get_unsigned_byte(); - /* Read the second byte */ - pair = pair << 8; pair += get_unsigned_byte(); - return pair; + if (dvi_buffer_len == LINE_LENGTH - 2) flush_text(); + dvi_buffer[dvi_buffer_len++] = c; } -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; -} +#define INFINITY 0x7FFFFFFFL //017777777777 +#define MAX_DRIFT 2 +#define PIXEL_ROUND(p) xround(conv*(p)) -static UNSIGNED_TRIPLE get_unsigned_triple (void) +static void move_right (SIGNED_QUAD q) { - 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; -} + SIGNED_QUAD h, hh, hhh; -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; + h = dvi_state.h; hh = dvi_state.hh; + + if (h > 0 && q > 0 && h > INFINITY - q) { + msg_out(M_DEBUG, " arithmetic overflow! parameter changed from '%ld' to '%ld'\n", q, INFINITY - h); + q = INFINITY - h; + } + if (h < 0 && q < 0 && -h > q + INFINITY) { + msg_out(M_DEBUG, " arithmetic overflow! parameter changed from '%ld' to '%ld'\n", q, (-h) - INFINITY); + q = (-h) - INFINITY; + } + hhh = PIXEL_ROUND(h + q); + if (labs(hhh - hh) > MAX_DRIFT) { + if (hhh > hh) hh = hhh - MAX_DRIFT; + else hh = hhh + MAX_DRIFT; + } + msg_out(M_DEBUG, " h:=%ld", h); + if (q >= 0) msg_out(M_DEBUG, "+"); + msg_out(M_DEBUG, "%ld=%ld, hh:=%ld", q, h + q, hh); + h = h + q; + if (labs(h) > max_h_so_far) { + if (labs(h) > max_h + 99) { + msg_out(M_DEBUG, " warning: |h|>%ld!", max_h); + max_h = labs(h); + } + max_h_so_far = labs(h); + } + msg_out(M_DEBUG, " \n"); + dvi_state.h = h; dvi_state.hh = hh; } -static UNSIGNED_QUAD get_unsigned_quad (void) +/* 92. <Finish a command that sets v = v + p, then goto done> */ +static void move_down (SIGNED_QUAD p) { - 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; + SIGNED_QUAD v, vv, vvv; + + v = dvi_state.v; vv = dvi_state.vv; + + if (v > 0 && p > 0 && v > INFINITY - p) { + msg_out(M_DEBUG, " arithmetic overflow! parameter changed from '%ld' to '%ld'\n", p, INFINITY - v); + p = INFINITY - v; + } + if (v < 0 && p < 0 && -v > p + INFINITY) { + msg_out(M_DEBUG, " arithmetic overflow! parameter changed from '%ld' to '%ld'\n", p, (-v) - INFINITY); + p = (-v) - INFINITY; + } + vvv = PIXEL_ROUND(v + p); + if (labs(vvv - vv) > MAX_DRIFT) { + if (vvv > vv) vv = vvv - MAX_DRIFT; + else vv = vvv + MAX_DRIFT; + } + msg_out(M_DEBUG, " v:=%ld", v); + if (p >= 0) msg_out(M_DEBUG, "+"); + msg_out(M_DEBUG, "%ld=%ld, vv:=%ld", p, v + p, vv); + v = v + p; + if (labs(v) > max_v_so_far) { + if (labs(v) > max_v + 99) { + msg_out(M_DEBUG, " warning: |v|>%ld!", max_v); + max_v = labs(v); + } + max_v_so_far = labs(v); + } + msg_out(M_DEBUG, " \n"); + dvi_state.v = v; dvi_state.vv = vv; } -static SIGNED_QUAD get_signed_quad (void) +/* 84. Rounding to the nearest pixel is best done in the manner shown here, + * so as to be inoffensive to the eye: When the horizontal motion is small, + * like a kern, hh changes by rounding the kern; but when the motion is + * large, hh changes by rounding the true position h so that accumulated + * rounding errors disappear. We allow a larger space in the negative + * direction than in the positive one, because \TeX{} makes comparatively + * large backspaces when it positions accents. */ +static void out_space (SIGNED_QUAD p) { - 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; + SIGNED_QUAD font_space; + + font_space = (cur_font >= 0 ? dvi_fonts[cur_font].size / 6 : 0); + + if (p >= font_space || p <= -4 * font_space) { + out_text(' '); + dvi_state.hh = PIXEL_ROUND(dvi_state.h + p); + } else + dvi_state.hh += PIXEL_ROUND(p); + + move_right(p); } -static void dvi_clear_state (void) +/* 85. Vertical motion is done similarly, but with the threshold between + * ``small'' and ``large'' increased by a factor of five. The idea is to + * make fractions like ``1\over2'' round consistently, but to absorb + * accumulated rounding errors in the baseline-skip moves. */ +static void out_vmove (SIGNED_QUAD p) { - 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; + SIGNED_QUAD font_space; + + font_space = (cur_font >= 0 ? dvi_fonts[cur_font].size / 6 : 0); + + if (labs(p) >= 5 * font_space) + dvi_state.vv = PIXEL_ROUND(dvi_state.v + p); + else + dvi_state.vv += PIXEL_ROUND(p); + + move_down(p); } static void do_space (UNSIGNED_BYTE opcode) { SIGNED_QUAD x; + msg_out(M_DEBUG, "%ld: ", dvi_location); 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 + x = dvi_signed_byte(); + if (frmfp) put_signed_byte(x, frmfp); + msg_out(M_DEBUG, "right1"); break; case RIGHT2: - x = get_signed_pair(); -#ifdef DEBUG - fprintf(stderr, "%ld: right2 %ld ", dvi_location-2, x); - dvi_buffer[dvi_buffer_len++] = ' '; -#endif + x = dvi_signed_pair(); + if (frmfp) put_signed_pair(x, frmfp); + msg_out(M_DEBUG, "right2"); break; case RIGHT3: - x = get_signed_triple(); -#ifdef DEBUG - fprintf(stderr, "%ld: right3 %ld ", dvi_location-3, x); - dvi_buffer[dvi_buffer_len++] = ' '; -#endif + x = dvi_signed_triple(); + if (frmfp) put_signed_triple(x, frmfp); + msg_out(M_DEBUG, "right3"); break; case RIGHT4: - x = get_signed_quad(); -#ifdef DEBUG - fprintf(stderr, "%ld: right4 %ld ", dvi_location-4, x); - dvi_buffer[dvi_buffer_len++] = ' '; -#endif + x = dvi_signed_quad(); + if (frmfp) put_signed_quad(x, frmfp); + msg_out(M_DEBUG, "right4"); break; case W0: x = dvi_state.w; -#ifdef DEBUG - fprintf(stderr, "%ld: w0 %ld ", dvi_location, x); - dvi_buffer[dvi_buffer_len++] = ' '; -#endif + msg_out(M_DEBUG, "w0"); 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 + x = dvi_state.w = dvi_signed_byte(); + if (frmfp) put_signed_byte(x, frmfp); + msg_out(M_DEBUG, "w1"); 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 + x = dvi_state.w = dvi_signed_pair(); + if (frmfp) put_signed_pair(x, frmfp); + msg_out(M_DEBUG, "w2"); 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 + x = dvi_state.w = dvi_signed_triple(); + if (frmfp) put_signed_triple(x, frmfp); + msg_out(M_DEBUG, "w3"); 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 + x = dvi_state.w = dvi_signed_quad(); + if (frmfp) put_signed_quad(x, frmfp); + msg_out(M_DEBUG, "w4"); break; case X0: x = dvi_state.x; -#ifdef DEBUG - fprintf(stderr, "%ld: x0 %ld ", dvi_location, x); -#endif + msg_out(M_DEBUG, "x0"); break; case X1: - x = dvi_state.x = get_signed_byte(); -#ifdef DEBUG - fprintf(stderr, "%ld: x1 %ld ", dvi_location-1, x); -#endif + x = dvi_state.x = dvi_signed_byte(); + if (frmfp) put_signed_byte(x, frmfp); + msg_out(M_DEBUG, "x1"); break; case X2: - x = dvi_state.x = get_signed_pair(); -#ifdef DEBUG - fprintf(stderr, "%ld: x2 %ld ", dvi_location-2, x); -#endif + x = dvi_state.x = dvi_signed_pair(); + if (frmfp) put_signed_pair(x, frmfp); + msg_out(M_DEBUG, "x2"); break; case X3: - x = dvi_state.x = get_signed_triple(); -#ifdef DEBUG - fprintf(stderr, "%ld: x3 %ld ", dvi_location-3, x); -#endif + x = dvi_state.x = dvi_signed_triple(); + if (frmfp) put_signed_triple(x, frmfp); + msg_out(M_DEBUG, "x3"); break; case X4: - x = dvi_state.x = get_signed_quad(); -#ifdef DEBUG - fprintf(stderr, "%ld: x4 %ld ", dvi_location-4, x); -#endif + x = dvi_state.x = dvi_signed_quad(); + if (frmfp) put_signed_quad(x, frmfp); + msg_out(M_DEBUG, "x4"); break; } + msg_out(M_DEBUG, " %ld", x); - 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; - } + if (!dvi_state.d) + out_space(x); + else + out_vmove(x); } static void do_vmove (UNSIGNED_BYTE opcode) { SIGNED_QUAD y; + flush_text(); + msg_out(M_DEBUG, "%ld: ", dvi_location); switch (opcode) { case DOWN1: - y = get_signed_byte(); -#ifdef DEBUG - fprintf(stderr, "%ld: down1 %ld ", dvi_location-1, y); -#endif + y = dvi_signed_byte(); + if (frmfp) put_signed_byte(y, frmfp); + msg_out(M_DEBUG, "down1"); break; case DOWN2: - y = get_signed_pair(); -#ifdef DEBUG - fprintf(stderr, "%ld: down2 %ld ", dvi_location-2, y); -#endif + y = dvi_signed_pair(); + if (frmfp) put_signed_pair(y, frmfp); + msg_out(M_DEBUG, "down2"); break; case DOWN3: - y = get_signed_triple(); -#ifdef DEBUG - fprintf(stderr, "%ld: down3 %ld ", dvi_location-3, y); -#endif + y = dvi_signed_triple(); + if (frmfp) put_signed_triple(y, frmfp); + msg_out(M_DEBUG, "down3"); break; case DOWN4: - y = get_signed_quad(); -#ifdef DEBUG - fprintf(stderr, "%ld: down4 %ld ", dvi_location-4, y); -#endif + y = dvi_signed_quad(); + if (frmfp) put_signed_quad(y, frmfp); + msg_out(M_DEBUG, "down4"); break; case Y0: y = dvi_state.y; -#ifdef DEBUG - fprintf(stderr, "%ld: y0 %ld ", dvi_location, y); -#endif + msg_out(M_DEBUG, "y0"); break; case Y1: - y = dvi_state.y = get_signed_byte(); -#ifdef DEBUG - fprintf(stderr, "%ld: y1 %ld ", dvi_location-1, y); -#endif + y = dvi_state.y = dvi_signed_byte(); + if (frmfp) put_signed_byte(y, frmfp); + msg_out(M_DEBUG, "y1"); break; case Y2: - y = dvi_state.y = get_signed_pair(); -#ifdef DEBUG - fprintf(stderr, "%ld: y2 %ld ", dvi_location-2, y); -#endif + y = dvi_state.y = dvi_signed_pair(); + if (frmfp) put_signed_pair(y, frmfp); + msg_out(M_DEBUG, "y2"); break; case Y3: - y = dvi_state.y = get_signed_triple(); -#ifdef DEBUG - fprintf(stderr, "%ld: y3 %ld ", dvi_location-3, y); -#endif + y = dvi_state.y = dvi_signed_triple(); + if (frmfp) put_signed_triple(y, frmfp); + msg_out(M_DEBUG, "y3"); break; case Y4: - y = dvi_state.y = get_signed_quad(); -#ifdef DEBUG - fprintf(stderr, "%ld: y4 %ld ", dvi_location-4, y); -#endif + y = dvi_state.y = dvi_signed_quad(); + if (frmfp) put_signed_quad(y, frmfp); + msg_out(M_DEBUG, "y4"); break; case Z0: y = dvi_state.z; -#ifdef DEBUG - fprintf(stderr, "%ld: z0 %ld ", dvi_location, y); -#endif + msg_out(M_DEBUG, "z0"); break; case Z1: - y = dvi_state.z = get_signed_byte(); -#ifdef DEBUG - fprintf(stderr, "%ld: z1 %ld ", dvi_location-1, y); -#endif + y = dvi_state.z = dvi_signed_byte(); + if (frmfp) put_signed_byte(y, frmfp); + msg_out(M_DEBUG, "z1"); break; case Z2: - y = dvi_state.z = get_signed_pair(); -#ifdef DEBUG - fprintf(stderr, "%ld: z2 %ld ", dvi_location-2, y); -#endif + y = dvi_state.z = dvi_signed_pair(); + if (frmfp) put_signed_pair(y, frmfp); + msg_out(M_DEBUG, "z2"); break; case Z3: - y = dvi_state.z = get_signed_triple(); -#ifdef DEBUG - fprintf(stderr, "%ld: z3 %ld ", dvi_location-3, y); -#endif + y = dvi_state.z = dvi_signed_triple(); + if (frmfp) put_signed_triple(y, frmfp); + msg_out(M_DEBUG, "z3"); break; case Z4: - y = dvi_state.z = get_signed_quad(); -#ifdef DEBUG - fprintf(stderr, "%ld: z4 %ld ", dvi_location-4, y); -#endif + y = dvi_state.z = dvi_signed_quad(); + if (frmfp) put_signed_pair(y, frmfp); + msg_out(M_DEBUG, "z4"); break; } + msg_out(M_DEBUG, " %ld", y); - 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; - } + if (!dvi_state.d) + out_vmove(y); + else + out_space(-y); } +#define RULE_PIXELS(p) (SIGNED_QUAD)ceil(conv*(p)) + +/* 90. <Finish a command that either sets or puts a rule, then goto + * move_right or done> */ static void do_rule (UNSIGNED_BYTE opcode) { SIGNED_QUAD width, height; + flush_text(); switch (opcode) { case SET_RULE: -#ifdef DEBUG - fprintf(stderr, "%ld: setrule ", dvi_location); -#endif + msg_out(M_DEBUG, "%ld: setrule", dvi_location); break; case PUT_RULE: -#ifdef DEBUG - fprintf(stderr, "%ld: putrule ", dvi_location); -#endif + msg_out(M_DEBUG, "%ld: putrule", dvi_location); break; } - height = get_signed_quad(); width = get_signed_quad(); -#ifdef DEBUG - fprintf(stderr, "height %ld width %ld ", height, width); -#endif + height = dvi_signed_quad(); width = dvi_signed_quad(); + if (frmfp) { + put_signed_quad(height, frmfp); put_signed_quad(width, frmfp); + } + msg_out(M_DEBUG, " height %ld width %ld", height, width); + if (height <= 0 || width <= 0) + msg_out(M_DEBUG, " (invisible) \n"); + else { + msg_out(M_DEBUG, " %ldx%ld pixels \n", RULE_PIXELS(height), RULE_PIXELS(width)); + calc_bbox(width, height, 0); + } /* * SET_RULE: Typeset a solid black rectangle of height |a| and width |b|, @@ -409,127 +700,149 @@ static void do_rule (UNSIGNED_BYTE opcode) * 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 + dvi_state.hh += RULE_PIXELS(width); + move_right(width); + } +} + +/* 89. <Finish a command that either sets or puts a character, then + * goto move_right or done> */ +static void fin_set (UNSIGNED_BYTE p, int move) +{ + SIGNED_QUAD width, height, depth; + + if (cur_font < 0) + msg_out(M_FAIL, "[fatal] fin_set(): No font selected.\n"); + + width = sqxfw(dvi_fonts[cur_font].size, tfm_get_fw_width(dvi_fonts[cur_font].tfm_id, p)); + height = sqxfw(dvi_fonts[cur_font].size, tfm_get_fw_height(dvi_fonts[cur_font].tfm_id, p)); + depth = sqxfw(dvi_fonts[cur_font].size, tfm_get_fw_depth(dvi_fonts[cur_font].tfm_id, p)); + + calc_bbox(width, height, depth); + + if (!move) return; + + if (!dvi_state.d) { + dvi_state.hh += PIXEL_ROUND(width); + move_right(width); + } else { + dvi_state.vv += PIXEL_ROUND(width); + move_down(width); } } +/* 88. Translate a set_char command. */ +static void do_setchar (UNSIGNED_BYTE opcode) +{ + if (opcode > 32 && opcode < 127) /* from '!' to '~' */ + out_text(opcode - SET_CHAR_0); + else + flush_text(); + msg_out(M_DEBUG, "%ld: setchar%d", dvi_location, opcode - SET_CHAR_0); + + fin_set(opcode - SET_CHAR_0, 1); +} + +/* 89. <Finish a command that either sets or puts a character, then + * goto move_right or done> */ static void do_set (UNSIGNED_BYTE opcode) { - SIGNED_QUAD ch, width; - struct dvi_font *fnt; + SIGNED_QUAD ch; + + flush_text(); + msg_out(M_DEBUG, "%ld: ", dvi_location); switch (opcode) { case SET1: - ch = get_unsigned_byte(); -#ifdef DEBUG - fprintf(stderr, "%ld: set1 %ld ", dvi_location-1, ch); -#endif + ch = dvi_unsigned_byte(); + if (frmfp) put_unsigned_byte(ch, frmfp); break; case SET2: - ch = get_unsigned_pair(); -#ifdef DEBUG - fprintf(stderr, "%ld: set2 %ld ", dvi_location-2, ch); -#endif + ch = dvi_unsigned_pair(); + if (frmfp) put_unsigned_pair(ch, frmfp); break; case SET3: - ch = get_unsigned_triple(); -#ifdef DEBUG - fprintf(stderr, "%ld: set3 %ld ", dvi_location-3, ch); -#endif + ch = dvi_unsigned_triple(); + if (frmfp) put_unsigned_triple(ch, frmfp); break; case SET4: - ch = get_signed_quad(); -#ifdef DEBUG - fprintf(stderr, "%ld: set4 %ld ", dvi_location-4, ch); -#endif + ch = dvi_signed_quad(); + if (frmfp) put_signed_quad(ch, frmfp); break; } + msg_out(M_DEBUG, " set%c %ld ", '1' + (opcode - SET1), ch); - 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; - } + fin_set(ch, 1); } +/* 89. <Finish a command that either sets or puts a character, then + * goto move_right or done> */ static void do_put (UNSIGNED_BYTE opcode) { SIGNED_QUAD ch; + flush_text(); + msg_out(M_DEBUG, "%ld: ", dvi_location); switch (opcode) { case PUT1: - ch = get_unsigned_byte(); -#ifdef DEBUG - fprintf(stderr, "%ld: put1 %ld ", dvi_location-1, ch); -#endif + ch = dvi_unsigned_byte(); + if (frmfp) put_unsigned_byte(ch, frmfp); break; case PUT2: - ch = get_unsigned_pair(); -#ifdef DEBUG - fprintf(stderr, "%ld: put2 %ld ", dvi_location-2, ch); -#endif + ch = dvi_unsigned_pair(); + if (frmfp) put_unsigned_pair(ch, frmfp); break; case PUT3: - ch = get_unsigned_triple(); -#ifdef DEBUG - fprintf(stderr, "%ld: put3 %ld ", dvi_location-3, ch); -#endif + ch = dvi_unsigned_triple(); + if (frmfp) put_unsigned_triple(ch, frmfp); break; case PUT4: - ch = get_signed_quad(); -#ifdef DEBUG - fprintf(stderr, "%ld: put4 %ld ", dvi_location-4, ch); -#endif + ch = dvi_signed_quad(); + if (frmfp) put_signed_quad(ch, frmfp); break; } + msg_out(M_DEBUG, " put%c %ld ", '1' + (opcode - PUT1), ch); + + fin_set(ch, 0); +} + +static void show_state (void) +{ + msg_out(M_DEBUG, "level %d:(h=%ld,v=%ld,w=%ld,x=%ld,y=%ld,z=%ld,hh=%ld,vv=%ld) \n", dvi_stack_depth, dvi_state.h, dvi_state.v, dvi_state.w, dvi_state.x, dvi_state.y, dvi_state.z, dvi_state.hh, dvi_state.vv); } static void do_push (void) { + flush_text(); + msg_out(M_DEBUG, "%ld: push \n", dvi_location); + show_state(); 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 + else + msg_out(M_FAIL, "[fatal] do_push(): DVI stack exceeded.\n"); } static void do_pop (void) { + BBOX *bb; + 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; + else + msg_out(M_FAIL, "[fatal] do_pop(): Tried to pop an empty stack.\n"); + flush_text(); + msg_out(M_DEBUG, "%ld: pop \n", dvi_location); + show_state(); + + /* reset bounding boxes */ + bb = page_bbox.next; + while (bb) { + if (bb->lev_s == dvi_stack_depth + 1 && bb->type == LINES_TYPE) { + flush_bbox(bb); + reset_bbox(bb); + } + bb = bb->next; } - 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) @@ -537,95 +850,61 @@ static void do_fnt_num (UNSIGNED_BYTE opcode) register int i; SIGNED_QUAD id; + flush_text(); + msg_out(M_DEBUG, "%ld: ", dvi_location); 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) { + msg_out(M_DEBUG, "fntnum%ld ", id); + } else { + switch (opcode) { case FNT1: - id = get_unsigned_byte(); -#ifdef DEBUG - fprintf(stderr, "%ld: fnt1 %ld ", dvi_location-1, id); -#endif + id = dvi_unsigned_byte(); + if (frmfp) put_unsigned_byte(id, frmfp); break; case FNT2: - id = get_unsigned_pair(); -#ifdef DEBUG - fprintf(stderr, "%ld: fnt2 %ld ", dvi_location-2, id); -#endif + id = dvi_unsigned_pair(); + if (frmfp) put_unsigned_pair(id, frmfp); break; - case FNT3: - id = get_unsigned_triple(); -#ifdef DEBUG - fprintf(stderr, "%ld: fnt3 %ld ", dvi_location-3, id); -#endif + case FNT3: + id = dvi_unsigned_triple(); + if (frmfp) put_unsigned_triple(id, frmfp); break; - case FNT4: - id = get_signed_quad(); -#ifdef DEBUG - fprintf(stderr, "%ld: fnt4 %ld ", dvi_location-4, id); -#endif + case FNT4: + id = dvi_signed_quad(); + if (frmfp) put_signed_quad(id, frmfp); break; } + msg_out(M_DEBUG, "fnt%c %ld ", '1' + (opcode - FNT1), id); + } 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); - } + if (i == num_dvi_fonts) + msg_out(M_FAIL, "[fatal] do_fnt_num(): Tried to select a font (ID %ld) that hasn't been defined.\n", id); -#ifdef DEBUG - fprintf(stderr, "current font is %s\n", dvi_fonts[i].name); -#endif + msg_out(M_DEBUG, "current font is %s \n", dvi_fonts[i].name); 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 + cur_font = i; } 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; + unsigned char *cmd, *tag, *p; + SIGNED_QUAD x, y, w, h, d; + double w_pt, h_pt, d_pt; /* in pt */ + int parsed = 0; /* how many conversions the sscanf managed */ + + struct /* see \doregisterparoptions in ConTeXt's core-pos.tex */ + { + double hsize, leftskip, rightskip, hangindent, parindent; + SIGNED_QUAD hangafter; + } list; for (p = buffer; p - buffer < buffer_len && isspace(*p); p++) ; /* skip white chars */ @@ -637,25 +916,51 @@ static void do_pos_special (unsigned char *buffer, SIGNED_QUAD buffer_len) 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; + /* retrieve POS identification */ + if (*p == '"') + for (tag = ++p; p - buffer < buffer_len && *p != '"'; p++); + else + for (tag = p; p - buffer < buffer_len && !isspace(*p); p++); + *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); + { + /* hangafter is a number, not a dimension, hence its %ld */ + parsed = sscanf(p, "%lfpt %lfpt %lfpt %lfpt,%lfpt,%lfpt,%lfpt,%ld,%lfpt", + &w_pt, &h_pt, &d_pt, + &list.hsize, &list.leftskip, &list.rightskip, + &list.hangindent, &list.hangafter, &list.parindent); + /* convert pt to sp. Forget about rounding (add 0.5 if you want it). */ + w = w_pt * 65536; + h = h_pt * 65536; + d = d_pt * 65536; + } 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); + fprintf(outfp, "\\pospxy{%s}{%d}{%ldsp}{%ldsp}\n", tag, 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); + fprintf(outfp, "\\pospxywhd{%s}{%d}{%ldsp}{%ldsp}{%ldsp}{%ldsp}{%ldsp}\n", tag, current_page, x, y, w, h, d); + else if (strcmp(cmd, "pos:pxyplus") == 0) { + if (parsed < 9) + fprintf(stderr, "dvipos: only %d conversions for \\pospxyplus but 9 are needed\nBeward: Coordinates in the output may therefore be junk. Continuing anyway...", parsed); + fprintf(outfp, "\\pospxyplus{%s}{%d}{%ldsp}{%ldsp}{%ldsp}{%ldsp}{%ldsp}", tag, current_page, x, y, w, h, d); + fprintf(outfp, "{%lfpt,%lfpt,%lfpt,%lfpt,%ld,%lfpt}\n", + list.hsize, list.leftskip, list.rightskip, + list.hangindent, list.hangafter, list.parindent); + } + else if (strcmp(cmd, "pos:begbox") == 0) + new_bbox(tag, BOX_TYPE); + else if (strcmp(cmd, "pos:endbox") == 0) + close_bbox(tag); + else if (strcmp(cmd, "pos:beglines") == 0) + new_bbox(tag, LINES_TYPE); + else if (strcmp(cmd, "pos:endlines") == 0) + close_bbox(tag); } static void do_xxx (UNSIGNED_BYTE opcode) @@ -663,371 +968,473 @@ 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 - + flush_text(); + msg_out(M_DEBUG, "%ld: xxx ", dvi_location); switch (opcode) { case XXX1: - size = get_unsigned_byte(); -#ifdef DEBUG - fprintf(stderr, "%ld: xxx ", dvi_location-1); -#endif + size = dvi_unsigned_byte(); + if (frmfp) put_unsigned_byte(size, frmfp); break; case XXX2: - size = get_unsigned_pair(); -#ifdef DEBUG - fprintf(stderr, "%ld: xxx ", dvi_location-2); -#endif + size = dvi_unsigned_pair(); + if (frmfp) put_unsigned_pair(size, frmfp); break; case XXX3: - size = get_unsigned_triple(); -#ifdef DEBUG - fprintf(stderr, "%ld: xxx ", dvi_location-3); -#endif + size = dvi_unsigned_triple(); + if (frmfp) put_unsigned_triple(size, frmfp); break; case XXX4: - size = get_signed_quad(); -#ifdef DEBUG - fprintf(stderr, "%ld: xxx ", dvi_location-4); -#endif + size = dvi_signed_quad(); + if (frmfp) put_signed_quad(size, frmfp); 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); + if (fread(sp_buf, sizeof(unsigned char), size, dvi_file) != size) + msg_out(M_FAIL, "[fatal] do_xxx(): Failed to read the special commands with size %d.\n", size); + if (frmfp) { + fwrite(sp_buf, sizeof(unsigned char), size, frmfp); + dbg_location += size; } -#ifdef DEBUG - fprintf(stderr, "'%s'\n", sp_buf); + msg_out(M_DEBUG, "'%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) +static void dvi_clear_state (void) { - UNSIGNED_BYTE opcode; - SIGNED_QUAD current_location; + cur_font = -1; /* set current font undefined */ + dvi_stack_depth = 0; + 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.hh = 0; dvi_state.vv = 0; + dvi_state.d = 0; /* direction for ASCII pTeX */ +} - /* 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); +static void do_bop (void) +{ + int i; + + msg_out(M_DEBUG, " \n%ld: beginning of page %d \n", dvi_location, current_page); + if (frmfp) { + for (i = 0; i < 10; i++) put_signed_quad(dvi_signed_quad(), frmfp); + /* the previous page location */ + dvi_signed_quad(); + put_signed_quad(prev_page_location, frmfp); + prev_page_location = dbg_location - 45; + } else + for (i = 0; i < 11; i++) dvi_signed_quad(); + dvi_clear_state(); + clear_bbox(0); +} + +static void do_eop (void) +{ + BBOX *bb; + + flush_text(); + msg_out(M_DEBUG, "%ld: eop ", dvi_location); + msg_out(M_DEBUG, "[%ld %ld %ld %ld]", page_bbox.h1, page_bbox.v1, page_bbox.h2, page_bbox.v2); + + /* reset bounding boxes */ + bb = page_bbox.next; + while (bb) { + reset_bbox(bb); + bb = bb->next; + } + + flush_bbox(&page_bbox); + if (frmfp) put_unsigned_byte(EOP, frmfp); +} + +static void do_dir (void) +{ + dvi_state.d = dvi_unsigned_byte(); + if (frmfp) put_unsigned_byte(dvi_state.d, frmfp); + msg_out(M_DEBUG, "%ld: dir %d \n", dvi_location-1, dvi_state.d); +} + +static void do_fnt_def (UNSIGNED_BYTE opcode) +{ + register int dlen, flen; + SIGNED_QUAD id; + char *fnt_buf; + + flush_text(); + switch (opcode) { + case FNT_DEF1: + id = dvi_unsigned_byte(); + if (frmfp) put_unsigned_byte(id, frmfp); + msg_out(M_DEBUG, "%ld: fntdef1 %ld: ", dvi_location-1, id); + break; + case FNT_DEF2: + id = dvi_unsigned_pair(); + if (frmfp) put_unsigned_pair(id, frmfp); + msg_out(M_DEBUG, "%ld: fntdef2 %ld: ", dvi_location-2, id); + break; + case FNT_DEF3: + id = dvi_unsigned_triple(); + if (frmfp) put_unsigned_triple(id, frmfp); + msg_out(M_DEBUG, "%ld: fntdef3 %ld: ", dvi_location-3, id); + break; + case FNT_DEF4: + id = dvi_signed_quad(); + if (frmfp) put_signed_quad(id, frmfp); + msg_out(M_DEBUG, "%ld: fntdef4 %ld: ", dvi_location-4, id); + break; } + + /* the checksum that TeX found in the TFM file for this font */ + if (frmfp) put_signed_quad(dvi_signed_quad(), frmfp); + else dvi_signed_quad(); + /* a fixed-point scale factor */ + if (frmfp) put_signed_quad(dvi_signed_quad(), frmfp); + else dvi_signed_quad(); + /* the "design size" */ + if (frmfp) put_signed_quad(dvi_signed_quad(), frmfp); + else dvi_signed_quad(); + /* the length of the "area" or directory */ + dlen = dvi_unsigned_byte(); + if (frmfp) put_unsigned_byte(dlen, frmfp); + /* the length of the font name itself */ + flen = dvi_unsigned_byte(); + if (frmfp) put_unsigned_byte(flen, frmfp); - 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); + /* the external name of the font */ + fnt_buf = (char *)calloc(dlen+flen+1, sizeof(char)); + flen = fread(fnt_buf, sizeof(char), dlen+flen, dvi_file); + if (frmfp) { + fwrite(fnt_buf, sizeof(char), flen, frmfp); + dbg_location += flen; } + fnt_buf[flen] = 0; + msg_out(M_DEBUG, "%s \n", fnt_buf); + dvi_location += flen; + free(fnt_buf); +} + +/* 110. The conversion factor \emph{conv} is figured as follows: There are + * exactly $n/d$ decimicrons per DVI unit, and 254000 decimicrons per inch, + * and \emph{resolution} pixels per inch. Then we have to adjust this by + * the stated amount of magnification. */ +static void compute_conversion_factors (void) +{ + if ((numerator = dvi_signed_quad()) <= 0) + msg_out(M_FAIL, "Bad DVI file: numerator is %d!\n", numerator); + + if ((denominator = dvi_signed_quad()) <= 0) + msg_out(M_FAIL, "Bad DVI file: denominator is %d!\n", denominator); - post_location = current_location; + msg_out(M_DEBUG, "numerator/denominator=%ld/%ld\n", numerator, denominator); + + tfm_conv = ((double)25400000.0/numerator) * (denominator/(double)473628672)/16.0; + conv = (numerator/(double)254000.0) * (resolution/denominator); + + dvi_mag = mag = dvi_signed_quad(); + if (new_mag > 0) + mag = new_mag; /* override the existing maginification */ + else if (mag <= 0) + msg_out(M_FAIL, "Bad DVI file: magnification is %d!\n", mag); + + true_conv = conv; + conv = true_conv * (mag/(double)1000.0); + + msg_out(M_DEBUG, "magnification=%ld; %16.8f pixels per DVI unit\n", mag, conv); } -/* - * The last page in a DVI file is followed by `post'; this command - * introduces the postamble, which summarizes important facts that TeX has +/* 109. A DVI-reading program that reads the postamble first need not look + * at the preamble; but DVItype looks at the preamble in order to do error + * checking, and to display the introductory comment. */ +static void process_preamble (void) +{ + fseek(dvi_file, 0L, SEEK_SET); + + /* fetch the first byte */ + if (dvi_unsigned_byte() != PRE) + msg_out(M_FAIL, "First byte isn't start of preamble!\n"); + /* fetch the identification byte */ + if ((id = dvi_unsigned_byte()) != DVI_ID && id != DVIV_ID) + msg_out(M_FAIL, "identification in byte 1 should be %d or %d.\n", DVI_ID, DVIV_ID); + + compute_conversion_factors(); + + /* fetch the introductory comment */ + comment[fread(comment, sizeof(char), dvi_unsigned_byte(), dvi_file)] = 0; + msg_out(M_DEBUG, "'%s'\n", comment); +} + +/* 19. The last page in a DVI file is followed by `\emph{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] + * 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 + * 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) +/* 103. Reading the postamble. Now imagine that we are reading the DVI file + * and positioned just four bytes after the \emph{post} command. That, + * in fact, is the situation, when the following part of DVItype is called + * upon to read, translate, and check the rest of the postamble. */ + +/* 20. The curious way to finish off a DVI file makes it feasible for + * DVI-reading programs to find the postamble first, on most computers, + * even though \TeX{} wants to write the postamble last. Most operating + * systems permit random access to individual words or bytes of a file, + * so the DVI reader can start at the end and skip backwards over the + * 223's until finding the identification byte. Then it can back up four + * bytes, read $q$, and move to byte $q$ of the file. This byte should, + * of course, contain the value 248 (\emph{post}); now the postamble can + * be read, so the DVI reader discovers all the information needed for + * typesetting the pages. Note that it is also possible to skip through + * the DVI file at reasonably high speed to locate a particular page, + * if that proves desirable. This saves a lot of time, since DVI files + * used in production jobs tend to be large. */ +static void read_postamble (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 + UNSIGNED_BYTE opcode; + SIGNED_QUAD current_location = dvi_fsize; - /* Skip the first five bytes; post and p[4] */ - fseek(dvi_file, post_location+5, SEEK_SET); + /* scan backwards through PADDING */ + do { + current_location--; + fseek(dvi_file, current_location, SEEK_SET); + } while((opcode = dvi_unsigned_byte()) == PADDING && current_location > 0); - if ((numerator = get_signed_quad()) <= 0) { - fprintf(stderr, "Bad DVI file: numerator is %d!\n", numerator); - exit(1); - } + /* current_location now points to the identification byte */ + if (dvi_fsize <= current_location + 4) + msg_out(M_FAIL, "Bad DVI file: not enough signature bytes at end of file (%ld)\n", dvi_fsize - current_location - 1); - if ((denominator = get_signed_quad()) <= 0) { - fprintf(stderr, "Bad DVI file: denominator is %d!\n", denominator); - exit(1); - } + post_post_location = current_location - 5; + fseek(dvi_file, post_post_location, SEEK_SET); + if ((opcode = dvi_unsigned_byte()) != POST_POST) + msg_out(M_FAIL, "[fatal] Found (%d) where POST_POST should be.\n", opcode); -#ifdef DEBUG - fprintf(stderr, "numerator/denomination=%ld/%ld\n", numerator, denominator); -#endif + /* now points to the pointer $q$ to the \emph{post} command */ + post_location = dvi_signed_quad(); + fseek(dvi_file, post_location, SEEK_SET); + if ((opcode = dvi_unsigned_byte()) != POST) + msg_out(M_FAIL, "[fatal] Found (%d) where POST should be\n", opcode); - if ((mag = get_signed_quad()) <= 0) { - fprintf(stderr, "Bad DVI file: magnification is %d!\n", mag); - exit(1); - } + msg_out(M_DEBUG, "Postamble starts at byte %ld.\n", post_location); - 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); + dvi_signed_quad(); /* skip the first four bytes; p[4] */ -#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 + if (dvi_signed_quad() != numerator) + msg_out(M_FAIL, "Bad DVI file: numerator doesn't match the preamble!\n"); - 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(); + if (dvi_signed_quad() != denominator) + msg_out(M_FAIL, "Bad DVI file: denominator doesn't match the preamble!\n"); -#ifdef DEUBG - fprintf(stderr, "maxv=%ld, maxh=%ld, maxstackdepth=%d, totalpages=%d\n", - max_v, max_h, max_s, total_pages); -#endif -} + if (dvi_signed_quad() != mag && new_mag == 0) + msg_out(M_FAIL, "Bad DVI file: magnification doesn't match the preamble!\n"); -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 + max_v = dvi_signed_quad(); + max_h = dvi_signed_quad(); + msg_out(M_DEBUG, "maxv=%ld, maxh=%ld, ", max_v, max_h); + + if ((max_s = dvi_signed_pair()) > DVI_MAX_STACK_DEPTH) + msg_out(M_FAIL, "[fatal] maxstackdepth %d exceeds DVI_MAX_STACK_DEPTH %d\n", max_s, DVI_MAX_STACK_DEPTH); + total_pages = dvi_signed_pair(); + msg_out(M_DEBUG, "maxstackdepth=%d, totalpages=%d\n", max_s, total_pages); } static void find_page_location (void) { - register int i; + 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); - } + if ((dvi_pages = dvi_unsigned_pair()) == 0) + msg_out(M_FAIL, "[fatal] Total page number is zero.\n"); /* 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); - } + page_location[dvi_pages-1] = dvi_signed_quad(); + if (page_location[dvi_pages-1] + 41 > dvi_fsize) + msg_out(M_FAIL, "[fatal] The location of the page %d was broken.\n", dvi_pages); 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); - } + page_location[i] = dvi_signed_quad(); + if (page_location[i] + 41 > dvi_fsize) + msg_out(M_FAIL, "[fatal] The location of the page %d was broken.\n", i+1); } } -static void read_dvi_fonts (void) +/* 59. The following subroutine does the necessary things when a fnt_def + * command is being processed. */ +static void define_font (SIGNED_QUAD e) { - UNSIGNED_BYTE opcode; - SIGNED_QUAD id, size; + SIGNED_QUAD c, q, d, m; + int p, n; + char *name; - int dir_len, name_len; - char *dir, *name; + 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)); + } - fseek(dvi_file, post_location+29, SEEK_SET); + c = dvi_signed_quad(); /* font_check_sum */ + q = dvi_signed_quad(); /* font_scaled_size */ + d = dvi_signed_quad(); /* font_design_size */ - while ((opcode = get_unsigned_byte()) != POST_POST) { + if (q <= 0 || d <= 0) m = 1000; + else m = xround((1000.0*conv*q)/(true_conv*d)); - 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); - } + p = dvi_unsigned_byte(); + n = dvi_unsigned_byte(); - /* 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)); - } + msg_out(M_DEBUG, "Font %ld: ", e); - get_signed_quad(); /* checksum */ - size = get_signed_quad(); /* scale factor */ - get_signed_quad(); /* designed size */ + /* Retrieve the directory name and the font name */ + if (p + n > 0) { + name = (char *)calloc(p+n+1, sizeof(char)); + if (fread(name, sizeof(char), p+n, dvi_file) != p+n) + msg_out(M_FAIL, "[fatal] Failed to retrieve a font name.\n"); + name[p+n] = 0; + } - dir_len = get_unsigned_byte(); - name_len = get_unsigned_byte(); + msg_out(M_DEBUG, "%s", (p + n > 0 ? name : "null font name!")); - /* 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); + if (m != 1000) + msg_out(M_DEBUG, " scaled %ld", m); - /* 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++; - } -} + dvi_fonts[num_dvi_fonts].name = name; + dvi_fonts[num_dvi_fonts].size = q; /* scaled_size */ + dvi_fonts[num_dvi_fonts].id = e; + dvi_fonts[num_dvi_fonts].used = 0; -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(); -} + msg_out(M_DEBUG, "---loaded at size %ld DVI units \n", q); + d = xround((100.0*conv*q)/(true_conv*d)); + if (d != 100) + msg_out(M_DEBUG, " (this font is magnified %ld%c) \n", d, '%'); -static void do_eop (void) -{ -#ifdef DEBUG - fprintf(stderr, "%ld: eop\n", dvi_location); -#endif + num_dvi_fonts++; } -static void do_dir (void) +static void process_fonts (void) { - dvi_state.d = get_unsigned_byte(); -#ifdef DEBUG - fprintf(stderr, "%ld: dir %d\n", dvi_location-1, dvi_state.d); -#endif + UNSIGNED_BYTE opcode; +// fseek(dvi_file, post_location+29, SEEK_SET); + while ((opcode = dvi_unsigned_byte()) != POST_POST) + switch (opcode) { + case FNT_DEF1: define_font(dvi_unsigned_byte()); break; + case FNT_DEF2: define_font(dvi_unsigned_pair()); break; + case FNT_DEF3: define_font(dvi_unsigned_triple()); break; + case FNT_DEF4: define_font(dvi_signed_quad()); break; + default: msg_out(M_FAIL, "Bad DVI file: byte %ld is not postpost!\n", dvi_location); + } } -static void do_fnt_def (UNSIGNED_BYTE opcode) +void dvi_init (int m, int r) { - register int len; - SIGNED_QUAD id; - char *fnt_buf; + time_t tm = time(NULL); + /* get all variables initialized */ + dvi_file = infp; + new_mag = (SIGNED_QUAD)m; + resolution = (double)r; + + /* 73. Three characteristics of the pages (their max_v, max_h, and max_s) + * are specified in the postamble, and a warning message is printed if + * their limits are exceeded. Actually max_v is set to the maximum height + * plus depth of a page, and max_h to the maximum width, for purposes of + * page layout. Since characters can legally be set outside of the page + * boundaries, it is not an error when max_v or max_h is exceeded. But + * max_s should not be exceeded. + * The postamble also specifies the total number of pages; DVItype + * checks to see if this total is accurate. */ +// max_v = max_h = 017777777777 - 99; +// max_s = stack_size + 1; + max_v_so_far = max_h_so_far = max_s_so_far = page_count = 0; -#ifdef DEBUG - if (dvi_buffer_len > 0) { - dvi_buffer[dvi_buffer_len] = 0; - fprintf(stderr, "[%s]\n", dvi_buffer); - dvi_buffer_len = 0; - } -#endif + /* Calculate the file size of the DVI file */ + fseek(dvi_file, 0L, SEEK_END); + dvi_fsize = ftell(dvi_file); + rewind(dvi_file); - 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(); + /* process the preamble */ + process_preamble(); - /* 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 -} + /* reading the postamble */ + read_postamble(); + + /* process the font definitions of the postamble */ + process_fonts(); -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(); + + dvi_clear_state(); clear_bbox(1); + + if (bbxfp) { + fprintf(bbxfp, "%%!! DVIpos, version (%s), output file\n", VERSION); + fprintf(bbxfp, "%% This_position_filename: \"%s\"\n", bbxfname); + fprintf(bbxfp, "%% Command_line_to_dvipos:\n"); + fprintf(bbxfp, "%%+ <THE_COMMAND_LINE>\n"); + fprintf(bbxfp, "%%+ <THE_COMMAND_LINE CONTINUED>\n"); + fprintf(bbxfp, "%% Processing_data_and_time: %s", ctime(&tm)); + fprintf(bbxfp, "%% Input_filename: \"%s\"\n", infname); + if (frmfp) + fprintf(bbxfp, "%% DVI_debug_output_filename: \"%s\"\n", frmfname); + fprintf(bbxfp, "%% DVI_standard: %d\n", id); + fprintf(bbxfp, "%% DVI_mag: %ld\n", dvi_mag); + fprintf(bbxfp, "%% DVI_mag_requested: %ld\n", mag); + } + + if (frmfp) { + int count = 15 + strlen(comment); + char *buf = (char *)xmalloc(count); + fseek(dvi_file, 0L, SEEK_SET); + fread(buf, 1, count, dvi_file); + sput_signed_quad(buf+10, mag); + fwrite(buf, 1, count, frmfp); + dbg_location += count; + free(buf); + } } void dvi_close (void) { - register int i; + int i; + + if (frmfp) { + char *buf; + int count = post_post_location - post_location - 29; + SIGNED_QUAD new_post_location = dbg_location; /* new post_location */ + put_unsigned_byte(POST, frmfp); + put_signed_quad(prev_page_location, frmfp); + put_signed_quad(numerator, frmfp); + put_signed_quad(denominator, frmfp); + put_signed_quad(mag, frmfp); + put_signed_quad(max_v_so_far, frmfp); + put_signed_quad(max_h_so_far, frmfp); + put_unsigned_pair(max_s, frmfp); + put_unsigned_pair(new_dvi_pages, frmfp); + buf = (char *)xmalloc(count); + fseek(dvi_file, post_location + 29, SEEK_SET); + fread(buf, 1, count, dvi_file); + fwrite(buf, 1, count, frmfp); + free(buf); + dbg_location += count; + put_unsigned_byte(POST_POST, frmfp); + put_signed_quad(new_post_location, frmfp); + put_unsigned_byte(id, frmfp); + for (i = 0; i < 3; i++) + put_unsigned_byte(223, frmfp); + while (dbg_location % 4 != 3) + put_unsigned_byte(223, frmfp); + } + tfm_close_all(); fclose(dvi_file); free(page_location); @@ -1035,22 +1442,24 @@ void dvi_close (void) if (dvi_fonts) free(dvi_fonts); } - +/* 79. Here is the overall setup. */ void dvi_do_page (int n) { -#ifdef DEBUG - dvi_location = page_location[n] - 1; -#endif - - current_page = n + 1; + dvi_location = page_location[n-1] - 1; + current_page = n; + new_dvi_pages++; /* Position to beginning of page */ - fseek(dvi_file, page_location[n], SEEK_SET); + fseek(dvi_file, page_location[n-1], SEEK_SET); + /* set current font undefined; initialize the state variables */ dvi_clear_state(); - for (;;) { /* until finding EOP opcode */ - UNSIGNED_BYTE opcode = get_unsigned_byte(); + /* 80. Translate the next command in the DVI file until finding EOP. */ + for (;;) { + UNSIGNED_BYTE opcode = dvi_unsigned_byte(); + + if (frmfp && opcode != EOP) put_unsigned_byte(opcode, frmfp); /* SET_CHAR_0 - SET_CHAR_127 */ if (opcode >= SET_CHAR_0 && opcode <= SET_CHAR_127) { @@ -1075,7 +1484,7 @@ void dvi_do_page (int n) case PUT4: do_put(opcode); break; case SET_RULE: case PUT_RULE: do_rule(opcode); break; - case NOP: break; + case NOP: msg_out(M_DEBUG, "%ld: nop \n", dvi_location); break; case BOP: do_bop(); break; case EOP: do_eop(); return; case PUSH: do_push(); break; @@ -1125,9 +1534,7 @@ void dvi_do_page (int n) case POST: case POST_POST: default: - fprintf(stderr, "[fatal] Unexpected opcode (%d).", opcode); - exit(1); + msg_out(M_FAIL, "[fatal] Unexpected opcode (%d).", opcode); } } } - diff --git a/Build/source/texk/dvipos/dvicore.h b/Build/source/texk/dvipos/dvicore.h index 30b1a835e50..f3168143662 100644 --- a/Build/source/texk/dvipos/dvicore.h +++ b/Build/source/texk/dvipos/dvicore.h @@ -1,6 +1,6 @@ /* $Header - dvipos-20030225 + dvipos-20030422 Copyright (C) 2003 by Jin-Hwan <chofchof@ktug.or.kr> @@ -22,16 +22,7 @@ #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 +#include "utils.h" /* DVI opcodes */ #define SET_CHAR_0 0 @@ -144,10 +135,10 @@ #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; +extern int dvi_pages; -#endif /* _DVICORE_H_ */ +extern void dvi_init (int m, int r); +extern void dvi_close (void); +extern void dvi_do_page (int n); +#endif /* _DVICORE_H_ */ diff --git a/Build/source/texk/dvipos/dvipos.1 b/Build/source/texk/dvipos/dvipos.1 new file mode 100644 index 00000000000..477fdcec7bf --- /dev/null +++ b/Build/source/texk/dvipos/dvipos.1 @@ -0,0 +1,136 @@ +.TH "DVIPOS" "1" "January 2007" "dvipos 20030628 (KPATHSEA)" "ConTeXt" +.de URL +\\$2 \(laURL: \\$1 \(ra\\$3 +.. +.if \n[.g] .mso www.tmac +.de EX +.in +3 +.nf +.ft CW +.. +.de EE +.in -3 +.ft R +.fi +.. + +.SH NAME +dvipos \- compute positions in a DVI file + +.SH SYNOPSIS +\fBdvipos\fP [ \fIOPTION\fP... ] \fIinfile[.dvi]\fP + +.SH DESCRIPTION +\fBdvipos\fP parses a DVI file looking for \fIpos:\fP specials. It +currently recognizes \fIpos:pxy\fP, \fIpos:pxywhd\fP, +\fIpos:pxyplus\fP, \fIpos:begbox\fP, \fIpos:endbox\fP, +\fIpos:beglines\fP, and \fIpos:endlines\fP. It then outputs the +information from those specials along with information that only a DVI +postprocessor could determine, such as the current \fIx\fP and \fIy\fP +location. The output looks like: +.EX +\\pospxywhd{text:54}{54}{10663sp}{8535sp}{21326sp}{34081sp}{0sp} +.EE +and is suitable for including in a +.BR tex (1) +or +.BR pdftex (1) +auxilliary file, such as \fIdocument.tuo\fP, to be read in on the next run. + +.SH OPTIONS + +.TP +\fB-h, --help\fR +print usage. +.TP +\fB-W, --warning\fR +print warnings. +.TP +\fB-v, --verbose\fR +print verbose output. +.TP +\fB-d, --debug\fR +print +.BR dvitype (1) +debugging data. +.TP +\fB-s, --smashchars\fR +regard height and depth as zero. +.TP +\fB-o, --output=\fIFILE\fR +send all output to FILE. Without this option, output goes to stdout. +.TP +\fB-b, --bbox[=\fP\fIFILE\fP]\fR +send bounding box to FILE (default FILE is \fIinfile.pos\fP). +.TP +\fB-f, --framed[=\fP\fIBASE\fP]\fR +request copy of DVI file, \fIBASE.dvi\fP, with bounding boxes +\fBframed\fP (default FILE is \fIinfile_frames.dvi\fP). See the +\fB--framesize\fP option. +.TP +\fB-m, --mag=\fIINT\fR +override +.BR tex (1) +magnification by INT. +.TP +\fB-w, --framesize=\fIINT\fR +set frame rule size by INT (default 6554 = .1pt). +.TP +\fB-p, --pages=\fIX:Y\fR +set page ranges from X to Y. + +.SH USAGE +.B dvipos +is run mostly by ConTeXt's +.BR texexec (1) +between runs of +.BR tex (1) +or +.BR pdftex (1), +in order to compute positions for the metafun interface to +.BR mpost (1). +A typical use: +.EX +dvipos notes.dvi +.EE +The position information that is output is collected by +.BR texexec (1) +to include in the \fInotes.tuo\fP auxilliary file for the next run +to use. + +.SH EXAMPLES +.TP +Extract positions from \fIdoc.dvi\fP, with output to \fIdoc.loc\fP: +\f(CWdvipos -o doc.loc doc.dvi\fP +.TP +Same as above, but also send bbox information to \fIdoc.pos\fP: +\f(CWdvipos -b -o doc.loc doc.dvi\fP +.TP +Instead send bbox information to \fI/tmp/debug.pos\fP: +\f(CWdvipos -b=/tmp/debug.pos -o doc.loc doc.dvi\fP + +.SH "SEE ALSO" +.BR dvips (1), +.BR dvitype (1), +.BR mpost (1), +.BR pdftex (1), +.BR tex (1), +.BR texexec (1). + +.SH BUGS +If you specify a file for the \fB-b\fP option, you must join the +option and name with rather than (the more common) space: +.EX +dvipos -b=/tmp/debug.pos notes.dvi +.EE +works, but +.EX +dvipos -b /tmp/debug.pos notes.dvi +.EE +does not. + +.SH AUTHOR +.B dvipos +is written by Jin-Hwan Cho <chofchof@ktug.or.kr>. It is free +software (GPLv2 or later). This manpage was written by Sanjoy +Mahajan <sanjoy@mit.edu> and is in the public domain. diff --git a/Build/source/texk/dvipos/dvipos.c b/Build/source/texk/dvipos/dvipos.c index 80bd669aa66..430cd954aaa 100644 --- a/Build/source/texk/dvipos/dvipos.c +++ b/Build/source/texk/dvipos/dvipos.c @@ -1,6 +1,6 @@ -/* $Header +/* $Header: /home/cvsroot/dvipos/dvipos.c,v 1.9 2003/06/28 05:43:40 chofchof Exp $ - dvipos-20030225 + dvipos-20030627 Copyright (C) 2003 by Jin-Hwan <chofchof@ktug.or.kr> @@ -19,110 +19,241 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include "utils.h" #include "dvicore.h" -#ifdef KPATHSEA -string progname; -unsigned dpi = 600; -string mode = NULL; -extern KPSEDLL char *kpathsea_version_string; +#include <limits.h> +#ifdef WIN32 +#include <getopt.h> #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; +int verbose = M_FAIL, do_smashchars = 0; /* output message only if failed */ +FILE *infp = NULL, *outfp = NULL, *bbxfp = NULL, *frmfp = NULL; +char *infname = NULL, *bbxfname = NULL, *frmfname = NULL; +SIGNED_QUAD dbg_location = 0, rule_width = 6554; /* .1pt */ /* 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"); - } -} +static char *outfname = NULL; +static char deffname[] = "default"; +static int nmag = 0, resol = 300, bpage = 1, epage = INT_MAX; #ifdef MIKTEX #define PLATFORM "(MiKTeX 2.2)" #else -#define PLATFORM kpathsea_version_string +#define PLATFORM "(KPATHSEA)" #endif -#define VERSION "20030225" -static void title() +static void title (void) { - fprintf(stderr, "This is DVIpos, Version %s %s\nby Jin-Hwan Cho <chofchof@ktug.or.kr>\n\n", VERSION, PLATFORM); + msg_out(M_VERBOSE, "This is DVIpos, Version %s %s\nby Jin-Hwan Cho <chofchof@ktug.or.kr>\n\n", VERSION, PLATFORM); } -static void usage() +static void usage (void) { - fprintf(stderr, "Usage: dvipos infile[.dvi] [outfile]\n\nDVIpos appends output to infile.tuo if no outfile is specified.\n\n"); + fprintf(stdout, "Usage: dvipos [OPTION...] infile[.dvi]\n\n" + "-h, --help print usage\n" + "-W, --warning print warnings\n" + "-v, --verbose print verbose output\n" + "-d, --debug print 'dvitype' debugging data\n" + "-s, --smashchars regard height and depth as zero\n" + "-o, --output=FILE send all output to FILE\n" + "-b, --bbox[=FILE] send bounding box to FILE (default FILE is infile.pos)\n" + "-f, --framed[=BASE] request copy of DVI file, BASE.dvi, with bounding boxes\n" + " *framed* (default FILE is infile_frames.dvi)\n" + "-m, --mag=INT override TeX magnification by INT\n" +// "-r, --resolution=INT set resolution by INT\n" + "-w, --framesize=INT set frame rule size by INT (default 6554 = .1pt)\n" + "-p, --pages=X:Y set page ranges from X to Y\n\n"); } -int main (int argc, char *argv[]) +static struct option long_options[] = { + /* Options without arguments: */ + { "debug", no_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "verbose", no_argument, NULL, 'v' }, + { "warning", no_argument, NULL, 'W' }, + { "smashchars", no_argument, NULL, 's' }, + /* Options accepting an argument: */ + { "mag", required_argument, NULL, 'm' }, + { "framesize", required_argument, NULL, 'w' }, + { "pages", required_argument, NULL, 'p' }, + { "resolution", required_argument, NULL, 'r' }, + { "output", optional_argument, NULL, 'o' }, + /* Options accepting an optional argument: */ + { "bbox", optional_argument, NULL, 'b' }, + { "framed", optional_argument, NULL, 'f' }, + { 0, 0, 0, 0 } +}; + +static void read_options (int argc, char **argv) { - register int i; + int op; - if (argc < 2) { - title(); - usage(); - fprintf(stderr, "No DVI filename specified.\n"); - exit(1); + while ((op = getopt_long(argc, argv, "dhvwm:s:r:p:o:b::f::", long_options, (int *)0)) != EOF) { + char *p, *q; + switch (op) { + case 'd': /* debug */ + verbose |= M_DEBUG; + break; + case 'h': /* help */ + verbose |= M_VERBOSE; title(); usage(); exit(1); + break; + case 'v': /* verbose */ + verbose |= M_VERBOSE; + break; + case 'W': /* warning */ + verbose |= M_WARNING; + break; + case 's': /* smashchars */ + do_smashchars = 1; + break; + case 'm': /* mag */ + if (*(q = optarg) == '=') q++; + nmag = (int)strtol(q, &p, 0); + if (p == q || nmag < 0) + msg_out(M_FAIL, "Missing a number for magnification.\n"); + break; + case 'r': /* resolution */ + if (*(q = optarg) == '=') q++; + resol = (int)strtol(q, &p, 0); + if (p == q || resol < 0) + msg_out(M_FAIL, "Missing a number for resolution.\n"); + break; + case 'w': /* framesize */ + if (*(q = optarg) == '=') q++; + rule_width = (int)strtol(q, &p, 0); + if (p == q || rule_width < 0) + msg_out(M_FAIL, "Missing a number for frame rule size.\n"); + break; + case 'p': /* pages */ + if (*(q = optarg) == '=') q++; + bpage = (int)strtol(q, &p, 0); + if (p == q) msg_out(M_FAIL, "Missing a page range.\n"); + if (*p == ':') { + epage = (int)strtol(q = p + 1, &p, 0); + if (p == q) msg_out(M_FAIL, "Missing a 2nd page number.\n"); + } + if (bpage > epage) { + int sw = bpage; bpage = epage; epage = sw; + } + break; + case 'o': /* output */ + if (*(q = optarg) == '=') q++; + if (strlen(q) > 0) outfname = xstrdup(q); + else msg_out(M_FAIL, "Missing an output file name.\n"); + break; + case 'b': /* bbox */ + bbxfname = deffname; + if (optarg) { + if (*(q = optarg) == '=') q++; + if (strlen(q) > 0) bbxfname = xstrdup(q); + } + break; + case 'f': /* framed */ + frmfname = deffname; + if (optarg) { + if (*(q = optarg) == '=') q++; + if (strlen(q) > 0) frmfname = xstrdup(q); + } + break; + default: + msg_out(M_FAIL, "Unparsed option (%d)\n", op); + } } - 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); + /* The first non-optional argument is to be used as the DVI file name */ + if (optind < argc) { + infname = make_suffix(argv[optind], "dvi"); + optind++; + while (optind < argc) + msg_out(M_WARNING, "Warning: Ignore unparsed argument (%s).\n", argv[optind++]); } - -#ifdef MIKTEX - miktex_initialize(); -#endif + + /* set up all the options */ + msg_out(M_DEBUG, "Options selected:\n"); + msg_out(M_DEBUG, " Starting page = * \n"); + msg_out(M_DEBUG, " Maximum number of pages = 1000000\n"); + msg_out(M_DEBUG, " Output level = 4 (the works)\n"); + msg_out(M_DEBUG, " Resolution = %d.00000000 pixels per inch\n", resol); + if (nmag > 0) + msg_out(M_DEBUG, " New magnification factor = %-8.03f\n", nmag / 1000.); +} + +int main (int argc, char *argv[]) +{ + int i; + + if (argc > 1) + read_options(argc, argv); + + title(); + + if (infname == NULL) + msg_out(M_FAIL, "No DVI filename specified.\n"); + +// if (outfname == NULL) +// outfname = make_suffix(infname, "tuo"); + + if (bbxfname == deffname) + bbxfname = make_suffix(infname, "pos"); + + if (frmfname) { + if (frmfname == deffname) { + frmfname = make_suffix(infname, "frames.dvi"); + *(frmfname+strlen(frmfname)-11) = '_'; + } else { + char *p = frmfname; + frmfname = make_suffix(p, "dvi"); + free(p); + } + } + + /* Open the input DVI file */ + if ((infp = fopen(infname, "rb")) == NULL) + msg_out(M_FAIL, "Could not open the input file %s.", infname); + + /* Open the output file */ + if (outfname == NULL) outfp = stdout; + else if ((outfp = fopen(outfname, "at")) == NULL) + msg_out(M_FAIL, "Could not open the output file %s.\n", outfname); + + /* Open the boundingbox file */ + if (bbxfname && (bbxfp = fopen(bbxfname, "wt")) == NULL) + msg_out(M_FAIL, "Could not open the boundingbox file %s.\n", bbxfname); + + /* Open the framed DVI file */ + if (frmfname && (frmfp = fopen(frmfname, "wb")) == NULL) + msg_out(M_FAIL, "Could not open the framed DVI file %s.\n", frmfname); #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); + kpse_set_program_name(argv[0], NULL); +#elif MIKTEX + miktex_initialize(); #endif - dvi_init(dvi_filename); + dvi_init(nmag, resol); - for (i = 0; i < dvi_pages; i++) + if (bpage <= 0) bpage = 1; + if (epage >= dvi_pages) epage = dvi_pages; + + for (i = bpage; i <= epage; i++) dvi_do_page(i); dvi_close(); - fclose(tuo_file); + if (infname) free(infname); + if (outfname) free(outfname); + if (bbxfname) free(frmfname); + if (frmfname) free(frmfname); + + if (outfp) fclose(outfp); + if (bbxfp) fclose(bbxfp); + if (frmfp) fclose(frmfp); #ifdef MIKTEX - miktex_uninitialize (); + miktex_uninitialize(); #endif exit(0); } - diff --git a/Build/source/texk/dvipos/miktex.mak b/Build/source/texk/dvipos/miktex.mak new file mode 100644 index 00000000000..67a0a9c8335 --- /dev/null +++ b/Build/source/texk/dvipos/miktex.mak @@ -0,0 +1,95 @@ +## miktex.mak: dvipos +## Copyright (C) 2003 Jin-Hwan Cho <chofchof@ktug.or.kr> +## +## This file is part of dvipos. +## +## dvipos 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, or (at your option) +## any later version. +## +## dvipos 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 dvipdfmx; if not, write to the Free Software Foundation, +## 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +miktex_cc_no_runtime_checks = 1 +miktex_cc_no_warnings = 1 + +!include ..\miktex.inc + +objects = \ + $(outdir)\dvicore.obj \ + $(outdir)\dvipos.obj \ + $(outdir)\tfm.obj \ + $(outdir)\utils.obj \ + +sources = \ + dvicore.c \ + dvipos.c \ + tfm.c \ + utils.c \ + +cc_options = $(cflags) $(cdebug) $(cvarsdll) $(cflagspackfunc) \ + -I. -I$(libdir) -I$(gnulibdir) -I$(kpslibdir) \ + $(miktexvars) + +.c{$(outdir)\}.obj: +!ifdef xxx + $(sed) -e "s/^static \(.*\)(/\1(/" $< > _xyz.c + $(cc) $(cc_options) -Fo$@ _xyz.c + del _xyz.c +!else + $(cc) $(cc_options) -Fo$(outdir)\ $< +!endif + +.cpp{$(outdir)\}.obj: + $(cc) $(cc_options) $(cflagseh) -Fo$(outdir)\ $< + +binaries = $(outdir)\dvipos.exe + +all: common-all $(binaries) + +install: common-install install-binaries + +qrt: common-qrt + +# ----------------------------------------------------------------------------- +# dvipos +# ----------------------------------------------------------------------------- + +$(outdir)\dvipos.exe: $(outdir) $(objects) \ + $(miktex_lib) $(kps_lib) $(gnu_lib) + $(link) $(conlflags) $(ldebug) \ + -out:$@ \ + $(objects) \ + $(miktex_lib) $(kps_lib) $(gnu_lib) $(conlibsdll) + +#$(outdir)\dvipos.res: $(outdir) dvipos.rc +# $(rc) $(rcflags) $(rcvars) -I$(libdir) -Fo$@ dvipos.rc + +# ----------------------------------------------------------------------------- +# clean-up +# ----------------------------------------------------------------------------- + +mostlyclean: common-mostlyclean + +clean: common-clean mostlyclean + +distclean: common-distclean clean + +realclean: common-realclean distclean + +# ----------------------------------------------------------------------------- +# dependencies +# ----------------------------------------------------------------------------- + +!include ..\common-dependencies.inc + +depend: $(sources) + $(MAKEDEPEND1) -I..\libkps $** + diff --git a/Build/source/texk/dvipos/tfm.c b/Build/source/texk/dvipos/tfm.c index b99f6017aea..e15f93ea116 100644 --- a/Build/source/texk/dvipos/tfm.c +++ b/Build/source/texk/dvipos/tfm.c @@ -1,4 +1,4 @@ -/* $Header +/* $Header: /home/cvsroot/dvipos/tfm.c,v 1.2 2003/04/24 00:56:00 chofchof Exp $ dvipos-20030225 @@ -26,47 +26,21 @@ #include <stdio.h> +#include "utils.h" #include "dvicore.h" +#define tfm_unsigned_byte() get_unsigned_byte(tfm_file) +#define tfm_signed_byte() get_signed_byte(tfm_file) +#define tfm_unsigned_pair() get_unsigned_pair(tfm_file) +#define tfm_signed_pair() get_signed_pair(tfm_file) +#define tfm_unsigned_triple() get_unsigned_triple(tfm_file) +#define tfm_signed_triple() get_signed_triple(tfm_file) +#define tfm_unsigned_quad() get_unsigned_quad(tfm_file) +#define tfm_signed_quad() get_signed_quad(tfm_file) + 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 */ @@ -160,32 +134,32 @@ static void get_sizes (struct a_tfm *a_tfm) { UNSIGNED_PAIR tfm_id; - tfm_id = get_unsigned_pair(); + tfm_id = tfm_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(); + a_tfm -> nt = tfm_unsigned_pair(); + a_tfm -> wlenfile = tfm_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(); + a_tfm->wlenheader = tfm_unsigned_pair(); + a_tfm->bc = tfm_unsigned_pair(); + a_tfm->ec = tfm_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(); + a_tfm->nwidths = tfm_unsigned_pair(); + a_tfm->nheights = tfm_unsigned_pair(); + a_tfm->ndepths = tfm_unsigned_pair(); + a_tfm->nitcor = tfm_unsigned_pair(); + a_tfm->nlig = tfm_unsigned_pair(); + a_tfm->nkern = tfm_unsigned_pair(); + a_tfm->nextens = tfm_unsigned_pair(); + a_tfm->nfonparm = tfm_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); @@ -206,24 +180,24 @@ static void get_sizes (struct a_tfm *a_tfm) 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(); + level = tfm_signed_quad(); + a_tfm -> wlenfile = tfm_signed_quad(); + a_tfm -> wlenheader = tfm_signed_quad(); + a_tfm -> bc = tfm_signed_quad(); + a_tfm -> ec = tfm_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(); + a_tfm -> nwidths = tfm_signed_quad(); + a_tfm -> nheights = tfm_signed_quad(); + a_tfm -> ndepths = tfm_signed_quad(); + a_tfm -> nitcor = tfm_signed_quad(); + a_tfm -> nlig = tfm_signed_quad(); + a_tfm -> nkern = tfm_signed_quad(); + a_tfm -> nextens = tfm_signed_quad(); + a_tfm -> nfonparm = tfm_signed_quad(); + a_tfm -> font_direction = tfm_signed_quad(); if (a_tfm->font_direction) { fprintf (stderr, "Warning: I may be interpreting a font direction incorrectly.\n"); } @@ -239,9 +213,9 @@ static int ofm_get_sizes (struct a_tfm *a_tfm) 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(); + a_tfm -> nco = tfm_signed_quad(); + a_tfm -> ncw = tfm_signed_quad(); + a_tfm -> npc = tfm_signed_quad(); fseek(tfm_file, 4*(a_tfm -> nco), SEEK_SET); } else { fprintf(stderr, "Can't handle OFM files with level > 1"); @@ -272,14 +246,14 @@ 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(); + a_word[i] = tfm_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(); + a_word[i] = tfm_unsigned_quad(); } static void do_fix_word_array (SIGNED_QUAD **a, SIGNED_QUAD len) @@ -309,8 +283,8 @@ static void do_char_type_array(struct a_tfm *a_tfm) 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(); + charcode = tfm_unsigned_pair(); + chartype = tfm_unsigned_pair(); (a_tfm->chartypes)[charcode] = chartype; } } @@ -404,10 +378,10 @@ static void do_ofm_zero_char_info (struct a_tfm *a_tfm) 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 */ + (a_tfm->width_index)[i] = tfm_unsigned_pair(); + (a_tfm->height_index)[i] = tfm_unsigned_byte(); + (a_tfm->depth_index)[i] = tfm_unsigned_byte(); + tfm_signed_quad(); /* Ignore remaining quad */ } } @@ -434,15 +408,15 @@ static void do_ofm_one_char_info (struct a_tfm *a_tfm) } 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(); + (a_tfm->width_index)[i] = tfm_unsigned_pair(); + (a_tfm->height_index)[i] = tfm_unsigned_byte(); + (a_tfm->depth_index)[i] = tfm_unsigned_byte(); + tfm_signed_quad(); /* Ignore next quad */ + repeats = tfm_unsigned_pair(); /* Skip params */ - for (j = 0; j < a_tfm->npc; j++) get_unsigned_pair(); + for (j = 0; j < a_tfm->npc; j++) tfm_unsigned_pair(); /* Remove word padding if necessary */ - if ((a_tfm->npc / 2) * 2 == a_tfm->npc) get_unsigned_pair(); + if ((a_tfm->npc / 2) * 2 == a_tfm->npc) tfm_unsigned_pair(); char_infos_read += 1; if (i+repeats > num_chars) { fprintf(stderr, "repeats causes number of characters to be exceeded"); @@ -782,4 +756,3 @@ 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 index 3779ecc0a48..049c8f0a282 100644 --- a/Build/source/texk/dvipos/tfm.h +++ b/Build/source/texk/dvipos/tfm.h @@ -60,4 +60,3 @@ extern char is_jfm (int font_id); extern char is_vertical (int font_id); #endif /* _TFM_H_ */ - diff --git a/Build/source/texk/dvipos/utils.c b/Build/source/texk/dvipos/utils.c new file mode 100644 index 00000000000..461be09d5a8 --- /dev/null +++ b/Build/source/texk/dvipos/utils.c @@ -0,0 +1,215 @@ +/* $Header: /home/cvsroot/dvipos/utils.c,v 1.1 2003/04/24 00:56:27 chofchof Exp $ + + dvipos-20030422 + + 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 "utils.h" + +#include <stdarg.h> + +UNSIGNED_BYTE get_unsigned_byte (FILE *fp) +{ + return (UNSIGNED_BYTE)(fgetc(fp) & 0xFF); +} + +SIGNED_BYTE get_signed_byte (FILE *fp) +{ + UNSIGNED_BYTE byte = get_unsigned_byte(fp); + return (SIGNED_BYTE)(byte & 0x80 ? byte - 0x100 : byte); +} + +UNSIGNED_PAIR get_unsigned_pair (FILE *fp) +{ + UNSIGNED_PAIR pair = get_unsigned_byte(fp); + /* Read the second byte */ + pair = pair << 8; pair += get_unsigned_byte(fp); + return pair; +} + +SIGNED_PAIR get_signed_pair (FILE *fp) +{ + UNSIGNED_PAIR pair; + UNSIGNED_BYTE byte = get_unsigned_byte(fp); + pair = (byte & 0x80 ? byte - 0x100 : byte); + /* Read the second byte */ + pair = pair << 8; pair += get_unsigned_byte(fp); + return (SIGNED_PAIR)pair; +} + +UNSIGNED_TRIPLE get_unsigned_triple (FILE *fp) +{ + UNSIGNED_TRIPLE triple = get_unsigned_byte(fp); + /* Read the second, the third byte */ + triple = triple << 8; triple += get_unsigned_byte(fp); + triple = triple << 8; triple += get_unsigned_byte(fp); + return triple; +} + +SIGNED_TRIPLE get_signed_triple (FILE *fp) +{ + UNSIGNED_TRIPLE triple; + /* Read the first byte and check the sign */ + UNSIGNED_BYTE byte = get_unsigned_byte(fp); + triple = (byte & 0x80 ? byte - 0x100 : byte); + /* Read the second, the third byte */ + triple = triple << 8; triple += get_unsigned_byte(fp); + triple = triple << 8; triple += get_unsigned_byte(fp); + return (SIGNED_TRIPLE)triple; +} + +UNSIGNED_QUAD get_unsigned_quad (FILE *fp) +{ + UNSIGNED_QUAD quad = get_unsigned_byte(fp); + /* Read the second, the third, and the fourth byte */ + quad = quad << 8; quad += get_unsigned_byte(fp); + quad = quad << 8; quad += get_unsigned_byte(fp); + quad = quad << 8; quad += get_unsigned_byte(fp); + return quad; +} + +SIGNED_QUAD get_signed_quad (FILE *fp) +{ + UNSIGNED_QUAD quad; + /* Read the first byte and check the sign */ + UNSIGNED_BYTE byte = get_unsigned_byte(fp); + quad = (byte & 0x80 ? byte - 0x100 : byte); + /* Read the second, the third, and the fourth byte */ + quad = quad << 8; quad += get_unsigned_byte(fp); + quad = quad << 8; quad += get_unsigned_byte(fp); + quad = quad << 8; quad += get_unsigned_byte(fp); + return (SIGNED_QUAD)quad; +} + +void put_unsigned_byte (SIGNED_QUAD quad, FILE *fp) +{ + fputc(quad & 0xff, fp); + dbg_location++; +} + +void put_signed_byte (SIGNED_QUAD quad, FILE *fp) +{ + if (quad < 0) fputc((quad + 0x100) & 0xff, fp); + else fputc(quad & 0xff, fp); + dbg_location++; +} + +void put_unsigned_pair (SIGNED_QUAD quad, FILE *fp) +{ + put_unsigned_byte(quad >> 8, fp); + put_unsigned_byte(quad, fp); +} + +void put_signed_pair (SIGNED_QUAD quad, FILE *fp) +{ + put_signed_byte(quad >> 8, fp); + put_unsigned_byte(quad, fp); +} + +void put_unsigned_triple (SIGNED_QUAD quad, FILE *fp) +{ + put_unsigned_byte(quad >> 16, fp); + put_unsigned_pair(quad & 0xffff, fp); +} + +void put_signed_triple (SIGNED_QUAD quad, FILE *fp) +{ + put_signed_byte(quad >> 16, fp); + put_unsigned_pair(quad & 0xffff, fp); +} + +void put_signed_quad (SIGNED_QUAD quad, FILE *fp) +{ + put_signed_byte(quad >> 24, fp); + put_unsigned_triple(quad & 0xffffff, fp); +} + +void sput_signed_pair (char *buf, SIGNED_QUAD quad) +{ + if (quad < 0) *buf++ = (quad >> 8) + 0x100; + else *buf++ = quad >> 8; + *buf = quad & 0xff; +} + +void sput_signed_quad (char *buf, SIGNED_QUAD quad) +{ + if (quad < 0) *buf++ = (quad >> 24) + 0x100; + else *buf++ = quad >> 24; + *buf++ = quad >> 16; + *buf++ = quad >> 8; + *buf = quad & 0xff; +} + +#ifndef KPATHSEA +/* Borrowed from the kpathsea library, concat3.c */ +char *concat (const char *s1, const char *s2) +{ + unsigned s1len = strlen(s1); + unsigned s2len = strlen(s2); + char *answer = (char *)xmalloc(s1len + s2len + 1); + strcpy(answer, s1); + strcat(answer + s1len, s2); + return answer; +} + +/* Borrowed from the kpathsea library, concat3.c */ +char *concat3 (const char *s1, const char *s2, const char *s3) +{ + char *answer = (char *)xmalloc(strlen(s1) + strlen(s2) + strlen(s3) + 1); + strcpy(answer, s1); + strcat(answer, s2); + strcat(answer, s3); + return answer; +} + +/* Borrowed from the kpathsea library, make-suffix.c */ +/* Return a new string: S suffixed with SUFFIX, regardless of what it + * was before. This returns a newly allocated string. */ +char *make_suffix (const char *s, const char *suffix) +{ + char *new_s; + const char *dot_pos = strrchr(s, '.'); + const char *slash_pos; + + for (slash_pos = s + strlen(s) - 1; slash_pos > dot_pos && slash_pos > s; slash_pos--) + if (IS_DIR_SEP(*slash_pos)) break; + + if (dot_pos == NULL || slash_pos > dot_pos) + new_s = concat3(s, ".", suffix); + else { + unsigned past_dot_index = dot_pos + 1 - s; + new_s = (char *)xmalloc (past_dot_index + strlen (suffix) + 1); + strncpy(new_s, s, dot_pos + 1 - s); + strcpy(new_s + past_dot_index, suffix); + } + + return new_s; +} +#endif + +void msg_out (int level, char *fmt, ...) +{ + va_list args; + if (verbose & level) { + va_start(args, fmt); + vfprintf(stdout, fmt, args); + va_end(args); + } + if (level == M_FAIL) + exit(1); +} diff --git a/Build/source/texk/dvipos/utils.h b/Build/source/texk/dvipos/utils.h new file mode 100644 index 00000000000..c6d19a7f543 --- /dev/null +++ b/Build/source/texk/dvipos/utils.h @@ -0,0 +1,87 @@ +/* $Header: /home/cvsroot/dvipos/utils.h,v 1.5 2003/06/28 05:43:40 chofchof Exp $ + + dvipos-20030628 + + 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 _UTILS_H_ +#define _UTILS_H_ + +#include <stdio.h> + +#ifdef MIKTEX +#include "miktex.h" +#include "gnu-miktex.h" +#include "web2c-miktex.h" +#else +#include <kpathsea/kpathsea.h> +#endif + +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; + +extern UNSIGNED_BYTE get_unsigned_byte (FILE *fp); +extern SIGNED_BYTE get_signed_byte (FILE *fp); +extern UNSIGNED_PAIR get_unsigned_pair (FILE *fp); +extern SIGNED_PAIR get_signed_pair (FILE *fp); +extern UNSIGNED_TRIPLE get_unsigned_triple (FILE *fp); +extern SIGNED_TRIPLE get_signed_triple (FILE *fp); +extern UNSIGNED_QUAD get_unsigned_quad (FILE *fp); +extern SIGNED_QUAD get_signed_quad (FILE *fp); + +extern void put_unsigned_byte (SIGNED_QUAD quad, FILE *fp); +extern void put_signed_byte (SIGNED_QUAD quad, FILE *fp); +extern void put_unsigned_pair (SIGNED_QUAD quad, FILE *fp); +extern void put_signed_pair (SIGNED_QUAD quad, FILE *fp); +extern void put_unsigned_triple (SIGNED_QUAD quad, FILE *fp); +extern void put_signed_triple (SIGNED_QUAD quad, FILE *fp); +extern void put_signed_quad (SIGNED_QUAD quad, FILE *fp); + +extern void sput_signed_pair (char *buf, SIGNED_QUAD quad); +extern void sput_signed_quad (char *buf, SIGNED_QUAD quad); + +#ifndef KPATHSEA +# ifdef concat +# undef concat +extern char *concat (const char *s1, const char *s2); +# endif +extern char *concat3 (const char *s1, const char *s2, const char *s3); +extern char *make_suffix (const char *s, const char *suffix); +#endif + +#define M_FAIL 0x01 +#define M_VERBOSE 0x02 +#define M_WARNING 0x04 +#define M_DEBUG 0x08 +#define M_USAGE 0x10 + +extern void msg_out (int level, char *fmt, ...); + +/* Global Variables */ +extern int verbose, do_smashchars; +extern FILE *infp, *outfp, *bbxfp, *frmfp; +extern char *infname, *bbxfname, *frmfname; +extern SIGNED_QUAD dbg_location, rule_width; + +#define INFINITY 0x7FFFFFFFL //017777777777 + +#define VERSION "20070107" + +#endif /* _UTILS_H_ */ diff --git a/Build/source/texk/dvipos/win32.mak b/Build/source/texk/dvipos/win32.mak index dc4f1efc985..12077cd5b6c 100644 --- a/Build/source/texk/dvipos/win32.mak +++ b/Build/source/texk/dvipos/win32.mak @@ -1,54 +1,52 @@ ################################################################################ # -# 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> +# Makefile : DVIpos +# Author : Jin-Hwan Cho <chofchof@ktug.or.kr> +# Platform : Win32, Microsoft VC++ 7.0, depends upon fpTeX 0.6 sources +# Time-stamp: <03/06/27 00:00:00 ChoF> # ################################################################################ root_srcdir = ..\.. -!ifdef DEVELOPMENT -INCLUDE=$(INCLUDE);$(root_srcdir)\texk.development -!else -INCLUDE=$(INCLUDE);$(root_srcdir)\texk -!endif +INCLUDE=$(INCLUDE);$(root_srcdir)\..\win32 -# Makefile for ttfdump +version = 20030628 USE_GNUW32 = 1 USE_KPATHSEA = 1 -!include <msvc/common.mak> +!include <make/common.mak> -DEFS = -I.. $(DEFS) -DHAVE_CONFIG_H \ - -I..\crypto -# -DWITHOUT_OPENSSL -# -DWITHOUT_TOUNICODE +DEFS = $(DEFS) -manfiles = -objects = \ - $(objdir)\dvicore.obj \ - $(objdir)\dvipos.obj \ - $(objdir)\tfm.obj +programs=$(objdir)\dvipos.exe -program = $(objdir)\dvipos.exe -programs = $(program) +headers = dvicore.h tfm.h utils.h + +src = dvicore.c dvipos.c tfm.c utils.c + +objects = $(objdir)\dvicore.obj $(objdir)\dvipos.obj $(objdir)\tfm.obj $(objdir)\utils.obj default: all all: $(objdir) $(programs) -$(program): $(objects) $(kpathsealib) +$(objdir)\dvipos.exe: $(objects) $(kpathsealib) $(link) $(**) $(conlibs) -!include <msvc/config.mak> -!include <msvc/install.mak> +!include <make/install.mak> + +install:: install-exec install-data install-doc + +distclean:: + @$(copy) config.dvipos config-dvipos $(redir_stdout) -install:: install-exec install-man +!include <make/clean.mak> -!include <msvc/clean.mak> +distclean:: + @$(copy) config-dvipos config.dvipos $(redir_stdout) + -@$(del) config-dvipos $(redir_stderr) -!include <msvc/rdepend.mak> +!include <make/rdepend.mak> !include "./depend.mak" # |