|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T d
Length: 20548 (0x5044) Types: TextFile Names: »dvireader.h«
└─⟦52210d11f⟧ Bits:30007239 EUUGD2: TeX 3 1992-12 └─⟦883b7f77d⟧ »dvi2vdu.tar.Z« └─⟦f158c222e⟧ └─⟦this⟧ »dvi2vdu/dvi2vdu-1.1J/src/dvireader.h«
/* Modified for JTeX M.Kitagawa (kitagawa@wave.ntt.jp) 8 May 1990 */ /* Original Author: Andrew Trevorrow Implementation: Modula-2 under VAX/UNIX 4.2 BSD Date Started: June, 1986 Description: DVIReader exports routines and data structures for moving about randomly in a TeX82 DVI file and interpreting pages. DVItoVDU (an interactive page previewer) is currently the only client, but it is anticipated that DVIReader could just as well form the basis of a more conventional DVI translator (such as a non-interactive device driver). Limitations: - DVIReader does not look at the preamble and so ignores any comments there. - DVIReader does not do any terminal i/o, even upon detecting a fatal error. The client must write a DVIErrorRoutine that will be invoked at the time an error is detected. See below for details. - DVIReader knows little about the format of PXL, RST or similar such files. It only knows they contain crucial information for typesetting a DVI file. The client must write a PixelTableRoutine to read some sort of font file and fill in the pixel table information used to interpret a DVI page. See below for details. - The data structures used to represent an interpreted DVI page are best suited to a client whose output device is randomly addressable. Some clients may need to convert the information in the data structures into a more suitable format (such a task may even be impractical). Algorithm for a simple DVI translator: < initialize the DVIErrorRoutine used to handle various errors > < initialize filespec, resolution, etc. > OpenDVIFile(filespec); < initialize magnification, probably with DVImag > SetConversionFactor(resolution,magnification); < initialize the SpecialRoutine used in InterpretPage > < initialize the PixelTableRoutine used in InterpretPage > FOR p := 1 TO totalpages DO MoveToDVIPage(p); InterpretPage; IF pageempty THEN < process an empty page > ELSE < check that the page edges are within the paper edges > < process the rule list > < process the character list for each font used on the page > END; END; CloseDVIFile; ------------------------------------------------------------------------------- This version converted to C and ported to BSD and System V UNIX by some chaps at Kernel Technology up to September 1989. Contact mjh@uk.co.kernel (Mark J. Hewitt) with bug fixes etc. Involved were: Mark J. Hewitt Dave Dixon Marc Hadley */ static char *sccsid_dvir[] = "@(#)dvireader.h 1.1"; #define RULETABLESIZE 300 /* maximum number of rules in a ruletable */ #define CHARTABLESIZE 3000 /* maximum number of chars in a chartable */ #define MAXFONTSPEC 82 /* maximum length of a font file spec */ /* #define MAXTEXCHAR 129 */ /* DVI and font files should use char codes */ /* in 0..127 */ /* (Knuth's TRIP.DVI has codes > 127!) */ #define MAXTEXCHAR 255 /* Fixed for JTeX */ /* The major page structures are defined first. Information about the rules and characters appearing on a page is stored in dynamic one-way lists to avoid imposing any limit on their numbers. To reduce pointer overheads, the nodes in these lists contain large tables (the values of RULETABLESIZE and CHARTABLESIZE have been chosen so that the vast majority of DVI pages will only require one-node lists). When interpreting a DVI page, DVIReader adds a new rule or character node to the TAIL of the relevant list. This is done so that when the client accesses such lists (starting at the head), rules and characters will be processed in somewhat the same sequence as seen in the DVI file; i.e., top-to-bottom and left-to-right across the page. Since a character list is part of the information stored for a font, the precise sequence in which DVI characters are seen is not remembered. Font information is also linked together in a one-way list, but the ordering is more or less random (see, however, the SortFonts routine). */ struct ruleinfo { /* a node in a list of ruletables */ unsigned int rulecount ; /* number of rules in ruletable */ struct ruletab { int hp, vp ; /* pixel coords of rule's ref point*/ int wd, ht ; /* dimensions of rule in pixels */ } ruletable[RULETABLESIZE]; struct ruleinfo *nextrule ; /* next node in rule list */ } ; typedef struct ruleinfo *ruleinfoptr ; struct charinfo { /* a node in list of chartables */ unsigned int charcount ; /* number of chars in chartable */ struct chartab { int hp, vp ; /* pixel coords of char's ref point*/ short code; /* char's code and pixeltable index*/ } chartable[CHARTABLESIZE]; struct charinfo *nextchar ; /* next node in char list */ } ; typedef struct charinfo *charinfoptr ; /* pixeltable must be filled in by the client's PixelTableRoutine. DVIReader uses wd, ht, xo and yo to calculate minhp, minvp, maxhp and maxvp. It uses dwidth and pwidth to advance horizontally after setting a character. The mapadr field is not used by DVIReader. */ typedef struct pixtabstr { int wd, ht ; /* glyph width and height in pixels; they define the size of the smallest box containing all the black pixels */ int xo, yo ; /* x and y offsets from top left corner of glyph to character's reference point */ int dwidth ; /* advance width in DVI units computed from fix width stored in font file */ int pwidth ; /* advance width in pixels computed from fix width stored in font file */ unsigned int mapadr ; /* starting address of pixel map in font file (could be a word or byte offset; DVIReader neither knows nor cares) */ } pixtabstr; typedef struct pixtabstr *pixeltableptr ; typedef char fontstring[MAXFONTSPEC] ; typedef struct fontinfo *fontinfoptr; struct fontinfo { /* a node in list of fonts */ short fontused; /* is font used on current page? */ int fontnum; /* DVI font number: -2^31 .. 2^30 - 1*/ unsigned int scaledsize; /* scaled font size in DVI units */ unsigned int designsize; /* design size in DVI units */ fontstring fontarea; /* explicit font directory */ unsigned int fontarealen;/* length of fontarea */ fontstring fontname; /* font name; e.g., "cmr10" */ unsigned int fontnamelen;/* length of font name */ fontstring fontspec; /* client's font file specification */ unsigned int fontspeclen;/* length of fontspec */ unsigned int totalchars; /* number of chars from font on page */ charinfoptr charlist; /* head of char information list */ charinfoptr chartail; /* tail of char information list */ pixeltableptr pixelptr; /* allocated once: 1st time font used*/ fontinfoptr nextfont; /* next node in font list */ }; /* For the parameter in MoveToTeXPage: */ typedef int TeXcounters[10]; struct TeXpageinfo { TeXcounters value ; /* \count0..\count9 values */ short present[10] ; /* is counter relevant? */ short lastvalue ; /* last relevant counter */ }; /* For the parameter in client's DVIErrorRoutine: */ typedef unsigned short DVIerrorcodes; #define DVIunopened 0x00 /* OpenDVIFile could not open the given file */ #define DVIempty 0x01 /* OpenDVIFile detected an empty file */ #define DVIbadid 0x02 /* OpenDVIFile found an invalid TeX82 DVI file*/ #define DVIstackoverflow 0x03 /* OpenDVIFile found DVIReader's stck too smll*/ #define DVIbadchar 0x04 /* InterpretPage is ignoring a */ /* char code > MAXTEXCHAR */ /* (found while processing currfont^)*/ #define DVIcatastrophe 0x05 /* DVIReader found a situation that should */ /* never occur; client should scream */ /* for help and halt*/ /* For the function parameter in client's SpecialRoutine: */ typedef int (*GetByteFunction)() ; /* returns next DVI byte */ /* Most of these should be treated as read-only parameters: */ unsigned int DVImag, /* magnification stored in DVI file */ totalpages, /* number of pages in DVI file */ totalfonts, /* number of fonts in DVI file */ currDVIpage; /* updated by MoveTo... calls */ TeXcounters currTeXpage; /* ditto */ unsigned int totalrules; /* number of rules on current page */ ruleinfoptr rulelist, /* head of rule information list */ ruletail; /* tail of rule information list */ fontinfoptr fontlist, /* head of font information list */ currfont; /* InterpretPage's current font info */ short pageempty; /* is page empty of rules and chars? */ int minhp, /* minimum horizontal pixel coordinate */ minvp, /* minimum vertical pixel coordinate */ maxhp, /* maximum horizontal pixel coordinate */ maxvp; /* maximum vertical pixel coordinate */ void InitReader(); Void (*DVIErrorRoutine)(); /* The client MUST assign a procedure before the first OpenDVIFile call. Various DVIReader routines will call this procedure if they detect some sort of problem; the given argument will be one of the error codes described above. The client's routine can use this code to see what sort of error has occurred and take appropriate action. Most errors detected by DVIReader are fatal; the client should print some sort of message and halt. See DVItoVDU for an example DVIErrorRoutine. */ Void (*SpecialRoutine)(); /* The client can assign a procedure before the first InterpretPage call. InterpretPage will call this procedure to process the bytes belonging to a \special command. The first argument gives the number of bytes; the second argument is a function that returns the value of the next byte (0..255, but usually the ordinal value of a displayable ASCII character). The client's routine might look something like: PROCEDURE MySpecialRoutine (totalbytes : INTEGER; NextByte : GetByteFunction); VAR i, nextval : INTEGER; BEGIN FOR i := 1 TO totalbytes DO nextval := NextByte(); < process nextval > END; END MySpecialRoutine; If the client does not supply a SpecialRoutine, DVIReader will simply ignore any \special bytes. */ Void (*PixelTableRoutine)(); /* The client MUST assign a procedure before the first InterpretPage call. InterpretPage will call this procedure immediately after allocating a pixel table for currfont^. This will only occur once per font (the very first time the font is used). DVIReader only knows about DVI files; the task of the PixelTableRoutine is to fill in the current font's pixel table by reading the fontspec file. (The fontspec string must first be built using the fontarea and fontname.) This file could be a PXL file, an RST file, or some other type of file. See DVItoVDU for an example of a PixelTableRoutine that reads a PXL file. */ /*PROCEDURE OpenDVIFile (filespec : ARRAY OF CHAR);*/ /* This must be the first DVIReader routine called. If the given filespec can be opened (and is a valid TeX82 DVI file) then the following global variables are initialized: DVImag := magnification value stored in DVI file (TeX's \mag) totalpages := total number of pages in DVI file currDVIpage := 0 (and remains so until a page is selected) currTeXpage := ten 0s (ditto) totalfonts := total number of fonts in DVI file (= nodes in font list) fontlist^. (nodes are added to head of list) fontused := FALSE fontnum := internal DVI font number scaledsize := scaled size of font (in DVI units) designsize := design size of font (in DVI units) fontarea := a string of min(fontarealen,MAXFONTSPEC) characters fontname := a string of min(fontnamelen,MAXFONTSPEC) characters fontspec := a null string (fontspeclen := 0) totalchars := 0 charlist := NULL chartail := NULL pixelptr := NULL nextfont := next node in font list (if not NULL) */ /*PROCEDURE SetConversionFactor (resolution, magnification : CARDINAL);*/ /* This routine must be called before the first InterpretPage call. DVIReader needs to know the client's resolution and magnification values before it attempts to convert DVI dimensions into pixel values. */ /*PROCEDURE MoveToDVIPage (n : CARDINAL);*/ /*PROCEDURE MoveToNextPage (ascending : BOOLEAN);*/ /*PROCEDURE MoveToTeXPage (VAR newTeXpage : TeXpageinfo) : BOOLEAN;*/ /* Before calling InterpretPage, the client must position DVIReader to the desired page by calling one of these MoveTo... routines. MoveToDVIPage will select the nth page in the DVI file; nothing will happen if n is not in 1..totalpages. MoveToNextPage will select the next page, depending on the current page and the specified direction. If the value of currDVIpage is 0 (set in OpenDVIFile), then MoveToNextPage will select the first page if ascending is TRUE and the last page if ascending is FALSE. If currDVIpage is > 0 then MoveToNextPage will select currDVIpage+1 if ascending (unless currDVIpage = totalpages, in which case it does nothing), or currDVIpage-1 if descending (unless currDVIpage = 0). MoveToTeXPage will search for the lowest DVI page matching the given TeX page specification. (TeX stores the values of \count0,\count1,...,\count9 with every DVI page. Plain TeX uses \count0 to control page numbering.) newTeXpage is a VAR parameter only for efficiency; it won't be changed. The value array stores the requested counter values, the present array indicates which counters are relevant and lastvalue indicates the position (0..9) of the last relevant counter. The client will probably need to first convert a more friendly representation of a TeX page request into the TeXpageinfo format. For example, [2..5] would be converted to: and [] would be converted to: value = [2,?,5,?,?,?,?,?,?,?] value = [?,?,?,?,?,?,?,?,?,?] present = [T,F,T,?,?,?,?,?,?,?] present = [F,?,?,?,?,?,?,?,?,?] lastvalue = 2 lastvalue = 0 MoveToTeXPage returns TRUE iff the requested TeX page is located. The global variables updated if a page is located by any MoveTo... call are: currDVIpage := the current DVI page (1..totalpages) currTeXpage := the ten TeX counter values stored with this page Note that currDVIpage is initially 0 until one of these routines succeeds. */ /*PROCEDURE PixelRound (DVIunits : INTEGER) : INTEGER;*/ /* One of the important tasks the client's PixelTableRoutine must carry out is to convert the fix width values from a fontspec file into DVI and pixel units; i.e., the dwidth and pwidth values stored in the pixel table. Once dwidth has been calculated (see DVITYPE or DVItoVDU for how to do this) then pwidth is easy: pwidth := PixelRound(dwidth). PixelRound can be used to convert any DVI dimension (+ve or -ve) into pixels. */ /*PROCEDURE InterpretPage;*/ /* This routine will interpret the current DVI page and update the major data structures: totalrules := number of rules on page rulelist^. (nodes are added to tail of rule list) rulecount := number of rules in this ruletable ruletable[0..rulecount-1]. hp, vp := reference point of a rule wd, ht := pixel dimensions of a rule (both > 0) nextrule := next node in rule list (if not NULL) ruletail := pointer to last node in rule list fontlist^. (the following fontinfo is relevant only if fontused is TRUE) totalchars := number of chars on page from this font charlist^. (nodes are added to tail of char list) charcount := number of chars in this chartable chartable[0..charcount-1]. hp, vp := reference point of a character code := TeX character code (and index into pixel table) nextchar := next node in char list (if not NULL) chartail := pointer to last node in char list pixelptr^[0..maxTeXchar]. (filled in by client's PixelTableRoutine) wd, ht := glyph width and height in pixels xo, yo := offsets from the character's reference point dwidth := advance width in DVI units pwidth := advance width in pixels mapadr := starting address in fontspec of the glyph's pixel map nextfont := next node in font list (if not NULL) pageempty := TRUE iff the page has no rules and no characters minhp, minvp, maxhp, maxvp := the edges of the page (undefined if pageempty is TRUE) They define the smallest rectangle containing all black pixels AND all reference points on the page; (minhp,minvp) is the top left corner. Reference points for rules and characters are stored as a pair of horizontal and vertical pixel coordinates. The point (0,0) is assumed to be the pixel 1 inch in from the top and left edges of an imaginary sheet of paper. Horizontal coordinates increase to the right and vertical coordinates increase down the paper. The number of pixels per inch is defined by the resolution parameter given to SetConversionFactor. */ /*PROCEDURE SortFonts (VAR unusedlist : fontinfoptr);*/ /* This routine will sort fontlist in ascending order of totalchars. The client may wish to do this after interpreting a page so that fonts with the least number of characters on the page will be processed first. The routine will also move all unused fonts to the end of fontlist so that the client need only process fonts up to (but excluding) unusedlist and not have to worry about checking the fontused flag. For example: SortFont(unusedlist); thisfont := fontlist; WHILE thisfont <> unusedlist DO < process the font information in thisfont^ > thisfont := thisfont^.nextfont; END; If unusedlist is NULL then either 1) all fonts are used on the current page or 2) fontlist is also NULL (totalfonts = 0). */ /*PROCEDURE CloseDVIFile;*/ /* This routine closes the currently open DVI file; it is only mandatory if OpenDVIFile is going to be called again. All dynamic data structures are deallocated. */