diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/textool |
Initial commit
Diffstat (limited to 'dviware/textool')
-rw-r--r-- | dviware/textool/README | 48 | ||||
-rw-r--r-- | dviware/textool/commands.h | 266 | ||||
-rw-r--r-- | dviware/textool/defs.h | 83 | ||||
-rw-r--r-- | dviware/textool/dvistuff.c | 1006 | ||||
-rw-r--r-- | dviware/textool/globals.h | 64 | ||||
-rw-r--r-- | dviware/textool/makefile | 36 | ||||
-rw-r--r-- | dviware/textool/pkstuff.c | 618 | ||||
-rw-r--r-- | dviware/textool/problems | 35 | ||||
-rw-r--r-- | dviware/textool/pxlstuff.c | 173 | ||||
-rw-r--r-- | dviware/textool/sunstuff.c | 1620 | ||||
-rw-r--r-- | dviware/textool/textool.fix | 92 | ||||
-rw-r--r-- | dviware/textool/textool.icon | 36 | ||||
-rw-r--r-- | dviware/textool/textool.l | 224 | ||||
-rw-r--r-- | dviware/textool/textool.pdf | bin | 0 -> 62931 bytes |
14 files changed, 4301 insertions, 0 deletions
diff --git a/dviware/textool/README b/dviware/textool/README new file mode 100644 index 0000000000..10faa2d059 --- /dev/null +++ b/dviware/textool/README @@ -0,0 +1,48 @@ +This is a TeX previewer for SunView. It works under V3.2 of Sun unix, +and under V3.0 with KEYBOARDSCROLL undefined in defs.h. It has not been +tested with any other versions or on any hardware other than my 3/160M. + +The following files should be here: + README what you are reading + Problems various things that went wrong + Makefile the obvious thing + defs.h various #defines used everywhere + globals.h global variable and structure definitions + commands.h DVI format command defs + sunstuff.c The SunView parts of it + dvistuff.c The DVI file specific bits + pkstuff.c Routines for pk format fonts + pxlstuff.c Routines for pxl format fonts + textool.l a man page + textool.icon The icon file + +It has a fairly long history, see the note at the start of dvistuff.c +and the authors bit of the man page. This version opens its own window, +complete with scrollbars, menus etc. and does not use its parent window +for anything except debugging output. + +It can be compiled to use either pxl or pk format font files. + +Note that it was edited with tabs set to 4 rather than 8 spaces. + +Installation: + +Check the Makefile for paths etc. and for which of pkstuff.o or pxlstuff.o +you want included. + +Check defs.h, mainly for font file paths and MAXOPEN. + +Check the note in the Problems file about frame_default_done_proc() and +edit your <suntool/frame.h> if necessary. + +Make and then make install. + +Please send comments, bugs etc. to: + + peter@memex.co.uk + peter@memex.uucp + +Peter Ilieve +Memex Information Engines Ltd. +East Kilbride +Scotland diff --git a/dviware/textool/commands.h b/dviware/textool/commands.h new file mode 100644 index 0000000000..22475dabd7 --- /dev/null +++ b/dviware/textool/commands.h @@ -0,0 +1,266 @@ +/* + * + * $Revision: 1.1 $ + * $Log: commands.h,v $ + * Revision 1.1 83/11/23 10:56:00 mds + * Initial revision + * + * + */ +#define SETC_000 0 +#define SETC_001 1 +#define SETC_002 2 +#define SETC_003 3 +#define SETC_004 4 +#define SETC_005 5 +#define SETC_006 6 +#define SETC_007 7 +#define SETC_008 8 +#define SETC_009 9 +#define SETC_010 10 +#define SETC_011 11 +#define SETC_012 12 +#define SETC_013 13 +#define SETC_014 14 +#define SETC_015 15 +#define SETC_016 16 +#define SETC_017 17 +#define SETC_018 18 +#define SETC_019 19 +#define SETC_020 20 +#define SETC_021 21 +#define SETC_022 22 +#define SETC_023 23 +#define SETC_024 24 +#define SETC_025 25 +#define SETC_026 26 +#define SETC_027 27 +#define SETC_028 28 +#define SETC_029 29 +#define SETC_030 30 +#define SETC_031 31 +#define SETC_032 32 +#define SETC_033 33 +#define SETC_034 34 +#define SETC_035 35 +#define SETC_036 36 +#define SETC_037 37 +#define SETC_038 38 +#define SETC_039 39 +#define SETC_040 40 +#define SETC_041 41 +#define SETC_042 42 +#define SETC_043 43 +#define SETC_044 44 +#define SETC_045 45 +#define SETC_046 46 +#define SETC_047 47 +#define SETC_048 48 +#define SETC_049 49 +#define SETC_050 50 +#define SETC_051 51 +#define SETC_052 52 +#define SETC_053 53 +#define SETC_054 54 +#define SETC_055 55 +#define SETC_056 56 +#define SETC_057 57 +#define SETC_058 58 +#define SETC_059 59 +#define SETC_060 60 +#define SETC_061 61 +#define SETC_062 62 +#define SETC_063 63 +#define SETC_064 64 +#define SETC_065 65 +#define SETC_066 66 +#define SETC_067 67 +#define SETC_068 68 +#define SETC_069 69 +#define SETC_070 70 +#define SETC_071 71 +#define SETC_072 72 +#define SETC_073 73 +#define SETC_074 74 +#define SETC_075 75 +#define SETC_076 76 +#define SETC_077 77 +#define SETC_078 78 +#define SETC_079 79 +#define SETC_080 80 +#define SETC_081 81 +#define SETC_082 82 +#define SETC_083 83 +#define SETC_084 84 +#define SETC_085 85 +#define SETC_086 86 +#define SETC_087 87 +#define SETC_088 88 +#define SETC_089 89 +#define SETC_090 90 +#define SETC_091 91 +#define SETC_092 92 +#define SETC_093 93 +#define SETC_094 94 +#define SETC_095 95 +#define SETC_096 96 +#define SETC_097 97 +#define SETC_098 98 +#define SETC_099 99 +#define SETC_100 100 +#define SETC_101 101 +#define SETC_102 102 +#define SETC_103 103 +#define SETC_104 104 +#define SETC_105 105 +#define SETC_106 106 +#define SETC_107 107 +#define SETC_108 108 +#define SETC_109 109 +#define SETC_110 110 +#define SETC_111 111 +#define SETC_112 112 +#define SETC_113 113 +#define SETC_114 114 +#define SETC_115 115 +#define SETC_116 116 +#define SETC_117 117 +#define SETC_118 118 +#define SETC_119 119 +#define SETC_120 120 +#define SETC_121 121 +#define SETC_122 122 +#define SETC_123 123 +#define SETC_124 124 +#define SETC_125 125 +#define SETC_126 126 +#define SETC_127 127 +#define SET1 128 +#define SET2 129 +#define SET3 130 +#define SET4 131 +#define SET_RULE 132 +#define PUT1 133 +#define PUT2 134 +#define PUT3 135 +#define PUT4 136 +#define PUT_RULE 137 +#define NOP 138 +#define BOP 139 +#define EOP 140 +#define PUSH 141 +#define POP 142 +#define RIGHT1 143 +#define RIGHT2 144 +#define RIGHT3 145 +#define RIGHT4 146 +#define W0 147 +#define W1 148 +#define W2 149 +#define W3 150 +#define W4 151 +#define X0 152 +#define X1 153 +#define X2 154 +#define X3 155 +#define X4 156 +#define DOWN1 157 +#define DOWN2 158 +#define DOWN3 159 +#define DOWN4 160 +#define Y0 161 +#define Y1 162 +#define Y2 163 +#define Y3 164 +#define Y4 165 +#define Z0 166 +#define Z1 167 +#define Z2 168 +#define Z3 169 +#define Z4 170 +#define FONT_00 171 +#define FONT_01 172 +#define FONT_02 173 +#define FONT_03 174 +#define FONT_04 175 +#define FONT_05 176 +#define FONT_06 177 +#define FONT_07 178 +#define FONT_08 179 +#define FONT_09 180 +#define FONT_10 181 +#define FONT_11 182 +#define FONT_12 183 +#define FONT_13 184 +#define FONT_14 185 +#define FONT_15 186 +#define FONT_16 187 +#define FONT_17 188 +#define FONT_18 189 +#define FONT_19 190 +#define FONT_20 191 +#define FONT_21 192 +#define FONT_22 193 +#define FONT_23 194 +#define FONT_24 195 +#define FONT_25 196 +#define FONT_26 197 +#define FONT_27 198 +#define FONT_28 199 +#define FONT_29 200 +#define FONT_30 201 +#define FONT_31 202 +#define FONT_32 203 +#define FONT_33 204 +#define FONT_34 205 +#define FONT_35 206 +#define FONT_36 207 +#define FONT_37 208 +#define FONT_38 209 +#define FONT_39 210 +#define FONT_40 211 +#define FONT_41 212 +#define FONT_42 213 +#define FONT_43 214 +#define FONT_44 215 +#define FONT_45 216 +#define FONT_46 217 +#define FONT_47 218 +#define FONT_48 219 +#define FONT_49 220 +#define FONT_50 221 +#define FONT_51 222 +#define FONT_52 223 +#define FONT_53 224 +#define FONT_54 225 +#define FONT_55 226 +#define FONT_56 227 +#define FONT_57 228 +#define FONT_58 229 +#define FONT_59 230 +#define FONT_60 231 +#define FONT_61 232 +#define FONT_62 233 +#define FONT_63 234 +#define FNT1 235 +#define FNT2 236 +#define FNT3 237 +#define FNT4 238 +#define XXX1 239 +#define XXX2 240 +#define XXX3 241 +#define XXX4 242 +#define FNT_DEF1 243 +#define FNT_DEF2 244 +#define FNT_DEF3 245 +#define FNT_DEF4 246 +#define PRE 247 +#define POST 248 +#define POST_POST 249 +#define UNDEF_00 250 +#define UNDEF_01 251 +#define UNDEF_02 252 +#define UNDEF_03 253 +#define UNDEF_04 254 +#define UNDEF_05 255 + diff --git a/dviware/textool/defs.h b/dviware/textool/defs.h new file mode 100644 index 0000000000..9724b6ceed --- /dev/null +++ b/dviware/textool/defs.h @@ -0,0 +1,83 @@ +/* + * The various defines needed by TeXtool. + */ + +typedef short Boolean; + +char *calloc(); +#define NEW(count, type) ((type *) calloc(count, sizeof(type))) + +#define DEBUG /* for massive printing of input */ + /* trace information; select with -d */ + /* or -x for pxl font stuff */ + +#define BINARYOPEN fopen /* byte-oriented host version */ + +#define USEGLOBALMAG /* when defined, the dvi global + * magnification is applied + * and user specified magnifications + * are also allowed + */ +/* + * This is problematical. It would allow better resolution to be obtained + * by expanding the page but the code only allocates a fixed size canvas + * for drawing on, big enough for a normal page. If magnification is used + * the right and bottom of the page will not fall on the canvas and will + * never be visible. Scrolling only moves the canvas under the frame and + * will not redraw anything. + * It is rare to have a complete set of fonts at any other mag anyway. + */ + +#define KEYBOARDSCROLL /* allows h,j,k,l,c scrolling */ + /* + * NOTE: this will expose bugs in the + * scrolling code in V3.0. Do not use + * with 3.0 + */ + +#define FALSE 0 +#define TRUE 1 +#define NOTCACHED -1 +#define SETCMD 1 +#define PUTCMD 0 +#define DVIFORMAT 2 +#define FIRSTPXLCHAR 0 +#define LASTPXLCHAR 255 +#define NPXLCHARS 256 +#define PXLID 1001 +#ifndef PXLFONTAREA +#define PXLFONTAREA "/u/tex/pxlfiles" +#endif +#ifndef PKFONTAREA +#define PKFONTAREA "/u/tex/pk118" +#endif +#define MAXOPEN 9 /* limit of number of PXL files open */ + /* + * Not very many as SunView needs a lot + * You need two spare after allowing 3 for + * stdin, stout & stderr, 12 for SunView and + * 1 for the .dvi file. So MAXOPEN should + * be a max. of NOFILE-18. + */ +#define RESOLUTION 118 /* is really about 81 (11in raster, 900 dots */ +#define STACKSIZE 100 +#define STRSIZE 256 + +/* these are defined as macros for speed */ +#define MoveDown(a) v += (a); +#define MoveOver(b) h += (b); +#define PixRound(x, conv) ((int)(((x) + ((conv) >> 1)) / (conv))); + +/* status bits for main_state */ +#define SB_INITIAL 01 /* for case where called as textool <file> */ +#define SB_NOFILE 02 /* set after error or for no file name */ +#define SB_NEWFILE 04 /* we have a new dvi name to open */ +#define SB_NODVIFILE 010 /* we can't access(2) the dvi file */ +#define SB_NOTEXFILE 020 /* we can't access(2) the tex file */ +#define SB_INTERPRET 040 /* safe to process dvi file */ +#define SB_PLUSNUMBER 0100 /* accumulating a positive number */ +#define SB_MINUSNUMBER 0200 /* accumulating a negative number */ +#define SB_TEXING 0400 /* subwindow currently running tex or latex */ +#define SB_EDITING 01000 /* subwindow currently running vi */ +#define SB_SHELL 02000 /* subwindow currently running shell */ + diff --git a/dviware/textool/dvistuff.c b/dviware/textool/dvistuff.c new file mode 100644 index 0000000000..513c08938a --- /dev/null +++ b/dviware/textool/dvistuff.c @@ -0,0 +1,1006 @@ +/* + * This is the DVI related part of TeXtool + */ + +/* + * This code has quite a long history. + * The header comment from the dvi2ps driver from the TeX tape I + * received about August 86 is shown below + */ + +/* + * + * AUTHOR(s) + * Mark Senn wrote the early versions of this program for the + * BBN BitGraph. Stephan Bechtolsheim, Bob Brown, Richard + * Furuta, James Schaad and Robert Wells improved it. Norm + * Hutchinson ported the program to the Sun. Neal Holtz ported + * it to the Apollo, and from there to producing PostScript + * output. Scott Jones added intelligent font substitution. + * + */ + +/* + * This version presumably diverged from the dvi2ps line before the + * move to Apollo and was then modified by Y. Ledru (yl@lln-cs) + * to work with SunView. + * A bugfix from dvi2ps to do with marking font files closed when they + * are removed from the cache has been "bought back" into this version. + * The font data structures have also been changed so they are + * cross-linked so no searching has to be done except to find the + * least used cache entry. + * Extra tests for valid data values have been put into LoadAChar() + * as a bogus PXL file was causing havoc by overfilling a character + * pixrect. + * Much other tidying up and removal of code which was no longer used + * has also been done + * Peter Ilieve - peter@memex.co.uk + */ + +#include "defs.h" +#include "commands.h" +#include <sys/types.h> +#include <sys/stat.h> +#include <stdio.h> +#include <pixrect/pixrect_hs.h> +char *index(); +char *calloc(); +char *rindex(); +char *sprintf(); +char *strcpy(); + +/* procedures in sunstuff */ +extern void BatchStart(); +extern void BatchEnd(); +extern void Fatal(); +extern void SetBop(); +extern void SetChar(); +extern void SetRule(); +extern void Warning(); + +/* procedures in pxlstuff or pkstuff */ +extern void FindFontFile(); +extern void LoadAChar(); +extern void ReadCharDefs(); + +/* procedures here */ +float ActualFactor(); +FILE* BINARYOPEN(); +void CloseDviFile(); +int DoConv(); +void DoPage(); +Boolean DviFileChanged(); +void FindPostAmblePtr(); +void FreeFontStorage(); +void GetBytes(); +int NoSignExtend(); +void OpenDviFile(); +FILE *OpenFontFile(); +int ReadFontDef(); +void ReadPagePointers(); +void ReadPreAmble(); +void ReadPostAmble(); +void SetFntNum(); +int SignExtend(); +void SkipFontDef(); +#ifdef DEBUG +void ShowPxlCache(); +void ShowPxlFd(); +#endif + +/* a few global variables and data structures */ +#include "globals.h" + +struct pixel_list +{ + FILE *pixel_file_id; /* file identifier */ + struct font_entry *feptr; /* font_entry for this cache slot */ + int use_count; /* count of "opens" */ +}; + +struct font_entry *fontptr; /* font_entry pointer */ +struct font_entry *hfontptr=NULL;/* font_entry pointer to head of chain */ +struct font_entry *pfontptr = NULL; /* previous font_entry pointer */ +int nopen = 0; /* number of open font files */ +struct pixel_list pixel_files[MAXOPEN+1]; + /* list of open font file identifiers */ + /* slot 0 not used */ + +/* + * DVI file related data structures + */ + +/* pagepointers moved to globals to let sunstuff get at count_0 */ + + /* two structs to hold pre and postamble */ + /* a lot of this is not used */ +struct Preamble +{ + unsigned int num; + unsigned int den; + unsigned int mag; +} preamble; + +struct Postamble +{ + long last_page_ptr; + unsigned int num; + unsigned int den; + unsigned int mag; + unsigned int maxheight; + unsigned int maxwidth; + unsigned short maxstack; + unsigned short totalpages; +} postamble; + +FILE *dvifp; /* DVI file pointer */ +static time_t dvimodtime; + +struct stack_entry { /* stack entry */ + int h, v, w, x, y, z; /* what's on stack */ +}; +struct stack_entry stack[STACKSIZE]; /* stack */ +int sp; /* stack pointer */ + + /* h and v are global */ +int w; /* current horizontal spacing */ +int x; /* current horizontal spacing */ +int y; /* current vertical spacing */ +int z; /* current vertical spacing */ + +/* display related stuff */ + +int hconv, vconv; /* converts DVI units to pixels */ + +/* now to the real code */ + +/*-->ActualFactor*/ +/**********************************************************************/ +/************************** ActualFactor ****************************/ +/**********************************************************************/ + +float /* compute the actual size factor given the approximation */ +ActualFactor(unmodsize) +int unmodsize; /* actually factor * 1000 */ +{ + float realsize; /* the actual magnification factor */ + + realsize = (float)unmodsize / 1000.0; + /* a real hack to correct for rounding in some cases--rkf */ + if(unmodsize==1095) realsize = 1.095445; /*stephalf*/ + else if(unmodsize==1315) realsize=1.314534; /*stepihalf*/ + else if(unmodsize==2074) realsize=2.0736; /*stepiv*/ + else if(unmodsize==2488) realsize=2.48832; /*stepv*/ + else if(unmodsize==2986) realsize=2.985984; /*stepiv*/ + /* the remaining magnification steps are represented with sufficient + accuracy already */ + return(realsize); +} + + +/*-->CloseDviFile*/ +/**********************************************************************/ +/************************** CloseDviFile ******************************/ +/**********************************************************************/ + +void +CloseDviFile() +{ + if (dvifp != NULL) + fclose(dvifp); + if (pagepointers != NULL) { + free (pagepointers); + pagepointers = NULL; + } +} + + +/*-->DoConv*/ +/**********************************************************************/ +/****************************** DoConv ******************************/ +/**********************************************************************/ + +int +DoConv(num, den, mag, convResolution) +{ + register float conv; + conv = ((float)num/(float)den) * +#ifdef USEGLOBALMAG + ActualFactor(mag) * +#endif + ((float)convResolution/254000.0); + return((int) (1.0 / conv + 0.5)); +} + + +/*-->DoPage*/ +/**********************************************************************/ +/****************************** DoPage ******************************/ +/**********************************************************************/ + +void +DoPage(pagenumber) +int pagenumber; +{ + unsigned char command; + int val, val2; + int k; + +#ifdef DEBUG + if (Debug) + fprintf(stderr,"DoPage(%d)\n", pagenumber); +#endif + if (!(main_state & SB_INTERPRET)) + return; + h = v = w = x = y = z = 0; /* zero position */ + sp = 0; /* empty stack */ + fontptr = NULL; /* no font */ + fseek(dvifp, pagepointers[pagenumber].page_ptr, 0); /* go to correct page */ + SetBop(); /* clear canvas */ + if (Batching) + BatchStart(); + while (main_state & SB_INTERPRET) /* interpret DVI file */ + + /* we use getc here for speed */ + /* also force a complete jump table */ + switch (command=getc(dvifp)) { + + case SETC_000: case SETC_001: case SETC_002: case SETC_003: + case SETC_004: case SETC_005: case SETC_006: case SETC_007: + case SETC_008: case SETC_009: case SETC_010: case SETC_011: + case SETC_012: case SETC_013: case SETC_014: case SETC_015: + case SETC_016: case SETC_017: case SETC_018: case SETC_019: + case SETC_020: case SETC_021: case SETC_022: case SETC_023: + case SETC_024: case SETC_025: case SETC_026: case SETC_027: + case SETC_028: case SETC_029: case SETC_030: case SETC_031: + case SETC_032: case SETC_033: case SETC_034: case SETC_035: + case SETC_036: case SETC_037: case SETC_038: case SETC_039: + case SETC_040: case SETC_041: case SETC_042: case SETC_043: + case SETC_044: case SETC_045: case SETC_046: case SETC_047: + case SETC_048: case SETC_049: case SETC_050: case SETC_051: + case SETC_052: case SETC_053: case SETC_054: case SETC_055: + case SETC_056: case SETC_057: case SETC_058: case SETC_059: + case SETC_060: case SETC_061: case SETC_062: case SETC_063: + case SETC_064: case SETC_065: case SETC_066: case SETC_067: + case SETC_068: case SETC_069: case SETC_070: case SETC_071: + case SETC_072: case SETC_073: case SETC_074: case SETC_075: + case SETC_076: case SETC_077: case SETC_078: case SETC_079: + case SETC_080: case SETC_081: case SETC_082: case SETC_083: + case SETC_084: case SETC_085: case SETC_086: case SETC_087: + case SETC_088: case SETC_089: case SETC_090: case SETC_091: + case SETC_092: case SETC_093: case SETC_094: case SETC_095: + case SETC_096: case SETC_097: case SETC_098: case SETC_099: + case SETC_100: case SETC_101: case SETC_102: case SETC_103: + case SETC_104: case SETC_105: case SETC_106: case SETC_107: + case SETC_108: case SETC_109: case SETC_110: case SETC_111: + case SETC_112: case SETC_113: case SETC_114: case SETC_115: + case SETC_116: case SETC_117: case SETC_118: case SETC_119: + case SETC_120: case SETC_121: case SETC_122: case SETC_123: + case SETC_124: case SETC_125: case SETC_126: case SETC_127: + SetChar(&(fontptr->ch[command - SETC_000]), SETCMD); + break; + + case SET1:case SET2:case SET3:case SET4: + val = NoSignExtend(dvifp, command-SET1+1); + SetChar(&(fontptr->ch[val]), SETCMD); + break; + + case SET_RULE: + val = NoSignExtend(dvifp, 4); + val2 = NoSignExtend(dvifp, 4); + SetRule(val, val2, SETCMD); + break; + + case PUT1:case PUT2:case PUT3:case PUT4: + val = NoSignExtend(dvifp,command-PUT1+1); + SetChar(&(fontptr->ch[val]), PUTCMD); + break; + + case PUT_RULE: + val = NoSignExtend(dvifp, 4); + val2 = NoSignExtend(dvifp, 4); + SetRule(val, val2, PUTCMD); + break; + + case NOP: + break; + + case BOP: + Fatal("BOP encountered in page"); + break; + + case EOP: + if (Batching) + BatchEnd(); +#ifdef DEBUG + if (Debug) + fprintf(stderr,"DoPage return after EOP found\n"); +#endif + return; + + case PUSH: + if (sp >= STACKSIZE) + Fatal("stack overflow"); + else { + stack[sp].h = h; + stack[sp].v = v; + stack[sp].w = w; + stack[sp].x = x; + stack[sp].y = y; + stack[sp].z = z; + sp++; + } + break; + + case POP: + --sp; + if (sp < 0) + Fatal("stack underflow"); + else { + h = stack[sp].h; + v = stack[sp].v; + w = stack[sp].w; + x = stack[sp].x; + y = stack[sp].y; + z = stack[sp].z; + } + break; + + case RIGHT1:case RIGHT2:case RIGHT3:case RIGHT4: + val = SignExtend(dvifp,command-RIGHT1+1); + MoveOver(val); + break; + + case W0: + MoveOver(w); + break; + + case W1:case W2:case W3:case W4: + w = SignExtend(dvifp,command-W1+1); + MoveOver(w); + break; + + case X0: + MoveOver(x); + break; + + case X1:case X2:case X3:case X4: + x = SignExtend(dvifp,command-X1+1); + MoveOver(x); + break; + + case DOWN1:case DOWN2:case DOWN3:case DOWN4: + val = SignExtend(dvifp,command-DOWN1+1); + MoveDown(val); + break; + + case Y0: + MoveDown(y); + break; + + case Y1:case Y2:case Y3:case Y4: + y = SignExtend(dvifp,command-Y1+1); + MoveDown(y); + break; + + case Z0: + MoveDown(z); + break; + + case Z1:case Z2:case Z3:case Z4: + z = SignExtend(dvifp,command-Z1+1); + MoveDown(z); + break; + + case FONT_00: case FONT_01: case FONT_02: case FONT_03: + case FONT_04: case FONT_05: case FONT_06: case FONT_07: + case FONT_08: case FONT_09: case FONT_10: case FONT_11: + case FONT_12: case FONT_13: case FONT_14: case FONT_15: + case FONT_16: case FONT_17: case FONT_18: case FONT_19: + case FONT_20: case FONT_21: case FONT_22: case FONT_23: + case FONT_24: case FONT_25: case FONT_26: case FONT_27: + case FONT_28: case FONT_29: case FONT_30: case FONT_31: + case FONT_32: case FONT_33: case FONT_34: case FONT_35: + case FONT_36: case FONT_37: case FONT_38: case FONT_39: + case FONT_40: case FONT_41: case FONT_42: case FONT_43: + case FONT_44: case FONT_45: case FONT_46: case FONT_47: + case FONT_48: case FONT_49: case FONT_50: case FONT_51: + case FONT_52: case FONT_53: case FONT_54: case FONT_55: + case FONT_56: case FONT_57: case FONT_58: case FONT_59: + case FONT_60: case FONT_61: case FONT_62: case FONT_63: + SetFntNum(command - FONT_00); + break; + + case FNT1:case FNT2:case FNT3:case FNT4: + SetFntNum(NoSignExtend(dvifp, command-FNT1+1)); + break; + + case XXX1:case XXX2:case XXX3:case XXX4: + k = NoSignExtend(dvifp,command-XXX1+1); + while (k--) + getc(dvifp); + break; + + case FNT_DEF1:case FNT_DEF2:case FNT_DEF3:case FNT_DEF4: + k = NoSignExtend(dvifp, command-FNT_DEF1+1); + SkipFontDef (k); /* always read from postamble */ + break; + + case PRE: + Fatal("PRE occurs within file"); + break; + + case POST: + Fatal("POST found before EOP"); + break; + + case POST_POST: + Fatal("POST_POST with no preceding POST"); + break; + + case UNDEF_00: case UNDEF_01: case UNDEF_02: case UNDEF_03: + case UNDEF_04: case UNDEF_05: + default: + Fatal("%d is an undefined command", command); + break; + + } + if (Batching) + BatchEnd(); /* to catch cases when stop in mid page */ +} + + +/*-->DviFileChanged*/ +/**********************************************************************/ +/************************ DviFileChanged ****************************/ +/**********************************************************************/ + +Boolean +DviFileChanged() +{ + struct stat statbuf; + + if (main_state & (SB_NOFILE | SB_NODVIFILE)) /* can't do fstat */ + return (FALSE); + fstat(fileno(dvifp), &statbuf); + if (statbuf.st_mtime > dvimodtime) { + dvimodtime = statbuf.st_mtime; + return (TRUE); + } + else + return (FALSE); +} + + +/*-->FindPostAmblePtr*/ +/**********************************************************************/ +/************************ FindPostAmblePtr **************************/ +/**********************************************************************/ + +void +FindPostAmblePtr(postambleptr) +long *postambleptr; + +/* this routine will move to the end of the file and find the start + of the postamble */ + +{ + int i; + + fseek (dvifp, (long) 0, 2); /* goto end of file */ + *postambleptr = ftell (dvifp) - 4; + fseek (dvifp, *postambleptr, 0); + + while (TRUE) { + fseek (dvifp, --(*postambleptr), 0); + if (((i = NoSignExtend(dvifp, 1)) != 223) && (i != DVIFORMAT)) { + Fatal ("Bad end of DVI file"); + return; + } + if (i == DVIFORMAT) + break; + } + fseek (dvifp, (*postambleptr) - 4, 0); + (*postambleptr) = NoSignExtend(dvifp, 4); + fseek (dvifp, *postambleptr, 0); +} + + +/*-->FreeFontStorage*/ +/**********************************************************************/ +/**************************** FreeFontStorage ***********************/ +/**********************************************************************/ + +void +FreeFontStorage() +{ + register struct font_entry *tfontptr; + register struct char_entry *tcharptr; + register int i; + + while (hfontptr != NULL) { + tfontptr = hfontptr->next; + /* close open font file */ + if (hfontptr->cache_slot != NOTCACHED) + fclose(pixel_files[hfontptr->cache_slot].pixel_file_id); + /* free all memory pixrects for chars */ + if (hfontptr->has_been_opened == TRUE) { + for (i = FIRSTPXLCHAR; i <= LASTPXLCHAR; i++) { + tcharptr = &(hfontptr->ch[i]); + if (tcharptr->where.isloaded == TRUE) + pr_destroy(tcharptr->where.address.pixrectptr); + } + } + /* free font_entry struct */ + free(hfontptr); + hfontptr = tfontptr; + } + pfontptr = NULL; + nopen = 0; /* zero font cache count */ +} + + +/*-->GetBytes*/ +/**********************************************************************/ +/***************************** GetBytes *****************************/ +/**********************************************************************/ + +void +GetBytes(fp, cp, n) /* get n bytes from file fp */ +register FILE *fp; /* file pointer */ +register char *cp; /* character pointer */ +register int n; /* number of bytes */ + +{ + while (n--) + *cp++ = getc(fp); +} + + +/*-->NoSignExtend*/ +/**********************************************************************/ +/*************************** NoSignExtend ***************************/ +/**********************************************************************/ + +int +NoSignExtend(fp, n) /* return n byte quantity from file fd */ +register FILE *fp; /* file pointer */ +register int n; /* number of bytes */ + +{ + register int x; /* number being constructed */ + + x = 0; + while (n--) { + x <<= 8; + x |= getc(fp); + } + return(x); +} + + +/*-->OpenDviFile*/ +/**********************************************************************/ +/************************** OpenDviFile ******************************/ +/**********************************************************************/ + +void +OpenDviFile(dviname) +char *dviname; +{ + if (main_state & (SB_NOFILE | SB_NODVIFILE)) + return; /* don't even try */ + if ((dvifp=BINARYOPEN(dviname,"r")) == NULL) { + Fatal("Can't open \"%s\"", dviname); + return; + } + ReadPreAmble(); +#ifdef USEGLOBALMAG + if (Mflag) + preamble.mag = user_mag; +#endif + ReadPostAmble(); +#ifdef USEGLOBALMAG + if (Mflag) + postamble.mag = user_mag; +#endif + ReadPagePointers(); + if (postamble.maxstack >= STACKSIZE) { + Fatal ("Stack size is too small for \"%s\"", dviname); + return; + } + if ((preamble.num != postamble.num) || + (preamble.den != postamble.den) || + (preamble.mag != postamble.mag)) { + Fatal("Preamble-Postamble mismatch in \"%s\"", dviname); + return; + } + totalpages = postamble.totalpages; + hconv = DoConv(preamble.num, preamble.den, preamble.mag, RESOLUTION); + vconv = DoConv(preamble.num, preamble.den, preamble.mag, RESOLUTION); + dvimodtime = 0; /* to force DviFileChanged() to set it */ + (void)DviFileChanged(); +#ifdef DEBUG + if (Debug) fprintf(stderr,"DVI file open OK, total pages = %d\n", + totalpages); +#endif +} + + +/*-->OpenFontFile*/ +/**********************************************************************/ +/************************** OpenFontFile *****************************/ +/**********************************************************************/ + +FILE * +OpenFontFile() +/*********************************************************************** + The original version of this dvi driver reopened the font file each + time the font changed, resulting in an enormous number of relatively + expensive file openings. This version keeps a cache of up to + MAXOPEN open files, so that when a font change is made, the file + pointer returned can usually be updated from the cache. When the + file is not found in the cache, it must be opened. In this case, + the next empty slot in the cache is assigned, or if the cache is + full, the least used font file is closed and its slot reassigned for + the new file. Identification of the least used file is based on the + counts of the number of times each file has been "opened" by this + routine. On return, the file pointer is always repositioned to the + beginning of the file. + +***********************************************************************/ +{ + register int i,least_used,current; + FILE *fontfp; + +#ifdef DEBUG + if (ExtraDebug) fprintf(stderr,"Open Font file:\n"); +#endif + if (pfontptr == fontptr) + { + pixel_files[fontptr->cache_slot].use_count++; /* update reference count */ +#ifdef DEBUG + if (ExtraDebug) fprintf(stderr,"quick return (k = %d)\n", + fontptr->k); +#endif + return (pixel_files[fontptr->cache_slot].pixel_file_id); + } + + if ((current = fontptr->cache_slot) != NOTCACHED) + /* it is already in cache */ + { + fontfp = pixel_files[current].pixel_file_id; + fseek(fontfp,0,0); /* reposition to start of file */ +#ifdef DEBUG + if (ExtraDebug) fprintf(stderr, + "reposition font file position %d (k = %d)\n", + current, fontptr->k); +#endif + } + else /* file not in cache */ + { + if (nopen < MAXOPEN) /* just add it to list */ + current = ++nopen; + else /* list full -- find least used file, */ + { /* close it, and reuse slot for new file */ + least_used = 1; + for (i = 2; i <= MAXOPEN; ++i) + if (pixel_files[least_used].use_count > + pixel_files[i].use_count) + least_used = i; + (pixel_files[least_used].feptr)->cache_slot = NOTCACHED; + /* flag font_entry as no longer cached */ + fclose(pixel_files[least_used].pixel_file_id); + /* close it */ +#ifdef DEBUG + if (ExtraDebug) fprintf(stderr, + "font file %s, slot %d closed (k = %d)\n", + (pixel_files[least_used].feptr)->name, + least_used, + (pixel_files[least_used].feptr)->k); +#endif + current = least_used; + } + if (!fontptr->has_been_opened) + FindFontFile(fontptr, preamble.mag); + if (ExtraDebug) + printf("Trying to open file %s\n", fontptr->name); + if ((fontfp=BINARYOPEN(fontptr->name,"r")) == NULL) { + if (ExtraDebug) + printf("Failed to open file %s\n", fontptr->name); + Fatal("font file %s could not be opened; %d font files are open", + fontptr->name,nopen); + return (NULL); + } +#ifdef DEBUG + if (ExtraDebug) + fprintf(stderr,"font file %s opened, position %d, (k = %d)\n", + fontptr->name, current, fontptr->k); +#endif + pixel_files[current].pixel_file_id = fontfp; + pixel_files[current].use_count = 0; + pixel_files[current].feptr = fontptr; /* make cross links */ + fontptr->cache_slot = current; + if (!fontptr->has_been_opened) { + ReadCharDefs(fontptr, fontfp); + fontptr->has_been_opened = TRUE; + } + } + pfontptr = fontptr; /* make previous = current font */ + pixel_files[current].use_count++; /* update reference count */ + return (fontfp); +} + + +/*-->ReadFontDef*/ +/**********************************************************************/ +/**************************** ReadFontDef ***************************/ +/**********************************************************************/ + +int +ReadFontDef(k) +int k; +{ + register struct font_entry *tfontptr; /* temporary font_entry pointer */ + + if ((tfontptr = NEW(1, struct font_entry)) == NULL) { + Fatal("can't malloc space for font_entry"); + return; + } + tfontptr->next = hfontptr; + fontptr = hfontptr = tfontptr; + + tfontptr->k = k; + tfontptr->c = NoSignExtend(dvifp, 4); /* checksum */ + tfontptr->s = NoSignExtend(dvifp, 4); /* space size */ + tfontptr->d = NoSignExtend(dvifp, 4); /* design size */ + tfontptr->a = NoSignExtend(dvifp, 1); /* area length for font name */ + tfontptr->l = NoSignExtend(dvifp, 1); /* device length */ + GetBytes(dvifp, tfontptr->n, tfontptr->a+tfontptr->l); + tfontptr->n[tfontptr->a+tfontptr->l] = '\0'; + tfontptr->cache_slot = NOTCACHED; + tfontptr->has_been_opened = FALSE; + if (PreLoad || BigPreLoad) + (void)OpenFontFile(); +} + + +/*-->ReadPagePointers*/ +/**********************************************************************/ +/************************** ReadPagePointers ************************/ +/**********************************************************************/ + +void +ReadPagePointers() +{ + long temp_ptr; + int index; + int k; + + if (main_state & (SB_NOFILE | SB_NODVIFILE)) + return; +#ifdef DEBUG + if (Debug) fprintf (stderr, "now reading page pointers\n"); +#endif + pagepointers = NEW(postamble.totalpages ,struct page_entry); + if (pagepointers == NULL) { + Fatal("can't malloc space for page pointers"); + return; + } + index = postamble.totalpages; + temp_ptr = postamble.last_page_ptr; + while (--index >= 0) { + fseek(dvifp, temp_ptr, 0); + if(NoSignExtend(dvifp, 1) != BOP) { + Fatal("Couldn't find BOP"); + return; + } + pagepointers[index].count_0 = NoSignExtend(dvifp, 4); + k = 36; + while (k--) + getc(dvifp); + pagepointers[index].page_ptr = temp_ptr+45; + temp_ptr = (long)NoSignExtend(dvifp, 4); + } +} + + +/*-->ReadPreAmble*/ +/**********************************************************************/ +/************************** ReadPreAmble ****************************/ +/**********************************************************************/ + +void +ReadPreAmble() +{ + int k; + + if (main_state & (SB_NOFILE | SB_NODVIFILE)) + return; + if (NoSignExtend(dvifp, 2) != ((PRE << 8) | DVIFORMAT)) { + Fatal("This doesn't look like a DVI file, it doesn't start with PRE, %d", + DVIFORMAT); + return; + } + preamble.num = NoSignExtend(dvifp, 4); + preamble.den = NoSignExtend(dvifp, 4); + preamble.mag = NoSignExtend(dvifp, 4); + k = NoSignExtend(dvifp, 1); + while (k--) + getc(dvifp); +} + + +/*-->ReadPostAmble*/ +/**********************************************************************/ +/************************** ReadPostAmble ***************************/ +/**********************************************************************/ + +void +ReadPostAmble() +{ + long postambleptr; + int command; + Boolean foundPOST_POST; + + if (main_state & (SB_NOFILE | SB_NODVIFILE)) + return; + FindPostAmblePtr (&postambleptr); + if (NoSignExtend(dvifp, 1) != POST) { + Fatal ("POST missing at head of postamble"); + return; + } +#ifdef DEBUG + if (Debug) fprintf (stderr, "got POST command\n"); +#endif + postamble.last_page_ptr = NoSignExtend(dvifp, 4); + postamble.num = NoSignExtend(dvifp, 4); + postamble.den = NoSignExtend(dvifp, 4); + postamble.mag = NoSignExtend(dvifp, 4); + postamble.maxheight = NoSignExtend(dvifp, 4); + postamble.maxheight = NoSignExtend(dvifp, 4); + postamble.maxstack = NoSignExtend(dvifp, 2); + postamble.totalpages = NoSignExtend(dvifp, 2); + +#ifdef DEBUG + if (Debug) fprintf (stderr, "now reading font defs\n"); +#endif + foundPOST_POST = FALSE; + while (!foundPOST_POST) { + switch (command = NoSignExtend(dvifp, 1)) { + case FNT_DEF1: + case FNT_DEF2: + case FNT_DEF3: + case FNT_DEF4: + ReadFontDef(NoSignExtend(dvifp, command-FNT_DEF1+1)); + break; + case NOP: + break; + case POST_POST: + foundPOST_POST = TRUE; +#ifdef DEBUG + if (Debug) fprintf (stderr, "got POST_POST command\n"); +#endif + break; + default: + Fatal ("Bad command in postamble font defs"); + return; + } + } +} + + +/*-->SetFntNum*/ +/**********************************************************************/ +/**************************** SetFntNum *****************************/ +/**********************************************************************/ + +void +SetFntNum(k) +int k; + +/* + * This sets the global fontptr from the DVI font number k. + * This font is then used for all subsequent characters until the next + * SetFntNum + */ + +{ + fontptr = hfontptr; + while ((fontptr!=NULL) && (fontptr->k!=k)) + fontptr = fontptr->next; + if (fontptr == NULL) + Fatal("font %d undefined", k); +} + + +/*-->SignExtend*/ +/**********************************************************************/ +/**************************** SignExtend ****************************/ +/**********************************************************************/ + +int +SignExtend(fp, n) /* return n byte quantity from file fd */ +register FILE *fp; /* file pointer */ +register int n; /* number of bytes */ + +{ + int n1; /* number of bytes */ + register int x; /* number being constructed */ + + x = getc(fp); /* get first (high-order) byte */ + if ((x & 0x80) != 0) /* it is negative */ + x |= 0xFFFFFF00; /* fill upper bits with ones */ + n1 = n--; + while (n--) { + x <<= 8; + x |= getc(fp); + } + return(x); +} + + +/*-->SkipFontDef*/ +/**********************************************************************/ +/**************************** SkipFontDef ***************************/ +/**********************************************************************/ + +void +SkipFontDef() +{ + short n; + + n = 12; /* for c, s and d params */ + while (n--) + getc(dvifp); + n = getc(dvifp); /* a param */ + n += getc(dvifp); /* l param, form a+l */ + while (n--) + getc(dvifp); /* throw away name */ +} + + +#ifdef DEBUG +/*-->ShowPxlFd*/ +/**********************************************************************/ +/**************************** ShowPxlCache **************************/ +/**********************************************************************/ + +void +ShowPxlCache() +{ + short i; + + fprintf(stderr, "Font file cache contents:\n"); + for(i=1; i<=nopen; i++) { + fprintf(stderr,"Slot %d: Name %s.%dpxl: Use count %d\n", + i, + (pixel_files[i].feptr)->n, + (pixel_files[i].feptr)->font_mag, + pixel_files[i].use_count); + } +} + + +/*-->ShowPxlFd*/ +/**********************************************************************/ +/**************************** ShowPxlFd *****************************/ +/**********************************************************************/ + +void +ShowPxlFd() +{ + short i; + + if (dvifp) + fprintf(stderr,"\ndvi file %d\n\n", fileno(dvifp)); + fprintf(stderr,"number of pxl files open = %d\n", nopen); + for (i=1; i<=nopen; i++) + if ((pixel_files[i].feptr)->cache_slot != NOTCACHED) + fprintf(stderr,"pixel_files[%d]: fd %d, name %s\n", + i, + fileno(pixel_files[i].pixel_file_id), + (pixel_files[i].feptr)->n); +} +#endif + diff --git a/dviware/textool/globals.h b/dviware/textool/globals.h new file mode 100644 index 0000000000..9486dc4a72 --- /dev/null +++ b/dviware/textool/globals.h @@ -0,0 +1,64 @@ +/* + * a few really global variables + */ + +#ifdef _DEFINE +#define EXTERN +#else +#define EXTERN extern +#endif + +/* various flags and state variables */ + +EXTERN Boolean Debug; +EXTERN Boolean ExtraDebug; +EXTERN Boolean PreLoad; /* preload the font descriptions? */ +EXTERN Boolean BigPreLoad; /* preload the font descriptions? */ +EXTERN Boolean Batching; /* batch raster-ops for speed (approx x3) */ +EXTERN Boolean Mflag; /* to say that -m was specified */ +EXTERN int user_mag; /* the value specified with -m */ +EXTERN short main_state; /* to say what we are currently doing */ + +EXTERN int h; /* horizontal and vertical positions */ +EXTERN int v; +EXTERN int hconv; /* conversion factors from DVI to pixels */ +EXTERN int vconv; + +EXTERN char *PXLpath; +EXTERN char *PKpath; + +EXTERN unsigned short totalpages; + +struct char_entry { /* character entry */ + unsigned short width, height; /* width and height in pixels */ + short xOffset, yOffset; /* x offset and y offset in pixels */ + struct { + Boolean isloaded; + union { + long fileOffset; + struct pixrect *pixrectptr; + } address; + } where; + int tfmw; /* TFM width */ +}; + +struct font_entry { /* font entry */ + int k, c, s, d, a, l; + char n[STRSIZE]; /* FNT_DEF command parameters */ + int font_mag; /* computed from FNT_DEF s and d parameters */ + /* and only used for generating PXL filename */ + char name[STRSIZE]; /* full name of PXL file */ + int cache_slot; /* slot in pixel_files, NOTCACHED if not */ + Boolean has_been_opened; /* to say if ReadCharDefs() has been done */ + struct char_entry ch[NPXLCHARS]; /* character information */ + struct font_entry *next; /* next font in chain */ +}; + +struct page_entry /* for holding BOP info */ +{ + long page_ptr; /* offset in DVI file of command after BOP */ + int count_0; /* TeX count 0 (page number) for this page */ +}; + +EXTERN struct page_entry *pagepointers; + diff --git a/dviware/textool/makefile b/dviware/textool/makefile new file mode 100644 index 0000000000..1e76916dee --- /dev/null +++ b/dviware/textool/makefile @@ -0,0 +1,36 @@ +CFLAGS = -f68881 -fsingle -O +LIBS = -lsuntool -lsunwindow -lpixrect +BINDIR = /u/tex/bin +MANDIR = /usr/man/manl +ICONDIR = /usr/include/images +FONTOBJ = pkstuff.o +# change the above to pxlstuff.o for pxl format fonts +RHOST = drake +FILES = README Problems Makefile defs.h globals.h commands.h\ + sunstuff.c dvistuff.c pkstuff.c pxlstuff.c textool.l textool.icon + +textool: sunstuff.o dvistuff.o ${FONTOBJ} + cc -o textool ${CFLAGS} sunstuff.o dvistuff.o ${FONTOBJ} ${LIBS} + +install: textool + install -s textool ${BINDIR} + +rinstall: ${BINDIR}/textool + rcp ${BINDIR}/textool ${RHOST}:${BINDIR} + +installall: textool textool.l textool.icon + install -s textool ${BINDIR} + cp textool.l ${MANDIR} + cp textool.icon ${ICONDIR} + +clean: + rm -rf *.o textool kit + +kit: ${FILES} + tar cvf - ${FILES} | compress | btoa > kit + +sunstuff.o: defs.h globals.h +dvistuff.o: defs.h globals.h commands.h +pxlstuff.o: defs.h globals.h +pkstuff.o: defs.h globals.h + diff --git a/dviware/textool/pkstuff.c b/dviware/textool/pkstuff.c new file mode 100644 index 0000000000..32de8ed7e2 --- /dev/null +++ b/dviware/textool/pkstuff.c @@ -0,0 +1,618 @@ +/* + * This is the font part of textool, dealing with PK format files. + * The low level routines to deal with the PK format + * were transliterated from pktopx + * See the pktopx documentation for details. + * For V2.3, 29 Mar 88 +- * Fixed stupid errors in skip_specials() that caused specials to be +missed + + */ + +#include "defs.h" +#include <stdio.h> +#include <sys/file.h> /* for access() stuff */ +#include <pixrect/pixrect_hs.h> /* for LoadAChar() */ + +char *index(); +int strlen(); +char *strcpy(); +char *sprintf(); + +/* procedures in sunstuff */ +extern void Fatal(); +extern void Warning(); + +/* procedures in dvistuff */ +extern float ActualFactor(); +extern FILE *OpenFontFile(); + +/* procedures here */ +void ReadCharDefs(); +void LoadAChar(); + +/* a few global variables and data structures */ +#include "globals.h" + +#define PK_XXX1 240 +#define PK_XXX2 241 +#define PK_XXX3 242 +#define PK_XXX4 243 +#define PK_YYY 244 +#define PK_POST 245 +#define PK_NOP 246 +#define PK_PRE 247 +#define PK_ID 89 + +#define ROWSIZE 64 /* maximum width of raster in 16 bit words */ + +static FILE *pkfp; +static long pk_loc; /* points to next byte to be read in file */ +static long pk_char_start; +static int repeat_count; +static int dyn_f; +static int word_width; +static int char_height; +static int char_width; +static Boolean got_pk_post; +static Boolean turn_on; +static int bit_weight; +static int flag_byte; +static int packet_length; +static int char_code; +static int tfm_width; +static int hor_esc; +static int vert_esc; +static int h_off; +static int v_off; +static int nybindex; +static short row[ROWSIZE]; +static short *rowptr; +static short *imageptr; + +static int power[16] = + {1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80, + 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000}; +static int gpower[17] = + {0, 1, 3, 7, 15, 0x1f, 0x3f, 0x7f, + 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff}; + +#define get_pk_byte() (pk_loc++, getc(pkfp)) + + +int +get_pk_word() +{ + int myword; + + myword = get_pk_byte() << 8; + return (myword + get_pk_byte()); +} + + +int +get_pk_double() +{ + register int mydouble; + + mydouble = get_pk_byte() << 8; + mydouble += get_pk_byte(); + mydouble = (mydouble << 8) + get_pk_byte(); + return ((mydouble << 8) + get_pk_byte()); +} + + + /* + * This returns the next nybble from the pk file + * The variable nybindex controls which nybble is + * returned. This is initialised to 0 in normal_raster() + * as a previous normal_raster() may have read an odd + * number of nybbles. + */ +int +get_pk_nybble() +{ + static int mynybble; + + if (nybindex) { + nybindex = 0; + return (mynybble & 0xf); + } + else { + mynybble = get_pk_byte(); + nybindex = 1; + return (mynybble >> 4); + } +} + + + /* + * This returns a non-zero value if the next pk file + * bit is a one. It is only used in an if (..) so + * the actual value is not important. + * The variable bit_weight is used to count the bits + * between calls to get_pk_byte(). It is initialised + * to 0 in bitmap_raster() so a byte is fetched the + * first time. + * The function is given for illustration. The macro + * following is used for speed. + */ +/* + *int + *get_pk_bit() + *{ + * static int byte_for_bits; + * + * if (bit_weight <= 1) { + * bit_weight = 256; + * byte_for_bits = get_pk_byte(); + * } + * bit_weight = bit_weight >> 1; + * return (byte_for_bits & bit_weight); + *} + */ +static int byte_for_bits; +#define get_pk_bit() (((bit_weight<=1) ?\ + (bit_weight = 128, byte_for_bits=get_pk_byte()) : (bit_weight>>=1)),\ + byte_for_bits&bit_weight) + + +void +send_row() +{ + register short *dp; + register int i; + register int repcount; + + dp = imageptr; + repcount = repeat_count + 1; + while (repcount--) { + rowptr = row; + i = word_width; + while(i--) + *dp++ = *rowptr++; + } + imageptr=dp; /* save for next call */ +} + + +void +skip_specials() +{ + register int i; + + do { + i = 0; + flag_byte = get_pk_byte(); + if (flag_byte >= PK_XXX1) + switch (flag_byte) { + case PK_XXX4: + i = get_pk_byte(); + case PK_XXX3: + i = (i<<8) + get_pk_byte(); + case PK_XXX2: + i = (i<<8) + get_pk_byte(); + case PK_XXX1: + i = (i<<8) + get_pk_byte(); + while (i--) + (void)get_pk_byte(); + break; + case PK_YYY: + (void)get_pk_double(); + break; + case PK_POST: +#ifdef DEBUG + if (ExtraDebug) + fprintf(stderr, "Got pk_post in skip_specials()\n"); +#endif + got_pk_post = TRUE; + return; + case PK_NOP: + break; + default: + Fatal("Bad pk command byte (%d) in skip_specials()", + flag_byte); + return; + } + } while (flag_byte >= PK_XXX1); +} + + + /* + * This routine returns the next run count from the pk + * character description. It will set the global repeat_count + * to any repeat count value encountered. + */ +int +pk_packed_num() +{ + register int i, j; + + i = get_pk_nybble(); + if (i == 0) { + do { + j = get_pk_nybble(); + i++; + } while (j == 0); + while (i--) + j = (j<<4) + get_pk_nybble(); + return (j - 15 + ((13 - dyn_f)<<4) + dyn_f); + } + else if (i <= dyn_f) + return (i); + else if (i < 14) + return (((i - dyn_f - 1)<<4) + get_pk_nybble() + dyn_f + 1); + else { + if (i == 14) + repeat_count = pk_packed_num(); + else /* i must be 15 */ + repeat_count = 1; + return (pk_packed_num()); + } +} + + /* + * This deals with run count encoded rasters. + * It uses pk_packed_num() which in turn uses get_pk_nybble(). + */ +void +normal_raster(dp) +short *dp; +{ + register int word = 0; + register int count; + register int h_bit = char_width; + register int word_weight = 16; + register int rows_left = char_height; + + repeat_count = 0; + nybindex = 0; + imageptr = dp; + rowptr = row; + + while (rows_left > 0) { + count = pk_packed_num(); + while (count > 0) { + if ((count < word_weight) && (count < h_bit)) { + if (turn_on) + word += gpower[word_weight] - gpower[word_weight - count]; + h_bit -= count; + word_weight -= count; + count = 0; + } + else if ((count >= h_bit) && (h_bit <= word_weight)) { + if (turn_on) + word += gpower[word_weight] - gpower[word_weight - h_bit]; + *rowptr++ = word; + send_row(); + rowptr = row; + rows_left -= repeat_count + 1; + repeat_count = 0; + word = 0; + word_weight = 16; + count -= h_bit; + h_bit = char_width; + } + else { + if (turn_on) + word += gpower[word_weight]; + *rowptr++ = word; + word = 0; + count -= word_weight; + h_bit -= word_weight; + word_weight = 16; + } + } + turn_on ^= 1; + } + if ((rows_left != 0) || (h_bit != char_width)) { + Fatal("Bad pk file - more bits than required\n"); + return; + } +} + + + /* + * This deals with bit mapped raster (dyn_f = 14). + * It uses get_pk_bit(). + */ +void +bitmap_raster(dp) +short *dp; +{ + register int i; + register int j; + register int word; + register int word_weight; + + bit_weight = 0; + + for (i = 0; i < char_height; i++) { + word = 0; + word_weight = 15; + for (j = 0; j < char_width; j++) { + if (get_pk_bit()) + word += power[word_weight]; + if (word_weight-- == 0) { + *dp++ = word; + word = 0; + word_weight = 15; + } + } + if (word_weight < 15) + *dp++ = word; + } +} + + + /* + * This reads the pk file preamble and rejects the file + * if it does not start correctly. + */ +void +get_pk_preamble() +{ + register int comment_length; + + got_pk_post = FALSE; + fseek(pkfp, 0L, 0); + pk_loc = 0; + if (get_pk_byte() != PK_PRE) { + Fatal("Bad pk file - doesn't start with pk_pre\n"); + return; + } + if (get_pk_byte() != PK_ID) { + Fatal("Bad pk file - wrong pk_id byte\n"); + return; + } + comment_length = get_pk_byte(); + while (comment_length--) + get_pk_byte(); + (void)get_pk_double(); + (void)get_pk_double(); + (void)get_pk_double(); + (void)get_pk_double(); +} + + + /* + * This reads the preamble for one character up to the tfm width. + * The tfm width is read as when it is stored in the char_entry + * struct it needs to be multiplied by the font "s" parameter. + * ReadCharDefs() is passed a pointer to the font_entry struct + * so it can do this whereas LoadAChar() can't. + * The rest of the char will either be skipped or read with + * get_pk_char_dimen(). + * flag_byte will have been set by a previous skip_specials(). + */ +void +get_pk_char_code() +{ + dyn_f = flag_byte >> 4; + turn_on = (flag_byte & 0x8) >> 3; + flag_byte &= 0x7; + pk_char_start = pk_loc - 1; /* - 1 as flag byte has been read */ + + if (flag_byte < 4) { /* short preamble */ + packet_length = (flag_byte << 8) + get_pk_byte(); + char_code = get_pk_byte(); + tfm_width = get_pk_byte() << 16; + tfm_width += get_pk_word(); + packet_length -= 3; /* correct for reading tfm_width */ + } + else if (flag_byte < 7) { /* extended short preamble */ + packet_length = ((flag_byte - 4) << 16) + get_pk_word(); + char_code = get_pk_byte(); + tfm_width = get_pk_byte() << 16; + tfm_width += get_pk_word(); + packet_length -= 3; + } + else { /* long preamble */ + packet_length = get_pk_double(); + char_code = get_pk_double(); + tfm_width = get_pk_double(); + packet_length -= 4; + } +} + + /* + * This reads the char preamble starting after the tfm width, + * carrying on where get_pk_char_code() left off. + */ +void +get_pk_char_dimen() +{ + if (flag_byte < 4) { /* short preamble */ + hor_esc = get_pk_byte(); + char_width = get_pk_byte(); + word_width = (char_width + 15)>>4; + char_height = get_pk_byte(); + h_off = (char)get_pk_byte(); + v_off = (char)get_pk_byte(); + } + else if (flag_byte < 7) { /* extended short preamble */ + hor_esc = get_pk_word(); + char_width = get_pk_word(); + word_width = (char_width + 15)>>4; + char_height = get_pk_word(); + h_off = (short)get_pk_word(); + v_off = (short)get_pk_word(); + } + else { /* long preamble */ + hor_esc = get_pk_double(); + vert_esc = get_pk_double(); + char_width = get_pk_double(); + word_width = (char_width + 15)>>4; + char_height = get_pk_double(); + h_off = get_pk_double(); + v_off = get_pk_double(); + } +} + + + /* + * This reads the preamble for one character. + */ +void +get_pk_char_preamble() +{ + flag_byte = get_pk_byte(); + get_pk_char_code(); + get_pk_char_dimen(); +} + + +/* + * Now here are the routines called by the rest of textool + */ + +/*-->FindFontFile*/ + +void +FindFontFile(tfontptr, mag) +struct font_entry *tfontptr; +unsigned int mag; +{ + char *direct, *tcp, *tcp1; + int found; + char curarea[STRSIZE]; + + tfontptr->font_mag = (int)( + ActualFactor((int)(((float)tfontptr->s/(float)tfontptr->d)*1000.0+0.5)) +#ifdef USEGLOBALMAG + * ActualFactor(mag) +#endif + * (float)RESOLUTION + 0.5); +#ifdef DEBUG + if (ExtraDebug) { + fprintf(stderr, "FindFontFile():\n"); + fprintf(stderr, " mag = %d\n", mag); + fprintf(stderr, " s = %d\n", tfontptr->s); + fprintf(stderr, " d = %d\n", tfontptr->d); + fprintf(stderr, " font_mag = %d\n", tfontptr->font_mag); + } +#endif + if (tfontptr->a != 0) { + sprintf(tfontptr->name, "%s.%dpk", tfontptr->n, tfontptr->font_mag); + } else { + direct = PKpath; + found = FALSE; + do { + tcp = index(direct, ':'); + if (tcp == NULL) tcp = strlen(direct) + direct; + strncpy(curarea, direct, tcp-direct); + tcp1 = curarea + (tcp - direct); + *tcp1++ = '/'; + *tcp1++ = '\0'; + + sprintf(tfontptr->name, "%s%s.%dpk", + curarea, tfontptr->n, tfontptr->font_mag); + found = (access(tfontptr->name, R_OK) == 0); + if (*tcp) direct = tcp + 1; else direct = tcp; + } while ( !found && *direct != '\0'); + } +#ifdef DEBUG + if (ExtraDebug) + fprintf(stderr, "FindFontFile() returns with name %s\n", + tfontptr->name); +#endif +} + + +/*-->LoadAChar*/ + +void +LoadAChar(ptr) +register struct char_entry *ptr; +{ + register Pixrect *pr; + register short *dp; + + pkfp = OpenFontFile(); + if (ptr->where.address.fileOffset == 0) { + ptr->where.address.pixrectptr = NULL; + return; + } + fseek(pkfp, ptr->where.address.fileOffset, 0); + get_pk_char_preamble(); + ptr->width = char_width; + ptr->height = char_height; + ptr->xOffset= h_off; + ptr->yOffset = v_off; + if ((pr = mem_create(ptr->width, ptr->height, 1)) == NULL) { + Fatal("Couldn't allocate pixrect"); + return; + } + dp = ((struct mpr_data *)pr->pr_data)->md_image; + if (dyn_f == 14) + bitmap_raster(dp); + else + normal_raster(dp); + ptr->where.address.pixrectptr = pr; + ptr->where.isloaded = TRUE; +} + + +/*-->ReadCharDefs*/ + +void +ReadCharDefs(tfontptr, fp) +struct font_entry *tfontptr; +FILE *fp; +{ + register struct char_entry *tcharptr; /* temporary char_entry pointer */ + register Pixrect *pr; + register int junk_count; + short *dp; + +#ifdef DEBUG + if (ExtraDebug) + fprintf(stderr, "ReadCharDefs() for font %s\n", tfontptr->name); +#endif + pkfp = fp; + get_pk_preamble(); + skip_specials(); + while (!got_pk_post) { + get_pk_char_code(); + tcharptr = &(tfontptr->ch[char_code]); + tcharptr->tfmw = tfm_width * (float)tfontptr->s / (float)(1<<20); + if (BigPreLoad) { + /* + * Load the rest of the character info. + */ + get_pk_char_dimen(); + tcharptr->width = char_width; + tcharptr->height = char_height; + tcharptr->xOffset= h_off; + tcharptr->yOffset = v_off; + if ((pr = mem_create(char_width, char_height, 1)) == NULL) { + Fatal("Couldn't allocate pixrect"); + return; + } + dp = ((struct mpr_data *)pr->pr_data)->md_image; + if (dyn_f == 14) + bitmap_raster(dp); + else + normal_raster(dp); + tcharptr->where.address.pixrectptr = pr; + tcharptr->where.isloaded = TRUE; + } + else { + tcharptr->where.isloaded = FALSE; + tcharptr->where.address.fileOffset = pk_char_start; + /* + * Otherwise skip the rest of the char. + * The bytes are read rather than using fseek as the pk files + * are small and the whole thing is likely to fit in one stdio + * buffer so this will not involve any function calls. + */ + junk_count = packet_length; + while (junk_count--) + getc(pkfp); + pk_loc += packet_length; + } + skip_specials(); + } +} + + diff --git a/dviware/textool/problems b/dviware/textool/problems new file mode 100644 index 0000000000..c5b5cda091 --- /dev/null +++ b/dviware/textool/problems @@ -0,0 +1,35 @@ +scrollbar_scroll_to() does not work when called from CanvasEventProc() + The scroll event generated by this proc does not have the scrollbar + handle as an extra arg like it should. + Hacked to work by fixing up the arg in the interposer which has to + be there anyway to do the page forward/backward commands. + + Fixed in V3.2 + +menu_show() doesn't return ordinal position as default value + Fixed by putting in explicit MENU_VALUE. + +mpr_d() macro seems to give problem + Fixed by not using it. + +/SunView/Ttysubwindow/Retained still used by SunView but not be defaults editor + Defaults file edited by hand. + + Probably changed in v3.2. + +File descriptors asociated with TTY subwindows not being closed correctly +when window destroyed. + Hacked by noting their fd number relative to the fd for the frame with + the "show fd" menu choice and closing them, hoping that the fds are + always allocated in the same order. + + Program later changed so this frame is not destroyed, just undisplayed. + +Problem with TTY subwindows in two subframes. If you destroy one but not the +other the undestroyed frame is displayed with nothing in it. + Not fixed yet. Program changed not to have two subframes. This means + that the "shell" frame is not permanent but is shared with the "tex", + "latex" and "edit" ones. + +frame_default_done_proc() is misdefined in /usr/include/suntool/frame.h + It should use FRAME_DEFAULT_DONE_PROC. Fixed by editing include file. diff --git a/dviware/textool/pxlstuff.c b/dviware/textool/pxlstuff.c new file mode 100644 index 0000000000..c74d431699 --- /dev/null +++ b/dviware/textool/pxlstuff.c @@ -0,0 +1,173 @@ +/* + * This is the font specific bit of textool. + * This version supports PXL format files, which are easy to use but big. + */ + +#include "defs.h" +#include <stdio.h> +#include <sys/file.h> /* for access() stuff */ +#include <pixrect/pixrect_hs.h> /* for LoadAChar() */ +char *index(); +char *rindex(); +char *sprintf(); +char *strcpy(); + +/* procedures in sunstuff */ +extern void Fatal(); +extern void Warning(); + +/* procedures in dvistuff */ +extern float ActualFactor(); +extern int NoSignExtend(); +extern FILE *OpenFontFile(); + +/* procedures here */ +void FindFontFile(); +void LoadAChar(); +void ReadCharDefs(); + +/* a few global variables and data structures */ +#include "globals.h" + +/* now to the real code */ + +/*-->FindFontFile*/ +/**********************************************************************/ +/************************ FindFontFile ******************************/ +/**********************************************************************/ + +void +FindFontFile(tfontptr, mag) +struct font_entry *tfontptr; +unsigned int mag; +{ + char *direct, *tcp, *tcp1; + int found; + char curarea[STRSIZE]; + + tfontptr->font_mag = (int)((ActualFactor((int)(((float)tfontptr->s/ + (float)tfontptr->d)*1000.0 + 0.5)) * +#ifdef USEGLOBALMAG + ActualFactor(mag) * +#endif + (float)RESOLUTION * 5.0) + 0.5); + if (tfontptr->a != 0) { + sprintf(tfontptr->name, "%s.%dpxl", tfontptr->n, tfontptr->font_mag); + } + else { + direct = PXLpath; + found = FALSE; + do { + tcp = index(direct, ':'); + if (tcp == NULL) + tcp = strlen(direct) + direct; + strncpy(curarea, direct, tcp-direct); + tcp1 = curarea + (tcp - direct); + *tcp1++ = '/'; + *tcp1++ = '\0'; + + sprintf(tfontptr->name, "%s%s.%dpxl", + curarea, tfontptr->n, tfontptr->font_mag); + found = (access(tfontptr->name, R_OK) == 0); + if (*tcp) + direct = tcp + 1; + else + direct = tcp; + } while ( !found && *direct != '\0'); + } +} + + +/*-->LoadAChar*/ +/**********************************************************************/ +/***************************** LoadAChar ****************************/ +/**********************************************************************/ + +void +LoadAChar(ptr) +register struct char_entry *ptr; +{ + register Pixrect *pr; + register int nshorts, i, col, nints; + register short *dp, *sp; + int buffer[8]; + FILE *pxlfp; + + pxlfp = OpenFontFile(); + if (ptr->where.address.fileOffset == 0) { + ptr->where.address.pixrectptr = NULL; + return; + } + fseek(pxlfp, ptr->where.address.fileOffset, 0); + if ((pr = mem_create(ptr->width, ptr->height, 1)) == NULL) { + Fatal("Couldn't allocate pixrect"); + return; + } + nshorts = (ptr->width + 15) >> 4; + /* + * the following test is done because + * some bogus font files once caused + * the pixrect to be overfilled, damaging + * other font data structures + */ + if (nshorts != (((struct mpr_data *)pr->pr_data)->md_linebytes >> 1)) { + Fatal("Pixrect too narrow for font"); + return; + } + nints = (nshorts + 1) >> 1; + dp = ((struct mpr_data *)pr->pr_data)->md_image; + for (col = 0; col < ptr->height; col++) { + fread(buffer, 4, nints, pxlfp); + sp = (short *)&buffer[0]; + for (i = nshorts; i > 0; i--) + *dp++ = *sp++; + } + ptr->where.address.pixrectptr = pr; + ptr->where.isloaded = TRUE; +} + + +/*-->ReadCharDefs*/ +/**********************************************************************/ +/***************************** ReadCharDefs *************************/ +/**********************************************************************/ + +void +ReadCharDefs(tfontptr, pxlfp) +struct font_entry *tfontptr; +FILE *pxlfp; +{ + int t, i; + register struct char_entry *tcharptr; /* temporary char_entry pointer */ + + if ((t = NoSignExtend(pxlfp, 4)) != PXLID) { + Fatal("PXL ID = %d, can only process PXL ID = %d files", + t, PXLID); + return; + } + fseek(pxlfp, -20, 2); + t = NoSignExtend(pxlfp, 4); + if ((tfontptr->c != 0) && (t != 0) && (tfontptr->c != t)) + Warning("font = \"%s\",\n-->font checksum = %d,\n-->dvi checksum = %d", + tfontptr->name, tfontptr->c, t); + (void)NoSignExtend(pxlfp, 4); /* throw away magnification */ + (void)NoSignExtend(pxlfp, 4); /* throw away design size */ + + fseek(pxlfp, NoSignExtend(pxlfp, 4) * 4, 0); + + for (i = FIRSTPXLCHAR; i <= LASTPXLCHAR; i++) { + tcharptr = &(tfontptr->ch[i]); + tcharptr->width = NoSignExtend(pxlfp, 2); + tcharptr->height = NoSignExtend(pxlfp, 2); + tcharptr->xOffset= SignExtend(pxlfp, 2); + tcharptr->yOffset = SignExtend(pxlfp, 2); + tcharptr->where.isloaded = FALSE; + tcharptr->where.address.fileOffset = NoSignExtend(pxlfp, 4) << 2; + tcharptr->tfmw = ((float)NoSignExtend(pxlfp, 4)*(float)tfontptr->s) / + (float)(1<<20); + } + if (BigPreLoad) /* load all char pixrects */ + for (i = FIRSTPXLCHAR; i <= LASTPXLCHAR; i++) + LoadAChar(&(tfontptr->ch[i])); +} + diff --git a/dviware/textool/sunstuff.c b/dviware/textool/sunstuff.c new file mode 100644 index 0000000000..54457101ba --- /dev/null +++ b/dviware/textool/sunstuff.c @@ -0,0 +1,1620 @@ +/* + * This file contains the Sun specific bits of TeXtool, a TeX previewer + * derived from the texview posted on the network about spring 86, which + * in turn was derived from an earlier version and so on right back to + * a version for the BBN Bitgraph. + * + * This stuff deals with all SunView related things and calls things + * in the dvistuff file to do the DVI file and font file stuff, which + * in turn calls things in here like SetChar and SetRule to drive the + * screen. + */ + +/* + * Version 2.1 of 30 Oct 87 -- first real outside release + * + * -> V2.2, 27 Nov 87 -- fixed bug where .dvi file was opened twice, + * once from FrameDoneProc() and once by the WIN_REPAINT + * case in CanvasEventProc(). This ran us out of fds. + * -> V2.3, 29 Mar 88 -- fixed sloppy code in skip_specials() in +pkstuff.c + * that caused specials +to be missed and treated as chars. + + */ + +/* include the various global #defines */ +#include "defs.h" + +/* now some definitions for the menu items */ +/* + * NOTE: The menu items must be in the positions in the menu given by + * these values. This is not done automatically! + */ +#define M_NULL 0 +#define M_RESTART 1 +#define M_NEWPAGE 2 +#define M_NEWFILE 3 +#define M_CD 4 +#define M_TEX 5 +#define M_LATEX 6 +#define M_EDIT 7 +#define M_SHELL 8 +#define SM_TOGGLE_P 0x11 +#define SM_TOGGLE_BIGP 0x12 +#define SM_TOGGLE_B 0x13 +#define SM_TOGGLE_M 0x14 +#define DM_TOGGLE_D 0x21 +#define DM_TOGGLE_X 0x22 +#define DM_SHOW_FD 0x23 +#define DM_SHOW_PXL_CACHE 0x24 + +/* now some Sun include files */ +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/file.h> +#include <stdio.h> +#include <pwd.h> +#include <pixrect/pixrect_hs.h> +#include <suntool/sunview.h> +#include <suntool/icon_load.h> +#include <suntool/canvas.h> +#include <suntool/scrollbar.h> +#include <suntool/panel.h> +#include <suntool/tty.h> + +/* general external procedures */ +char *getenv(); +char *index(); +char *rindex(); +char *sprintf(); +char *strcpy(); +char *strcat(); +int strlen(); +char *getwd(); + +/* procedures from dvistuff */ +extern void CloseDviFile(); +extern void DoPage(); +extern Boolean DviFileChanged(); +extern void FreeFontStorage(); +extern void OpenDviFile(); +#ifdef DEBUG +extern void ShowPxlFd(); +extern void ShowPxlCache(); +#endif + +/* procedures from pxlstuff or pkstuff */ +extern void LoadAChar(); + +/* procedures in this file */ +void BatchEnd(); +void BatchStart(); +void CanvasEventProc(); +Notify_value CanvasInterposer(); +void CheckFiles(); +void ErrorEventProc(); +char *ExpandTilde(); +void Fatal(); +void FrameDoneProc(); +void InitWindows(); +void MenuCd(); +void MenuEdit(); +Menu MenuGenerate(); +void MenuLatex(); +void MenuNewFile(); +void MenuNewPage(); +void MenuRestart(); +void MenuShell(); +void MenuShortPage(); +void MenuTex(); +void MenuToggleFlag(); +void ProcessPage(); +void RestartDviFile(); +void SetBop(); +void SetChar(); +void SetFrameLabel(); +void SetPageMenu(); +void SetRule(); +Menu ShiftMenuGenerate(); +void SplitFilename(); +void TextInputProc(); +void Warning(); +#ifdef DEBUG +Menu DebugMenuGenerate(); +void ShowFd(); +#endif + +/* now include real global variables needed by both files */ +#define _DEFINE +#include "globals.h" + +/* now the "globals" only needed here */ + +static char progname[STRSIZE]; /* program name */ +static char ttyinbuf[STRSIZE]; /* for input to ttysubwindow */ +static char dirbuf[STRSIZE]; /* current working dir. */ +static char framelabelbuf[STRSIZE]; /* for frame label */ +static char curarea[STRSIZE]; /* current file area */ +static char curext[STRSIZE]; /* current file extension */ +static char curname[STRSIZE]; /* current file name */ +static char textinputbuffer[STRSIZE]; /* for copying text panel item value */ +static char dviname[STRSIZE]; /* current complete DVI filename */ +static short textinput_state; + +/* display related stuff */ + +static int hh; /* current horizontal position in pixels */ +static int vv; /* current vertical position in pixels */ +static int current_page; /* pagepointers index for current page */ + +static int xcanvasoffset = RESOLUTION; /* 1 inch offset to match TeX's */ +static int ycanvasoffset = RESOLUTION; /* 1 inch margin on paper */ + +static Boolean keyscroll; /* bodge to say h,j,k or l typed */ + +/* SunView defs */ +Frame frame; +Icon icon; +Canvas canvas; +Pixwin *pw; +Scrollbar vsb, hsb; +Cursor canvas_cursor; +Menu menu, tenpagemenu, shiftmenu; +Menu_item shortpageitem, longpageitem; +Frame ttyframe; +Tty ttysubwindow; +Frame errorframe; +Panel errorpanel; +Panel_item errorheader, errormessage; +Panel_item textinput; +#ifdef DEBUG +Menu debugmenu; +#endif + +/* now the real code */ + +main(argc, argv) +int argc; +char *argv[]; + +{ + + extern int optind; + extern char *optarg; + int c; + + strcpy(progname, argv[0]); + + /* initialse some globals */ + Debug = FALSE; + ExtraDebug = FALSE; + PreLoad = FALSE; + BigPreLoad = FALSE; + Batching = TRUE; + main_state = SB_INITIAL; + Mflag = FALSE; + pagepointers = NULL; /* we haven't malloc'd them yet */ + + InitWindows(&argc, argv); /* setup windows and consume -W args */ + + current_page = 0; /* start at the beginning */ + + /* get enviroment variables for different PXL directories */ + + if ((PXLpath=getenv("PXLPATH")) == NULL) + PXLpath = PXLFONTAREA; + if ((PKpath=getenv("PKPATH")) == NULL) + PKpath = PKFONTAREA; + + while ((c = getopt(argc, argv, "dxpPbm:")) != EOF) + switch(c) { + case 'd': /* d selects Debug output */ + Debug = TRUE; + break; + + case 'x': /* extra debug info for pxl files */ + ExtraDebug = TRUE; + break; + + case 'p': /* p enables font pre-loading */ + PreLoad = TRUE; + break; + + case 'P': /* P enables char pixrect pre-loading */ + BigPreLoad = TRUE; + break; + + case 'b': /* turn batching off for slowness */ + Batching = FALSE; + break; + + case 'm': /* specify mag to override that in DVI file */ + Mflag = TRUE; + user_mag = atoi(optarg); + break; + + case '?': + default: + fprintf(stderr, + "usage: textool [-pPb] [-m <mag>] [+n] file\n"); + exit(1); + } + + if ((optind < argc) && (argv[optind][0] == '+')) + /* we have starting page number */ + sscanf(&argv[optind][1], "%d", ¤t_page); + + if (optind >= argc) { + main_state = SB_NOFILE; /* cancel SB_INITIAL status */ + SplitFilename("<no_file>"); /* _ as icon labels don't like space */ + } + else + SplitFilename(argv[optind]); + SetFrameLabel(); + +#ifdef DEBUG + if (Debug) fprintf(stderr,"going into window_main_loop()\n"); +#endif + window_main_loop(frame); +} + + +/*-->InitWindows*/ + +void +InitWindows(argcptr, argv) /* initialize SunView stuff */ +int *argcptr; +char **argv; + +{ +Pixrect *pr1; +char error[IL_ERRORMSG_SIZE]; +int i; + + pr1 = icon_load_mpr("/u/tex/textool/textool.icon", error); + if (pr1 == NULL) /* couldn't load icon */ + fprintf(stderr, "%s\n", error); + /* not Fatal() as windows are not yet active */ + icon = icon_create(ICON_IMAGE, pr1, + 0); + + frame = window_create(0,FRAME, + WIN_WIDTH, 900, + WIN_HEIGHT, 900, + WIN_X, 100, + WIN_Y, 0, + WIN_SHOW, FALSE, + FRAME_LABEL, "TeXtool", + FRAME_ICON, icon, + FRAME_ARGC_PTR_ARGV, argcptr, argv, + 0); + + vsb = scrollbar_create(SCROLL_LINE_HEIGHT, 20, + SCROLL_ADVANCED_MODE, TRUE, + 0); + hsb = scrollbar_create(SCROLL_LINE_HEIGHT, 20, + SCROLL_ADVANCED_MODE, TRUE, + 0); + + canvas = window_create(frame,CANVAS, + CANVAS_AUTO_SHRINK, FALSE, + CANVAS_AUTO_EXPAND, FALSE, + CANVAS_WIDTH, (17 * RESOLUTION)/2, /* 8.5in */ + CANVAS_HEIGHT, 12 * RESOLUTION, /* 12in */ + WIN_VERTICAL_SCROLLBAR, vsb, + WIN_HORIZONTAL_SCROLLBAR, hsb, + WIN_CONSUME_KBD_EVENT, WIN_ASCII_EVENTS, + WIN_EVENT_PROC, CanvasEventProc, + 0); + pw = canvas_pixwin(canvas); + + /* interpose before canvas for pageing */ + (void)notify_interpose_event_func(canvas, CanvasInterposer, NOTIFY_SAFE); + + scrollbar_scroll_to(hsb, (long)RESOLUTION/2); + scrollbar_scroll_to(vsb, (long)RESOLUTION); + + /* now make the menu for canvas */ + tenpagemenu = menu_create(MENU_ACTION_PROC, MenuShortPage, 0); + menu_set(tenpagemenu, + MENU_STRING_ITEM, "1", 1, + MENU_STRING_ITEM, "2", 2, + MENU_STRING_ITEM, "3", 3, + MENU_STRING_ITEM, "4", 4, + MENU_STRING_ITEM, "5", 5, + MENU_STRING_ITEM, "6", 6, + MENU_STRING_ITEM, "7", 7, + MENU_STRING_ITEM, "8", 8, + MENU_STRING_ITEM, "9", 9, + MENU_STRING_ITEM, "10", 10, + 0); + + shortpageitem = menu_create_item(MENU_PULLRIGHT_ITEM, "go to page", + tenpagemenu, 0); + longpageitem = menu_create_item(MENU_ACTION_ITEM, "go to page", + MenuNewPage, 0); + + menu = menu_create(MENU_GEN_PROC, MenuGenerate, + MENU_ITEM, + MENU_ACTION_ITEM, "restart DVI file", MenuRestart, + 0, + MENU_ITEM, + MENU_ACTION_ITEM, "new file", MenuNewFile, + 0, + MENU_ITEM, + MENU_ACTION_ITEM, "change directory", MenuCd, + 0, + MENU_ITEM, + MENU_ACTION_ITEM, "run tex", MenuTex, + 0, + MENU_ITEM, + MENU_ACTION_ITEM, "run latex", MenuLatex, + 0, + MENU_ITEM, + MENU_ACTION_ITEM, "edit .tex file", MenuEdit, + 0, + MENU_ITEM, + MENU_ACTION_ITEM, "shell", MenuShell, + 0,0); + menu_set(menu, MENU_INSERT, 1, shortpageitem, 0); + + /* now a second menu for shift-right button */ + shiftmenu = menu_create(MENU_GEN_PROC, ShiftMenuGenerate, + MENU_ITEM, + MENU_ACTION_PROC, MenuToggleFlag, + MENU_VALUE, SM_TOGGLE_P, + 0, + MENU_ITEM, + MENU_ACTION_PROC, MenuToggleFlag, + MENU_VALUE, SM_TOGGLE_BIGP, + 0, + MENU_ITEM, + MENU_ACTION_PROC, MenuToggleFlag, + MENU_VALUE, SM_TOGGLE_B, + 0, + MENU_ITEM, + MENU_ACTION_PROC, MenuToggleFlag, + MENU_VALUE, SM_TOGGLE_M, + 0,0); + +#ifdef DEBUG + /* now a debug menu for the meta key */ + debugmenu = menu_create(MENU_GEN_PROC, DebugMenuGenerate, + MENU_ITEM, + MENU_ACTION_PROC, MenuToggleFlag, + MENU_VALUE, DM_TOGGLE_D, + 0, + MENU_ITEM, + MENU_ACTION_PROC, MenuToggleFlag, + MENU_VALUE, DM_TOGGLE_X, + 0, + MENU_ITEM, + MENU_ACTION_ITEM, "show fd", ShowFd, + MENU_VALUE, DM_SHOW_FD, + 0, + MENU_ITEM, + MENU_ACTION_ITEM, "show PXL cache", ShowPxlCache, + MENU_VALUE, DM_SHOW_PXL_CACHE, + 0,0); +#endif DEBUG + + /* now create a frame and panel for errors */ + + errorframe = window_create(frame, FRAME, + FRAME_NO_CONFIRM, TRUE, + WIN_SHOW, FALSE, + WIN_COLUMNS, 80, + WIN_ROWS, 2, + WIN_X, 100, + WIN_Y, 100, + 0); + errorpanel = window_create(errorframe, PANEL, + PANEL_BACKGROUND_PROC, ErrorEventProc, + PANEL_EVENT_PROC, ErrorEventProc, + 0); + errorheader = panel_create_item(errorpanel, PANEL_MESSAGE, + PANEL_LABEL_STRING, "TeXtool Warning:", + 0); + errormessage = panel_create_item(errorpanel, PANEL_MESSAGE, + PANEL_LABEL_STRING, "dummy message", + 0); + textinput = panel_create_item(errorpanel, PANEL_TEXT, + PANEL_LABEL_STRING, "Magnification:", + PANEL_ITEM_Y, ATTR_ROW(1), + PANEL_ITEM_X, ATTR_COL(0), + PANEL_SHOW_ITEM, FALSE, + PANEL_VALUE_DISPLAY_LENGTH, 40, + PANEL_NOTIFY_PROC, TextInputProc, + 0); + window_fit(errorpanel); + window_fit(errorframe); + /* create shell window for TeX, etc */ + ttyframe = window_create(frame, FRAME, + FRAME_LABEL, "TeXtool Shell", + FRAME_SHOW_LABEL, TRUE, + FRAME_NO_CONFIRM, TRUE, + FRAME_DONE_PROC, FrameDoneProc, + WIN_X, 25, + WIN_Y, 25, + WIN_SHOW, FALSE, + 0); + ttysubwindow = window_create(ttyframe, TTY, + 0); +} + + +/*-->SetFrameLabel*/ + +void +SetFrameLabel() +{ + if (pagepointers == NULL) + sprintf(framelabelbuf, + "TeXtool: Directory: %s File: %s%s%s", + getwd(dirbuf), curarea, curname, curext); + else + sprintf(framelabelbuf, + "TeXtool: Directory: %s File: %s%s%s \"Page\": %d \\count0: %d", + getwd(dirbuf), curarea, curname, curext, + current_page+1, pagepointers[current_page].count_0); + + + window_set(frame, FRAME_LABEL, framelabelbuf, 0); +} + + + /* + * Now two procs to deal with canvas input. + * CanvasInterposer is called first and filters out + * the vertical scroll page requests, turning them into + * calls of ProcessPage. + * CanvasEventProc handles all other input cases. + */ +/*-->CanvasInterposer*/ + +Notify_value +CanvasInterposer(object, event, arg, type) +Canvas object; +Event *event; +Notify_arg arg; +Notify_event_type type; +{ + Scroll_motion motion; + Notify_value retval; + +#ifdef DEBUG + if (Debug) fprintf(stderr,"Interposer called (%d) - ", event_id(event)); + if (Debug) fprintf(stderr, + "\nobject = %X, *event = %X, arg = %X, type = %X\n", + object, event, arg, type); +#endif + if (event_id(event) == SCROLL_REQUEST) { + if ((Scrollbar)arg == vsb) { +#ifdef DEBUG + if (Debug) fprintf(stderr,"arg is vsb, "); +#endif + motion = (Scroll_motion)scrollbar_get(vsb, SCROLL_REQUEST_MOTION); + if (!keyscroll && ((motion == SCROLL_PAGE_FORWARD) + || (motion == SCROLL_PAGE_BACKWARD))) { +#ifdef DEBUG + if (Debug) fprintf(stderr,"motion is %X (PAGE), ", (int)motion); +#endif + /* now tell bar to undo scroll */ + scrollbar_set(vsb, SCROLL_VIEW_START, + scrollbar_get(vsb, SCROLL_LAST_VIEW_START), 0); + if (motion == SCROLL_PAGE_BACKWARD) { + if (current_page-- > 0) + ProcessPage(current_page); + else + current_page++; + } + else { + if (++current_page < totalpages) + ProcessPage(current_page); + else + current_page--; + } +#ifdef DEBUG + if (Debug) fprintf(stderr,"Interposer return (DONE)\n"); +#endif + return (NOTIFY_DONE); + } + } + } +#ifdef DEBUG + if (Debug) fprintf(stderr,"calling next func\n"); +#endif + retval = (notify_next_event_func(object, event, arg, type)); + if (Debug) fprintf(stderr, "Interposer return (%X)\n", retval); + return (retval); +} + + +/*-->CanvasEventProc*/ + +void +CanvasEventProc(notused, event) +Canvas notused; +Event *event; +{ + static int intval; + +#ifdef DEBUG + if (Debug) fprintf(stderr,"event proc called (id = %d) - ", + event_id(event)); +#endif + + keyscroll = FALSE; + switch (event_id(event)) { + case '\n': + case '\r': + if (main_state & (SB_PLUSNUMBER | SB_MINUSNUMBER)) { + if ((main_state & SB_MINUSNUMBER) + && (current_page -= intval) < 0) + current_page = 0; + if ((main_state & SB_PLUSNUMBER) + && (current_page += intval) >= totalpages) + current_page = totalpages-1; + main_state &= (~SB_PLUSNUMBER & ~SB_MINUSNUMBER); + main_state |= SB_INTERPRET; + ProcessPage(current_page); + break; + } /* else fall into next page case */ + case ' ': /* normal case - start next page */ + case 'n': + main_state &= (~SB_PLUSNUMBER & ~SB_MINUSNUMBER); + main_state |= SB_INTERPRET; + if (++current_page < totalpages) + ProcessPage(current_page); + else + current_page--; + break; + + case 'b': + case 'P': + case 'p': /* redisplay from previous page */ + main_state &= (~SB_PLUSNUMBER & ~SB_MINUSNUMBER); + main_state |= SB_INTERPRET; + if (current_page-- > 0) + ProcessPage(current_page); + else + current_page++; + break; + +#ifdef KEYBOARDSCROLL + case 'j': + main_state &= (~SB_PLUSNUMBER & ~SB_MINUSNUMBER); + main_state |= SB_INTERPRET; + keyscroll = TRUE; + scrollbar_scroll_to(vsb, (long)600); + break; + + case 'h': + main_state &= (~SB_PLUSNUMBER & ~SB_MINUSNUMBER); + main_state |= SB_INTERPRET; + keyscroll = TRUE; + scrollbar_scroll_to(hsb, (long)0); + break; + + case 'l': + main_state &= (~SB_PLUSNUMBER & ~SB_MINUSNUMBER); + main_state |= SB_INTERPRET; + keyscroll = TRUE; + scrollbar_scroll_to(hsb, (long)300); + break; + + case 'k': + main_state &= (~SB_PLUSNUMBER & ~SB_MINUSNUMBER); + main_state |= SB_INTERPRET; + keyscroll = TRUE; + scrollbar_scroll_to(vsb, (long)0); + break; + + case 'c': + main_state &= (~SB_PLUSNUMBER & ~SB_MINUSNUMBER); + main_state |= SB_INTERPRET; + keyscroll = TRUE; + scrollbar_scroll_to(vsb, (long)RESOLUTION); + scrollbar_scroll_to(hsb, (long)(RESOLUTION/2)); + break; +#endif + +#ifdef DEBUG + case SCROLL_REQUEST: /* scroll request, after Sb gets it */ + { int a, b, c, d; + if (Debug) { + a = (int)scrollbar_get(vsb, SCROLL_VIEW_START); + b = (int)scrollbar_get(vsb, SCROLL_LAST_VIEW_START); + c = (int)scrollbar_get(hsb, SCROLL_VIEW_START); + d = (int)scrollbar_get(hsb, SCROLL_LAST_VIEW_START); + fprintf(stderr,"\nVsb scroll from %d to %d\n", b, a); + fprintf(stderr,"Hsb scroll from %d to %d\n", d, c); + } + } + break; + +#endif + case '-': + /* read in val */ + main_state |= SB_MINUSNUMBER; + intval = 0; + break; + + case '+': + /* read in val */ + main_state |= SB_PLUSNUMBER; + intval = 0; + break; + + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if (main_state & (SB_PLUSNUMBER | SB_MINUSNUMBER)) + intval = intval*10 + (event_id(event) - '0'); + break; + + case '\b': + case 127: /* delete key */ + if (main_state & (SB_PLUSNUMBER | SB_MINUSNUMBER)) + intval /= 10; + break; + + case MS_RIGHT: + if (event_is_up(event)) break; +#ifdef DEBUG + if (event_meta_is_down(event)) { + (void)menu_show(debugmenu, canvas, + canvas_window_event(canvas, event), 0); + break; + } +#endif + if (event_shift_is_down(event)) + (void)menu_show(shiftmenu, canvas, + canvas_window_event(canvas, event), 0); + else + (void)menu_show(menu, canvas, + canvas_window_event(canvas, event), 0); + break; + + case MS_LEFT: + canvas_cursor = window_get(canvas, WIN_CURSOR); + if (event_is_up(event)) { + cursor_set(canvas_cursor, + CURSOR_SHOW_CURSOR, TRUE, + CURSOR_SHOW_CROSSHAIRS, FALSE, + 0); + } + else { + /* + * All these except the pixrect op + * are defaults but it does not seem + * to work unles they are specified + */ + cursor_set(canvas_cursor, + CURSOR_SHOW_CURSOR, FALSE, + CURSOR_CROSSHAIR_COLOR, 1, + CURSOR_CROSSHAIR_THICKNESS, 1, + CURSOR_CROSSHAIR_GAP, 0, + CURSOR_CROSSHAIR_LENGTH, CURSOR_TO_EDGE, + CURSOR_CROSSHAIR_OP, PIX_SRC|PIX_DST, + CURSOR_SHOW_CROSSHAIRS, TRUE, + 0); + } + window_set(canvas, WIN_CURSOR, canvas_cursor, 0); + break; + + case WIN_REPAINT: + if (main_state & SB_INITIAL) { /* first time of display */ + main_state &= ~SB_INITIAL; + CheckFiles(); /* sets main_state */ + OpenDviFile(dviname); + if (main_state & (SB_NOFILE | SB_NODVIFILE)) + break; + SetPageMenu(); + main_state &= ~SB_NEWFILE; + main_state |= SB_INTERPRET; + ProcessPage(current_page); + } + break; + + default: +#ifdef DEBUG + if (Debug) fprintf(stderr,"event proc default case - "); +#endif + } +#ifdef DEBUG + if (Debug) fprintf(stderr,"event proc return\n"); +#endif +} + + + /* + * Now the procedures that actually do the work of + * drawing on the screen. These get called from + * dvistuff to prevent it having to know about + * SunView. + * SetBop just clears the screen and sets the initial + * offset. SetChar and SetRule draw text and lines. + */ +/*-->SetBop*/ + +void +SetBop() +{ + pw_writebackground(pw, 0, 0, + pw->pw_prretained->pr_size.x, pw->pw_prretained->pr_size.y, + PIX_CLR); + /* + * Start with h and v at offset point rather than 0,0. + * This means that offset does not need to be added in + * on every call to SetChar and SetRule. + */ + h = xcanvasoffset * hconv; + v = ycanvasoffset * vconv; +} + + +/*-->SetChar*/ + +void +SetChar(charptr, Set) +struct char_entry *charptr; +Boolean Set; +{ + hh = PixRound(h, hconv); + vv = PixRound(v, vconv); + if (!charptr->where.isloaded) LoadAChar(charptr); + if (charptr->where.isloaded == TRUE) + pw_rop(pw, hh-charptr->xOffset, + vv-charptr->yOffset, + charptr->width, charptr->height, PIX_SRC | PIX_DST, + charptr->where.address.pixrectptr, 0, 0); + if (Set) + h += charptr->tfmw; +} + + +/*-->SetRule*/ + +void +SetRule(a, b, Set) +int a, b; +Boolean Set; + +{ /* this routine draws \hrule and \vrule */ + int ehh, evv; + + hh = PixRound(h, hconv); + vv = PixRound(v-a, vconv); + ehh = PixRound(h + b, hconv); + evv = PixRound(v, vconv); + if (hh == ehh) ehh++; + if (vv == evv) vv--; + if ((a > 0) && (b > 0)) + pw_rop(pw, hh, vv, + ehh-hh, evv-vv, PIX_SET, NULL, 0, 0); + if (Set) + h += b; +} + + + /* + * These next two are only procedures here to avoid + * having dvistuff.c know about Pixwins. + * As they are only called once per page the loss of + * speed is not a problem. + */ +/*-->BatchStart*/ + +void +BatchStart() +{ + pw_batch_on(pw); +} + + +/*-->BatchEnd*/ + +void +BatchEnd() +{ + pw_batch_off(pw); +} + + + /* + * Now two procedures that call on things in + * dvistuff to get pages displayed. + */ +/*-->ProcessPage*/ + +void +ProcessPage(page) +int page; +{ + if (DviFileChanged()) + RestartDviFile(); + SetFrameLabel(); + DoPage(page); +} + + +/*-->RestartDviFile*/ + +void +RestartDviFile() +{ + CloseDviFile(); + FreeFontStorage(); + main_state &= (~SB_INTERPRET & ~SB_NOFILE); +/* main_state |= SB_NEWFILE; /* to allow a try at open */ + CheckFiles(); /* sets main_state */ + OpenDviFile(dviname); + if (main_state & (SB_NOFILE | SB_NODVIFILE)) /* something wrong */ + return; + SetPageMenu(); + main_state &= ~SB_NEWFILE; /* SB_NEWFILE must be set to get to here */ + main_state |= SB_INTERPRET; +} + + + /* + * Now to the menu generating procedures, one for + * each menu. There is also a procedure to set + * the "go to page" menu item depending on the + * number of pages. + * MenuGenerate() deals with most of the interlocking + * to avoid illegal menu choices. + */ +/*-->MenuGenerate*/ + +Menu +MenuGenerate(object, operation) +Menu object; +Menu_generate operation; +{ + if (operation == MENU_CREATE) { + menu_set(menu_get(object, MENU_NTH_ITEM, M_RESTART), + MENU_INACTIVE, + (main_state & (SB_TEXING | SB_NOFILE | SB_NODVIFILE ) ? + TRUE : FALSE), + 0); + menu_set(menu_get(object, MENU_NTH_ITEM, M_NEWPAGE), + MENU_INACTIVE, + (main_state & (SB_TEXING | SB_NOFILE | SB_NODVIFILE) ? + TRUE : FALSE), + 0); + menu_set(menu_get(object, MENU_NTH_ITEM, M_TEX), + MENU_INACTIVE, + (main_state & (SB_TEXING | SB_EDITING | SB_SHELL | SB_NOFILE | + SB_NOTEXFILE) ? TRUE : FALSE), + 0); + menu_set(menu_get(object, MENU_NTH_ITEM, M_LATEX), + MENU_INACTIVE, + (main_state & (SB_TEXING | SB_EDITING | SB_SHELL | SB_NOFILE | + SB_NOTEXFILE) ? TRUE : FALSE), + 0); + menu_set(menu_get(object, MENU_NTH_ITEM, M_EDIT), + MENU_INACTIVE, + (main_state & (SB_TEXING | SB_EDITING | SB_SHELL | SB_NOFILE) ? + TRUE : FALSE), + 0); + menu_set(menu_get(object, MENU_NTH_ITEM, M_SHELL), + MENU_INACTIVE, + (main_state & (SB_TEXING | SB_EDITING | SB_SHELL) ? + TRUE : FALSE), + 0); + } + return (object); + +} + + +/*-->ShiftMenuGenerate*/ + +Menu +ShiftMenuGenerate(object, operation) +Menu object; +Menu_generate operation; +{ + if (operation == MENU_CREATE) { + menu_set(menu_get(object, MENU_NTH_ITEM, SM_TOGGLE_P & 0xF), + MENU_STRING, (PreLoad ? "reset -p flag" : "set -p flag"), + 0); + menu_set(menu_get(object, MENU_NTH_ITEM, SM_TOGGLE_B & 0xF), + MENU_STRING, (Batching ? "set -b flag" : "reset -b flag"), + 0); + menu_set(menu_get(object, MENU_NTH_ITEM, SM_TOGGLE_BIGP & 0xF), + MENU_STRING, (BigPreLoad ? "reset -P flag" : "set -P flag"), + 0); +#ifdef USEGLOBALMAG + menu_set(menu_get(object, MENU_NTH_ITEM, SM_TOGGLE_M & 0xF), + MENU_STRING, (Mflag ? "reset -m flag" : "set -m flag"), + 0); +#endif + } + return (object); +} + + +#ifdef DEBUG +/*-->DebugMenuGenerate*/ + +Menu +DebugMenuGenerate(object, operation) +Menu object; +Menu_generate operation; +{ + if (operation == MENU_CREATE) { + menu_set(menu_get(object, MENU_NTH_ITEM, DM_TOGGLE_D & 0xF), + MENU_STRING, (Debug ? "reset -d flag" : "set -d flag"), + 0); + menu_set(menu_get(object, MENU_NTH_ITEM, DM_TOGGLE_X & 0xF), + MENU_STRING, (ExtraDebug ? "reset -x flag" : "set -x flag"), + 0); + } + return (object); +} +#endif DEBUG + + +/*-->SetPageMenu*/ + +void +SetPageMenu() +{ + short i; + + if (totalpages > 10) + menu_set(menu, + MENU_REPLACE, 2, longpageitem, + 0); + else { + menu_set(menu, + MENU_REPLACE, 2, shortpageitem, + 0); + for (i = 0; i < 10; i++) + menu_set(menu_get(tenpagemenu, MENU_NTH_ITEM, i+1, 0), + MENU_INACTIVE, (i < totalpages ? FALSE : TRUE), + 0); + } +} + + + /* + * Now the action procs called after a menu selection + * is made. + */ +/*-->MenuRestart*/ + +void +MenuRestart(object, item) +Menu object; +Menu_item item; +{ + window_release_event_lock(canvas); /* "I may be some time" */ + current_page = 0; + RestartDviFile(); + DoPage(current_page); +} + + +/*-->MenuNewPage*/ + +void +MenuNewPage(object, item) +Menu object; +Menu_item item; +{ + panel_set(textinput, + PANEL_LABEL_STRING, "Page number:", + PANEL_VALUE, "", + PANEL_SHOW_ITEM, TRUE, + 0); + panel_set(errorheader, + PANEL_SHOW_ITEM, FALSE, + 0); + panel_set(errormessage, + PANEL_LABEL_STRING, "", + PANEL_SHOW_ITEM, FALSE, + 0); + window_fit(errorpanel); + window_fit(errorframe); + window_set(errorframe, + WIN_X, 100, + WIN_Y, 100, + WIN_SHOW, TRUE, + 0); + textinput_state = M_NEWPAGE; +} + + +/*-->MenuShortPage*/ + +void +MenuShortPage(object, item) +Menu object; +Menu_item item; +{ + current_page = (int)menu_get(item, MENU_VALUE, 0); + current_page--; /* as current_page =0 for page 1 */ + if (current_page >= totalpages) + current_page = totalpages - 1; + ProcessPage(current_page); +} + + +/*-->MenuNewFile*/ + +void +MenuNewFile(object, item) +Menu object; +Menu_item item; +{ + panel_set(textinput, + PANEL_LABEL_STRING, "Filename:", + PANEL_VALUE, "", + PANEL_SHOW_ITEM, TRUE, + 0); + panel_set(errorheader, + PANEL_SHOW_ITEM, FALSE, + 0); + panel_set(errormessage, + PANEL_LABEL_STRING, "", + PANEL_SHOW_ITEM, FALSE, + 0); + window_fit(errorpanel); + window_fit(errorframe); + window_set(errorframe, + WIN_X, 100, + WIN_Y, 100, + WIN_SHOW, TRUE, + 0); + textinput_state = M_NEWFILE; +} + + +/*-->MenuCd*/ + +void +MenuCd(object, item) +Menu object; +Menu_item item; +{ + panel_set(textinput, + PANEL_LABEL_STRING, "Directory:", + PANEL_VALUE, "", + PANEL_SHOW_ITEM, TRUE, + 0); + panel_set(errorheader, + PANEL_SHOW_ITEM, FALSE, + 0); + panel_set(errormessage, + PANEL_LABEL_STRING, "", + PANEL_SHOW_ITEM, FALSE, + 0); + window_fit(errorpanel); + window_fit(errorframe); + window_set(errorframe, + WIN_X, 100, + WIN_Y, 100, + WIN_SHOW, TRUE, + 0); + textinput_state = M_CD; +} + + +/*-->MenuTex*/ + +void +MenuTex(object, item) +Menu object; +Menu_item item; +{ + strcpy(ttyinbuf, "cd "); + strcat(ttyinbuf, getwd(dirbuf)); + strcat(ttyinbuf, "\ntex "); + strcat(ttyinbuf, curname); + strcat(ttyinbuf, ".tex\n"); + (void)ttysw_input(ttysubwindow, ttyinbuf, strlen(ttyinbuf)); + main_state |= SB_TEXING; + window_set(ttyframe, WIN_SHOW, TRUE, 0); +} + + +/*-->MenuLatex*/ + +void +MenuLatex(object, item) +Menu object; +Menu_item item; +{ + strcpy(ttyinbuf, "cd "); + strcat(ttyinbuf, getwd(dirbuf)); + strcat(ttyinbuf, "\nlatex "); + strcat(ttyinbuf, curname); + strcat(ttyinbuf, ".tex\n"); + (void)ttysw_input(ttysubwindow, ttyinbuf, strlen(ttyinbuf)); + main_state |= SB_TEXING; + window_set(ttyframe, WIN_SHOW, TRUE, 0); +} + + +/*-->MenuEdit*/ + +void +MenuEdit(object, item) +Menu object; +Menu_item item; +{ + char *tcp; + + if ((tcp = getenv("EDITOR")) == NULL) + tcp = "vi"; + strcpy(ttyinbuf, tcp); + strcat(ttyinbuf, " "); + strcat(ttyinbuf, getwd(dirbuf)); + strcat(ttyinbuf, "/"); + strcat(ttyinbuf, curname); + strcat(ttyinbuf, ".tex\n"); + (void)ttysw_input(ttysubwindow, ttyinbuf, strlen(ttyinbuf)); + main_state |= SB_EDITING; + window_set(ttyframe, WIN_SHOW, TRUE, 0); +} + + +/*-->MenuShell*/ + +void +MenuShell(object, item) +Menu object; +Menu_item item; +{ + main_state |= SB_SHELL; + window_set(ttyframe, WIN_SHOW, TRUE, 0); +} + + +/*-->MenuToggleFlag*/ + +void +MenuToggleFlag(object, item) +Menu object; +Menu_item item; +{ + int itemvalue; + + itemvalue = (int)menu_get(item, MENU_VALUE, 0); + + switch (itemvalue) { +#ifdef DEBUG + case DM_TOGGLE_D: + Debug ^= 1; + break; + case DM_TOGGLE_X: + ExtraDebug ^= 1; + break; +#endif + case SM_TOGGLE_P: + PreLoad ^= 1; + break; + case SM_TOGGLE_B: + Batching ^= 1; + break; + case SM_TOGGLE_BIGP: + BigPreLoad ^= 1; + break; +#ifdef USEGLOBALMAG + case SM_TOGGLE_M: + Mflag ^= 1; + if (Mflag) { + panel_set(textinput, + PANEL_LABEL_STRING, "Magnification:", + PANEL_VALUE, "", + PANEL_SHOW_ITEM, TRUE, + 0); + panel_set(errorheader, + PANEL_SHOW_ITEM, FALSE, + 0); + panel_set(errormessage, + PANEL_LABEL_STRING, "", + PANEL_SHOW_ITEM, FALSE, + 0); + window_fit(errorpanel); + window_fit(errorframe); + window_set(errorframe, + WIN_X, 100, + WIN_Y, 100, + WIN_SHOW, TRUE, + 0); + textinput_state = SM_TOGGLE_M; + } + break; +#endif + default: + break; + } +} + + + /* + * The event proc for the panel which contains the + * error message item and the text input item. + * If the panel event is an ascii one it passes it + * on to the text input item. It removes the panel + * on a left mouse button. + */ +/*-->ErrorEventProc*/ + +void +ErrorEventProc(object, event) +Panel object; +Event *event; +{ + if (event_id(event) <= ASCII_LAST) + panel_accept_key(textinput, event); + else if (event_id(event) == MS_LEFT) + window_set(errorframe, + WIN_SHOW, FALSE, + 0); +} + + + /* + * The notify proc for the panel text input item. + * This gets things like page numbers and filenames + * from the user. + */ +/*-->TextInputProc*/ + +void +TextInputProc(item, event) +Panel_item item; +Event *event; +{ +#ifdef DEBUG + if (Debug) + fprintf(stderr,"TextInputProc(): panel_get_value returns %s\n", + (char *)panel_get_value(textinput)); +#endif + strcpy(textinputbuffer, (char *)panel_get_value(textinput)); + window_set(errorframe, + WIN_SHOW, FALSE, + 0); + if (*textinputbuffer == NULL) + return; + switch(textinput_state) { + case M_NEWPAGE: + sscanf(textinputbuffer, "%d", ¤t_page); + current_page--; + if (current_page >= totalpages) + current_page = totalpages - 1; + ProcessPage(current_page); + break; + + case M_NEWFILE: + window_release_event_lock(errorframe); + /* as this may take some time */ + SplitFilename(ExpandTilde(textinputbuffer)); + /* sets dviname */ + CloseDviFile(); /* from dvifp */ + FreeFontStorage(); + SetBop(); /* clear screen */ + current_page = 0; + main_state &= (~SB_INTERPRET & ~SB_NOFILE); + CheckFiles(); /* see what's there */ + OpenDviFile(dviname); /* sets dvifp */ + SetFrameLabel(); + if (main_state & (SB_NOFILE | SB_NODVIFILE)) /* something wrong */ + break; + SetPageMenu(); + main_state &= ~SB_NEWFILE; + main_state |= SB_INTERPRET; + DoPage(current_page); + break; + + case M_CD: + if (chdir(ExpandTilde(textinputbuffer))) + Warning("Couldn't change directory"); + SetFrameLabel(); + break; + + case SM_TOGGLE_M: + user_mag = atoi(textinputbuffer); + break; + + default: + break; + } +} + + + /* + * The done proc for the frame with the tty subwindow. + * It removes the frame and adjusts the display if the + * DVI file has changed. + */ +/*-->FrameDoneProc*/ + +void +FrameDoneProc(object) +Frame object; +{ + int i; + + if (Debug) { + fprintf(stderr, + "FrameDoneProc(), object = %X, frame = %X, ttyframe = %X\n", + object, frame, ttyframe); + fprintf(stderr,"calling default done proc for object\n"); + } + frame_default_done_proc(object); + main_state &= (~SB_TEXING & ~SB_EDITING & ~SB_SHELL); + CheckFiles(); /* see if anything changed */ + if (main_state & SB_NEWFILE) { /* we haven't seen it before */ + OpenDviFile(dviname); + if (main_state & SB_NOFILE)/* can't have NODVIFILE as NEWFILE was set */ + return; + main_state &= ~SB_NEWFILE; + main_state |= SB_INTERPRET; + DoPage(current_page); + } + else if (DviFileChanged()) { + RestartDviFile(); + DoPage(current_page); + } +} + + + /* + * Now some utility procedures. + */ +/*-->SplitFilename*/ + +void +SplitFilename(nameptr) +char *nameptr; +{ + char *tcp, *tcp1; + Icon temp_icon; /* for changing label */ + /* process filename */ + tcp = rindex(nameptr, '/'); + if (tcp == NULL) { + curarea[0] = '\0'; + tcp = nameptr; + } + else { + strncpy(curarea, nameptr, tcp-nameptr+1); + curarea[tcp-nameptr+1] = '\0'; /* as strncpy will not do this */ + tcp += 1; + } + tcp1 = index(tcp, '.'); + if (tcp1 == NULL) { + strcpy(curname, tcp); + curext[0] = '\0'; + } + else { + strncpy(curname, tcp, tcp1-tcp); + strcpy(curext, tcp1); + } + + strcpy(dviname, curarea); + strcat(dviname, curname); + if (curext[0] == '\0') + strcat(dviname, ".dvi"); + else + strcat(dviname, curext); +#ifdef DEBUG + if (Debug) { + fprintf(stderr,"curarea = %s\n", curarea); + fprintf(stderr,"curname = %s\nsetting icon label to curname\n", + curname); + fprintf(stderr,"curext = %s\n", curext); + fprintf(stderr,"dviname = %s\n", dviname); + } +#endif + temp_icon = (Icon)window_get(frame, FRAME_ICON, 0); + icon_set(temp_icon, ICON_LABEL, curname, 0); + window_set(frame, FRAME_ICON, temp_icon, 0); +} + + + /* + * CheckFiles tries access on the .dvi file, + * and if that does not exist, on the .tex file + * and sets main_state accordingly. + */ +/*-->CheckFiles*/ + +void +CheckFiles() +{ + char buf[STRSIZE]; + + if (access(dviname, F_OK | R_OK) == 0) { /* .dvi file present */ + if (main_state & SB_NODVIFILE) /* first time .dvi file found */ + main_state |= SB_NEWFILE; + main_state &= (~SB_NODVIFILE & ~SB_NOTEXFILE); + } + else { + strcpy(buf, curarea); + strcat(buf, curname); + strcat(buf, ".tex"); + if (access(buf, F_OK | R_OK) == 0) { /* no .dvi file but .tex file ok */ + main_state |= SB_NODVIFILE; + main_state &= (~SB_NEWFILE & ~SB_NOTEXFILE); + } + else { /* no .tex file either */ + main_state |= SB_NODVIFILE | SB_NOTEXFILE; + main_state &= ~SB_NEWFILE; + } + } + +} + + +/*-->ExpandTilde*/ + +char * +ExpandTilde(iptr) +char *iptr; +{ + char buff[STRSIZE]; + char *tptr; + struct passwd *passwdptr; + +#ifdef DEBUG + if (Debug) fprintf(stderr,"ExpandTilde(%s) - ", iptr); +#endif + if (*iptr == '~') { /* something to do */ + strcpy(buff, iptr); + tptr = index(buff, '/'); + if ((strlen(buff) == 1) || ((tptr-buff) == 1)) + /* expand to our $HOME */ + strcpy(iptr, getenv("HOME")); + else { /* ~name/... form */ + if (tptr != NULL) *tptr = 0; + if ((passwdptr = getpwnam(&buff[1])) != NULL) + strcpy(iptr, passwdptr->pw_dir); + if (tptr != NULL) *tptr = '/'; + } + if (tptr != NULL) + strcat(iptr, tptr); /* complete rest of path if there is any */ + } +#ifdef DEBUG + if (Debug) fprintf(stderr,"returns %s\n", iptr); +#endif + return (iptr); +} + + + /* + * Two error message procedures. + * Warning just displays the message, Error displays + * and then abandons the DVI file and goes to the + * NOFILE state. + */ +/*-->Warning*/ + +void +Warning(fmt, arg1, arg2, arg3, arg4) /* issue a warning */ +char *fmt; /* format */ +char *arg1, *arg2, *arg3, *arg4; /* arguments */ +{ + char message[STRSIZE]; + + sprintf(message, fmt, arg1, arg2, arg3, arg4); + + panel_set(errorheader, + PANEL_LABEL_STRING, "TeXtool Warning:", + PANEL_SHOW_ITEM, TRUE, + 0); + panel_set(errormessage, + PANEL_LABEL_STRING, message, + PANEL_SHOW_ITEM, TRUE, + 0); + panel_set(textinput, + PANEL_SHOW_ITEM, FALSE, + 0); + window_fit(errorpanel); + window_fit(errorframe); + window_set(errorframe, + WIN_X, 100, + WIN_Y, 100, + WIN_SHOW, TRUE, + 0); +} + + +/*-->Fatal*/ + +void +Fatal(fmt, arg1, arg2, arg3, arg4)/* issue a fatal error message */ +char *fmt; /* format */ +char *arg1, *arg2, *arg3, *arg4; /* arguments */ + +{ + char message[STRSIZE]; + + sprintf(message, fmt, arg1, arg2, arg3, arg4); + panel_set(errorheader, + PANEL_LABEL_STRING, "TeXtool Error:", + PANEL_SHOW_ITEM, TRUE, + 0); + panel_set(errormessage, + PANEL_LABEL_STRING, message, + PANEL_SHOW_ITEM, TRUE, + 0); + panel_set(textinput, + PANEL_SHOW_ITEM, FALSE, + 0); + window_fit(errorpanel); + window_fit(errorframe); + window_set(errorframe, + WIN_X, 100, + WIN_Y, 100, + WIN_SHOW, TRUE, + 0); + CloseDviFile(); + FreeFontStorage(); /* to get to known stable state */ + main_state |= SB_NOFILE; /* to stop further processing */ + main_state &= (~SB_NEWFILE & ~SB_NODVIFILE & ~SB_NOTEXFILE & ~SB_INTERPRET); + SplitFilename("<no_file>"); + SetFrameLabel(); +} + + +#ifdef DEBUG + /* + * A procedure to show the fds we are using. + * There was a leak of fds somewhere where ptys were + * not closed when a frame with a tty subwindow in it + * was destroyed and this was used to find it. + * The tty subframe is now not destroyed but just + * undisplayed to cure the problem. + * It also shows the huge number of fds needed by + * SunView which cuts down on the number available for + * PXL file caching. + */ +/*-->ShowFd*/ + +void +ShowFd(object, item) +Menu object; +Menu_item item; +{ + short i; + struct stat statbuf; + + fprintf(stderr,"frame %d, win%d\n", + window_get(frame, WIN_FD), window_get(frame, WIN_DEVICE_NUMBER)); + fprintf(stderr,"canvas %d, win%d\n", + window_get(canvas, WIN_FD), window_get(canvas, WIN_DEVICE_NUMBER)); + fprintf(stderr,"ttyframe %d, win%d\n", + window_get(ttyframe, WIN_FD), window_get(ttyframe, WIN_DEVICE_NUMBER)); + fprintf(stderr,"ttysubwindow %d, win%d\n", + window_get(ttysubwindow, WIN_FD), + window_get(ttysubwindow, WIN_DEVICE_NUMBER)); + fprintf(stderr,"errorframe %d, win%d\n", + window_get(errorframe, WIN_FD), window_get(errorframe, WIN_DEVICE_NUMBER)); + fprintf(stderr,"errorpanel %d, win%d\n", + window_get(errorpanel, WIN_FD), window_get(errorpanel, WIN_DEVICE_NUMBER)); + ShowPxlFd(); + + for (i=0; i<30; i++) /* enumerate fds */ + if (fstat(i,&statbuf) == 0) + fprintf(stderr,"fd %d open, type = %o, inode = %d\n", + i, + statbuf.st_mode & S_IFMT, + statbuf.st_ino); +} +#endif + diff --git a/dviware/textool/textool.fix b/dviware/textool/textool.fix new file mode 100644 index 0000000000..aae1373855 --- /dev/null +++ b/dviware/textool/textool.fix @@ -0,0 +1,92 @@ +*** sunstuff.c Tue Mar 29 08:06:23 1988 +--- sunstuff.c.old Tue Mar 29 08:02:13 1988 +*************** +*** 16,23 **** + * -> V2.2, 27 Nov 87 -- fixed bug where .dvi file was opened twice, + * once from FrameDoneProc() and once by the WIN_REPAINT + * case in CanvasEventProc(). This ran us out of fds. +- * -> V2.3, 29 Mar 88 -- fixed sloppy code in skip_specials() in pkstuff.c +- * that caused specials to be missed and treated as chars. + */ + + /* include the various global #defines */ +--- 16,21 ---- +*** pkstuff.c Tue Mar 29 08:05:07 1988 +--- pkstuff.c.old Tue Mar 29 08:02:03 1988 +*************** +*** 5,15 **** + * See the pktopx documentation for details. + */ + +- /* +- * For V2.3, 29 Mar 88 +- * Fixed stupid errors in skip_specials() that caused specials to be missed +- */ +- + #include "defs.h" + #include <stdio.h> + #include <sys/file.h> /* for access() stuff */ +--- 5,10 ---- +*************** +*** 190,200 **** + case PK_XXX4: + i = get_pk_byte(); + case PK_XXX3: +! i = (i<<8) + get_pk_byte(); + case PK_XXX2: +! i = (i<<8) + get_pk_byte(); + case PK_XXX1: +! i = (i<<8) + get_pk_byte(); + while (i--) + (void)get_pk_byte(); + break; +--- 185,195 ---- + case PK_XXX4: + i = get_pk_byte(); + case PK_XXX3: +! i = i<<8 + get_pk_byte(); + case PK_XXX2: +! i = i<<8 + get_pk_byte(); + case PK_XXX1: +! i = i<<8 + get_pk_byte(); + while (i--) + (void)get_pk_byte(); + break; +*************** +*** 215,221 **** + flag_byte); + return; + } +! } while (flag_byte >= PK_XXX1); + } + + +--- 210,216 ---- + flag_byte); + return; + } +! } while (flag_byte > PK_XXX1); + } + + +*** textool.l Tue Mar 29 09:24:36 1988 +--- textool.l.old Tue Mar 29 09:24:09 1988 +*************** +*** 187,193 **** + The following things are taken from the environment: + .TP + .B PKPATH +! A colon separated list of directories to search for the font PK files + in place of the default described below. + .TP + .B HOME +--- 187,193 ---- + The following things are taken from the environment: + .TP + .B PKPATH +! A comma separated list of directories to search for the font PK files + in place of the default described below. + .TP + .B HOME + +End of diffs. diff --git a/dviware/textool/textool.icon b/dviware/textool/textool.icon new file mode 100644 index 0000000000..93dc3c5c54 --- /dev/null +++ b/dviware/textool/textool.icon @@ -0,0 +1,36 @@ +/* Format_version=1, Width=64, Height=64, Depth=1, Valid_bits_per_item=16 + * Description: A model 120 display and keyboard. + * Background: white + */ + 0xFFFF,0xFFFF,0xFFFF,0xFFFF,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8FFF,0xFF00,0x00C0,0x0031,0x8FFF,0xFF00,0x00E0,0x0071, + 0x8C06,0x0300,0x0070,0x00E1,0x8006,0x0000,0x0038,0x01C1, + 0x8006,0x03FF,0xFFDC,0x0381,0x8006,0x03FF,0xFFCE,0x0701, + 0x8006,0x0300,0x00C7,0x0E01,0x8006,0x0300,0x0003,0x9C01, + 0x8006,0x0300,0x0001,0xF801,0x8006,0x0300,0x0000,0xF001, + 0x8006,0x0300,0x0000,0xF001,0x8006,0x0300,0x0001,0xF801, + 0x8006,0x0300,0xC003,0x9C01,0x8006,0x03FF,0xC007,0x0E01, + 0x8006,0x03FF,0xC00E,0x0701,0x8006,0x0300,0xC01C,0x0381, + 0x8006,0x0300,0x0038,0x01C1,0x8006,0x0300,0x0070,0x00E1, + 0x800F,0x0300,0x00E0,0x0071,0x800F,0x0300,0x00C0,0x0031, + 0x8000,0x0300,0x0000,0x0001,0x8000,0x0300,0x00C0,0x0001, + 0x8000,0x03FF,0xFFC0,0x0001,0x8000,0x03FF,0xFFC0,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0xFFFF,0xFFFF,0xFFFF,0xFFFF, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0x8000,0x0000,0x0000,0x0001, + 0x8000,0x0000,0x0000,0x0001,0xFFFF,0xFFFF,0xFFFF,0xFFFF diff --git a/dviware/textool/textool.l b/dviware/textool/textool.l new file mode 100644 index 0000000000..9ae203ddeb --- /dev/null +++ b/dviware/textool/textool.l @@ -0,0 +1,224 @@ +.TH TEXTOOL 1 +.SH NAME +textool \- TeX previewer for suntools +.SH SYNOPSIS +.B textool +[ +.B \-p +] [ +.B \-P +] [ +.B \-b +] [ +.B \-m +.I <mag> +] [ \+n ] [dvifile[.dvi]] +.SH DESCRIPTION +.LP +The +.I textool +program displays a TeX DVI file in a SunView window. +It is an enhanced version of the old "dvisun" command. +It can be driven either by keyboard commands typed into its window +or by using the mouse and various menus. +The label along the top of the window gives the current working directory, +the current filename and the current page number. +If invoked with no filename argument it will just display an empty +window. +If given a file it will read the preamble, postamble and page backpointers +so that it can go straight to a given page. +This means that it will only display files, it will not read stdin. +After each page of the +output is displayed the program will wait for a response from the user. +.SH OPTIONS +.TP +.B \-p +Pre-load all the font descriptions for fonts mentioned in the DVI file. +Normally only the information from the DVI postamble is loaded and the +various PK files are opened on demand. +This option loads all the character information except the actual character +bitmaps before displaying the first page. +.TP +.B \-P +A stronger version of the above. +In this case the character bitmaps are pre-loaded as well. +If this option is used no PK files will need to be accessed after the first +page is displayed. +The penalty is extra memory used for characters that may not be printed. +.TP +.BI \-m mag +This option gives a magnification factor (in the TeX form with +1000 for a magnification of 1) which will over-ride any magnification factor +specified in the DVI file. +The program may be compiled with this option disabled as it is uncommon +to have a set of PK files at several different magnifications. +.TP +.B \-b +This turns off SunView batching. +This slows page display down by a factor of about three but you get the +top lines of the screen displayed more quickly. +.TP +.BI \+ number +Skip +.I number +pages before displaying anything. +.LP +As well as those options described above +.I textool +will also consume the standard suntools options of the form \-W*, +for example the command "textool -Wi &" will start an instance +of +.I textool +in its iconic state in the background. +This can be used as a tool as and when required. +.SH "KEYBOARD COMMANDS" +.LP +Keyboard commands are provided to go forward and backwards 1 or n pages in +the file and to provide basic scrolling. +They are: +.TP +.B return +Go to next page in file. +.TP +.B space +Same as return. +.TP +.B b +Go to previous page in file. +.TP +.B p +Same as b. +.TP +.BI \+ nn +Skip forward +.I nn +pages. +The number is terminated with return. +.TP +.BI \- nn +Go back +.I nn +pages. +The number is again terminated with return. +.TP +.B h +Scroll over to the left edge of the page. +.TP +.B j +Scroll to bottom of page. +.TP +.B k +Scroll to top of page. +.TP +.B l +Scroll over to right edge of page. +.TP +.B c +Scroll to initial position, which is one inch down from the top and +half an inch in from the left edge. +.SH "MOUSE COMMANDS" +.LP +Both horizontal and vertical scrollbars are provided and these work in the +standard Sun fashion. +In particular the middle mouse button in either of the vertical bar's +page bottons will go to the next page and a shifted middle button will +go back a page. +.LP +Pressing the left mouse button changes the cursor to a set of cross-hairs +so alignment can be checked. +The arrow cursor is restored by releasing the button. +.LP +A menu is provided, popped up with the right mouse button, to do more +complex things. +Selections from this menu which require user text input will pop up a +text input panel with an appropriate prompt. +This panel is also used for error messages. +An error message can be removed by clicking on the panel with the left +mouse button. +Operations are interlocked to prevent impossible or inadvisable choices; +for example if there is no current file you cannot select the +"restart dvi file" or "go to page" choices. +.LP +The various selections are described below: +.TP +.B "restart dvi file" +This is a complete restart with the current file. +The DVI file is closed, font storage is freed and all PK files closed. +The file is then reopened and processed from scratch. +.TP +.B "go to page" +This allows direct access to any page in the file. +For documents of 10 pages or less a pullright menu is provided to select +the actual page. +For longer documents you must enter the page number into the pop up +panel. +.TP +.B "new file" +This closes the current file, as in the restart case, and then prompts for +a new file to process. +A leading ~ on the file name is interpreted in the same way as +.IR csh . +.TP +.B "change directory" +This prompts for a directory to replace the current working directory. +Leading ~ is allowed as in the "new file" case. +.TP +.B "run tex" +This creates a new window and runs tex on the .tex file with the same +basename as the current DVI file. +Only one extra window is allowed so all the other selections which +would require one are dimmed while the tex window is open. +As the DVI file is assumed to be changing the restart and page choices are +also dimmed. +To remove the window select "done" from its frame menu. +.TP +.B "run latex" +This is the same as the "run tex" case but runs latex instead. +.TP +.B "edit .tex file" +This runs an editor on the .tex file. +The EDITOR from the environment is used if there is one, otherwise +/usr/ucb/vi is used. +.TP +.B shell +This creates a window running whatever shell SunView finds for you. +.SH ENVIRONMENT +.LP +The following things are taken from the environment: +.TP +.B PKPATH +A comma separated list of directories to search for the font PK files +in place of the default described below. +.TP +.B HOME +Used for expanding tilde expressions of the form ~/dir. +.TP +.B EDITOR +The editor to use for the "edit .tex file" menu choice. +.SH FILES +.TP 2.5i +*.dvi +TeX DeVice Independent output file +.TP +/usr/local/lib/tex/fonts/pk/*.*pk +TeX default font rasters +.TP +/etc/passwd +Used for expanding tilde expressions of the form ~name/dir. +.SH "SEE ALSO" +dvitype(1), +dvisun(1), +tex(1) +.SH BUGS +When using fonts with decent resolution only part of a page appears +on the screen. +.SH AUTHORS +Mark Senn wrote the early versions of this program for the BBN BitGraph. +Stephan Bechtolsheim, Bob Brown, Richard Furuta, James Schaad +and Robert Wells improved it. +Norm Hutchinson ported the program to the Sun, becoming dvisun. +Yves Ledru did the initial suntools port, making texview. +Peter Ilieve re-did the suntools part, +tidied up and changed the font cacheing in the DVI part +and changed it to use PK files for fonts. + diff --git a/dviware/textool/textool.pdf b/dviware/textool/textool.pdf Binary files differnew file mode 100644 index 0000000000..ed22767870 --- /dev/null +++ b/dviware/textool/textool.pdf |