summaryrefslogtreecommitdiff
path: root/Build/source/texk/seetexk/dvistuff.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/seetexk/dvistuff.c')
-rw-r--r--Build/source/texk/seetexk/dvistuff.c1190
1 files changed, 0 insertions, 1190 deletions
diff --git a/Build/source/texk/seetexk/dvistuff.c b/Build/source/texk/seetexk/dvistuff.c
deleted file mode 100644
index 1831de3df7d..00000000000
--- a/Build/source/texk/seetexk/dvistuff.c
+++ /dev/null
@@ -1,1190 +0,0 @@
-/*
- * Copyright 1989 Dirk Grunwald
- *
- * Permission to use, copy, modify, distribute, and sell this software
- * and its documentation for any purpose is hereby granted without fee,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Dirk Grunwald or M.I.T.
- * not be used in advertising or publicity pertaining to distribution of
- * the software without specific, written prior permission. Dirk
- * Grunwald and M.I.T. makes no representations about the suitability of
- * this software for any purpose. It is provided "as is" without express
- * or implied warranty.
- *
- * DIRK GRUNWALD AND M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
- * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS, IN NO EVENT SHALL M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT
- * OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
- * OR PERFORMANCE OF THIS SOFTWARE.
- *
- * Author:
- * Dr. Dirk Grunwald
- * Dept. of Computer Science
- * Campus Box 430
- * Univ. of Colorado, Boulder
- * Boulder, CO 80309
- *
- * grunwald@colorado.edu
- *
- */
-
-#include <stdio.h>
-#include <ctype.h>
-
-#include "dvistuff.h" /* includes types & fonts */
-
-static char *rcsid="$Header: /home/reed/grunwald/Iptex/drivers/RCS/dvistuff.c,v 1.17 88/07/07 23:25:32 grunwald Exp Locker: grunwald $" ;
-
-#include "dviclass.h"
-#include "dvicodes.h"
-#include "postamble.h"
-#include "search.h"
-#include "fio.h"
-
-int dviHH = -1; /* current horizontal position, in DEVs */
-int dviVV = -1; /* current vertical position, in DEVs */
-long *dviCount[DVI_COUNT]; /* values of count */
-DviStack dvi_current;
-int dviHHMargin = -1; /* horizontal margin (in DEVs) */
-int dviVVMargin = -1; /* vertical margin (in DEVs) */
-int dviTallestPage = -1;
-int dviWidestPage = -1 ;
-int dviCurrentPage = -1;
-int dviTotalPages = -1;
-int dviDPI = -1;
-int dviMaxDrift = -1;
-int dviUserMag = -1; /* user-specified magnification */
-int dviBlackness = -1;
-int dviFontRotation = -1;
-char *DVIFileName;
-static char *dviTmpFileName = 0;
-static char dviTmpFileNameBuffer[256];
-FILE *dviFile; /* users file */
-char *dviPrintEngine = "canon";
-
-char *ProgName;
-
-/*
- * Similar to dvi_stack, but includes `dviHH and `dviVV, which are usually
- * but not always the same as fromSP(h) and fromSP(v):
- */
-struct localstack {
- int stack_hh;
- int stack_vv;
- struct dvi_stack stack_dvi;
-};
-
-static struct localstack *dvi_stack = 0;/* base of stack */
-static struct localstack *dvi_stackp; /* current place in stack */
-
-/*
- * DVI preamble and postamble information.
- */
-
-static long Magnification;
-static long Numerator; /* numerator from DVI file */
-static long Denominator; /* denominator from DVI file */
-
-/*
- * Font related things.
- * We keep track of the current font, use the fontfiner
- * and record errors in the dvi postable in FontErros.
- * the NoFont is a used when we cant find a font,
- * to avoid errors.
- */
-
-struct fontinfo *dviCurrentFont = 0;
-
-/*
- * imagen1-special uses the NextFamilyNumber. *sigh*
- */
-
-int NextFamilyNumber = 0;
-static int MaxFontFamily = MAX_FONTFAMILY;
-
-static struct search *FontFinder = 0;
-int FontErrors = 0;
-static struct fontinfo NoFont;
-/*
- * We keep a list of pointers to the beginning of pages.
- * Each page is headed by a DVI_BOP + 44 bytes of information.
- */
-
-static long *pageOffset = 0;
-
-#undef FIXDRIFT
-/*
- * Correct devpos (the actual device position) to be within MaxDrift pixels
- * of dvipos (the virtual DVI position).
- */
-#define FIXDRIFT(devpos, dvipos) \
- if (ABS((devpos) - (dvipos)) <= dviMaxDrift) \
- /* void */; \
- else \
- if ((devpos) < (dvipos)) \
- (devpos) = (dvipos) - dviMaxDrift; \
- else \
- (devpos) = (dvipos) + dviMaxDrift
-
-#define ABS(X) ( (X) < 0 ? -(X) : (X) )
-
-
-/*
- * Store the relevant information from the DVI postamble, and set up
- * various internal things.
- */
-static void
-PostAmbleHeader(p)
- register struct PostAmbleInfo *p;
-{
- int i;
- int page;
- int pageSize;
- int stackSize;
- long prevPagePointer;
- long wuzAt;
-
- Numerator = p->pai_Numerator;
- Denominator = p->pai_Denominator;
- Magnification = p->pai_DVIMag;
-
-/*
- * Set the conversion factor. This must be done before using
- * any fonts or the fromSP routine.
- */
-
- SetConversion(dviDPI, dviUserMag, Numerator, Denominator, Magnification);
-
- dviTotalPages = p -> pai_NumberOfPages;
- dviWidestPage = fromSP(p -> pai_WidestPageWidth);
- dviTallestPage = fromSP(p -> pai_TallestPageHeight);
-
-/*
- * Set up the DVI stack
- */
- stackSize = p -> pai_DVIStackSize * sizeof(*dvi_stack);
- if (dvi_stack != 0) {
- free(dvi_stack);
- }
- dvi_stack = (struct localstack *) malloc((unsigned) stackSize);
-
-/*
- * Set of the table of pointers to pages and room for the
- * count variables.
- */
-
- pageSize = dviTotalPages * sizeof(long);
- if (pageOffset != 0) {
- free(pageOffset);
- }
- pageOffset = (long *) malloc(pageSize);
-
- if (pageOffset == NULL) {
- fprintf(stderr,"xdvi: Can not allocate page directory (%d pages)",
- dviTotalPages);
- exit(1);
- }
-
- for (i = 0; i < DVI_COUNT; i++) {
- if (dviCount[i] != 0) {
- free(dviCount[i]);
- }
- dviCount[i] = (long*) malloc(pageSize);
- if (dviCount[i] == NULL) {
- fprintf(stderr,"xdvi: Can not allocate count directory (%d pages)",
- dviTotalPages);
- exit(1);
- }
- }
-
-
-/*
- * Follow back pointers through pages in the DVI file,
- * storing the offsets in the pageOffset table.
- */
-
- prevPagePointer = p->pai_PrevPagePointer;
- wuzAt = (long) ftell(dviFile);
-
- for (page = dviTotalPages - 1; page >= 0 ; page--) {
-
-/*
- * Skip to previous page, but skip over BOP marker.
- */
- pageOffset[page] = prevPagePointer;
- if( fseek(dviFile, prevPagePointer+1, 0) < 0) {
- perror("fseek");
- fprintf(stderr,"[postamble] improper seek looking up pages\n");
- fprintf(stderr,"prevPagePointer = %lx\n",
- prevPagePointer);
- exit(1);
- }
-
-/*
- * Read the other counters at the beginning of the page
- */
-
- for (i = 0; i < DVI_COUNT; i++) {
- long value;
- fGetLong(dviFile, value);
- dviCount[i][page] = value;
- }
- fGetLong(dviFile, prevPagePointer);
- }
- fseek(dviFile, wuzAt, 0);
-}
-
-static void
-PostAmbleFontDef(p)
-register struct PostAmbleFont *p;
-{
- register struct fontinfo *fi;
- register struct font *f;
-
- char *fname;
- int def = S_CREATE | S_EXCL;
-
- fi = (struct fontinfo *) SSearch(FontFinder, p->paf_DVIFontIndex,
- &def);
- if (fi == NULL) {
-/*
- * If the font already exists, lets just check that its really the
- * same thing & return
- */
-
- if ((def & S_FOUND) | (def & S_COLL)) {
-
- def = S_LOOKUP;
- if ((fi = (struct fontinfo *) SSearch(FontFinder,
- p -> paf_DVIFontIndex,
- &def)) == 0){
- GripeNoSuchFont(p -> paf_DVIFontIndex);
- exit(1);
- }
-
- if (fi -> f == NULL) {
- GripeCannotGetFont(p->paf_name, p->paf_DVIMag,
- p->paf_DVIDesignSize,
- dviPrintEngine, fname);
- }
- f = fi -> f;
- if (p->paf_DVIChecksum && f->f_checksum &&
- p->paf_DVIChecksum != f->f_checksum) {
- GripeDifferentChecksums(fname, p->paf_DVIChecksum,
- f->f_checksum);
- exit(1);
- }
- return; /* font already defined */
- }
- else {
- fprintf(stderr, "Can not stash font %ld (out of memory?)\n",
- p -> paf_DVIFontIndex);
- exit(1);
- }
- }
-
- if (NextFamilyNumber == MaxFontFamily) {
- fprintf(stderr,"Out of font family!\n");
- exit(1);
- }
-
- fi->family = NextFamilyNumber;
- NextFamilyNumber++;
-
- f = GetFont(p->paf_name, p->paf_DVIMag, p->paf_DVIDesignSize,
- dviPrintEngine, &fname);
-
-/*
- * Give the application a chance to bang on this if they want to.
- */
-
- f = applicationNewFont(f, fi -> family);
-
- if ((fi->f = f) == NULL) {
- GripeCannotGetFont(p->paf_name, p->paf_DVIMag,
- p->paf_DVIDesignSize, dviPrintEngine, fname);
- FontErrors++;
- return;
- }
-
- /* match checksums, if not zero */
- if (p->paf_DVIChecksum && f->f_checksum &&
- p->paf_DVIChecksum != f->f_checksum)
- GripeDifferentChecksums(fname, p->paf_DVIChecksum,
- f->f_checksum);
-
- fi->pspace = p->paf_DVIMag / 6; /* a three-unit "thin space" */
- fi->nspace = -4 * fi->pspace;
- fi->vspace = 5 * fi->pspace;
-}
-
-static void
-ReadPostAmble()
-{
-
- if (FontFinder == 0) {
- if ((FontFinder = SCreate(sizeof(struct fontinfo))) == 0) {
- fprintf(stderr, "can not create FontFinder (out of memory?)");
- exit(1);
- }
- }
-
- ScanPostAmble(dviFile, PostAmbleHeader, PostAmbleFontDef);
-
- if (FontErrors)
- GripeMissingFontsPreventOutput(FontErrors);
-}
-
-/*
- * Read the preamble and do a few sanity checks
- */
-
-static void
-ReadPreAmble()
-{
- register int n;
-
- rewind(dviFile);
- if (GetByte(dviFile) != Sign8(DVI_PRE))
- GripeMissingOp("PRE");
-
- if (GetByte(dviFile) != Sign8(DVI_VERSION))
- GripeMismatchedValue("version numbers");
-
- if (GetLong(dviFile) != Numerator)
- GripeMismatchedValue("numerator");
-
- if (GetLong(dviFile) != Denominator)
- GripeMismatchedValue("denominator");
-
- if (GetLong(dviFile) != Magnification)
- GripeMismatchedValue("\\magfactor");
-
- n = UnSign8(GetByte(dviFile));
- while (--n >= 0)
- (void) GetByte(dviFile);
-}
-
-int
-dviInit()
-{
- extern char *ProgName;
- FILE *tmpFile;
-#ifndef WIN32
- char *mktemp();
-#endif
-
- dviFini(); /* clean up the old files */
-
- if (DVIFileName == 0) {
- dviFile = stdin;
- DVIFileName = "<stdin>";
- }else if ((dviFile = fopen(DVIFileName, "r")) == NULL) {
- int n = strlen(DVIFileName);
- char *dvi_name;
-
- if (strcmp(DVIFileName + n - sizeof(".dvi") + 1, ".dvi") == 0) {
- perror(DVIFileName);
- return(1);
- }
-
- dvi_name = (char *) malloc((unsigned) n + sizeof(".dvi"));
- sprintf(dvi_name, "%s.dvi", DVIFileName);
-
- if ((dviFile = fopen(dvi_name, "r")) == NULL) {
- perror(dvi_name);
- return(1);
- }
- DVIFileName = dvi_name;
- }
-
-/*
- * node, copy the file to a temporary location. This lets the person
- * peruse the file while theyre re-texing it
- */
- strcpy(dviTmpFileNameBuffer,"/tmp/dvistuff.XXXXXX");
- dviTmpFileName = mktemp(dviTmpFileNameBuffer);
-
- if (!(tmpFile = fopen(dviTmpFileName,"w+"))) {
- perror("fopen");
- fprintf(stderr,"Unable to create temporary file");
- dviTmpFileName = 0;
- } else {
- char buffer[BUFSIZ];
- int b;
-
- rewind(dviFile);
- do {
- b = fread(buffer, 1, BUFSIZ, dviFile);
- fwrite(buffer, 1, b, tmpFile);
- } while (! feof(dviFile));
-
- fclose(dviFile);
- dviFile = tmpFile;
- rewind(dviFile);
- }
-/*
- * Unlink the temporary file. This keeps tmp files from cluddering
- * up /tmp and it does it in a very application-independent way.
- * You can't reopen the tmp file, but we don't really allow that
- * anyway (the tmp file is hidden from the user).
- */
- if (dviTmpFileName != 0 &&
- strncmp(dviTmpFileName,"/tmp/",5) == 0) {
- unlink(dviTmpFileName);
- }
-
- if (dviUserMag == -1) {
- dviUserMag = 1000;
- }
-
- if (dviMaxDrift == -1) {
- dviMaxDrift = DEFAULT_MAX_DRIFT;
- }
-
- if (dviDPI == -1) {
- dviDPI = DEFAULT_DPI;
- }
-
- if (dviBlackness == -1) {
- dviBlackness = DEFAULT_BLACKNESS;
- }
-
- if (dviFontRotation == -1) {
- dviFontRotation = ROT_NORM;
- }
-
- ReadPostAmble();
- ReadPreAmble();
-
- /* Margins -- needs work! */
-
- if (dviHHMargin == -1) {
- dviHHMargin = DEFAULT_HHMARGIN;
- }
-
- if (dviVVMargin == -1) {
- dviVVMargin = DEFAULT_VVMARGIN;
- }
-
- dviCurrentFont = &NoFont; /* fake font, all zeros */
-
- return(0);
-}
-
-void
-dviFini()
-{
- if (dviFile != 0) {
- fclose(dviFile);
- }
-
- if (dviTmpFileName != 0 &&
- strncmp(dviTmpFileName,"/tmp/",5) == 0) {
- unlink(dviTmpFileName);
- }
-}
-
-
-static void
-SelectFont(n)
-i32 n;
-{
- int x = S_LOOKUP;
-
- if ((dviCurrentFont = (struct fontinfo *)SSearch(FontFinder, n, &x)) == 0)
- GripeNoSuchFont(n);
-}
-
-/* Read the postamble. */
-
-static void
-doDviChar(c, advance)
-int c;
-int advance;
-{
- register struct glyph *g;
- register struct font *f;
- int p;
-
- f = dviCurrentFont->f;
-
- if (c < f -> f_lowch || c > f -> f_highch) {
- fprintf(stderr,"Character out of range: %d\n",
- c);
- return;
- }
-
- g = GLYPH(f, c);
- if (!GVALID(g)) {
- fprintf(stderr, "there is no character %d in %s",
- c, f->f_path);
- exit(1);
- } else {
-
- if (HASRASTER(g)) { /* workaround for Imagen bug */
- applicationPutChar(dviHH,dviVV,c);
- }
-
- if (advance) {
- dviHH += g->g_pixwidth;
- dvi_h += g->g_tfmwidth;
- p = fromSP(dvi_h);
- FIXDRIFT(dviHH, p);
- }
- }
-}
-
-/*
- * The next two routines are used to reset all the glyphs.
- * the dviResetFont routine is called for each font in the font table.
- * It de-allocates the rasters & glyphs for the shrunken fonts, leaving
- * the original glyph data untouched.
- */
-
-
-static void
-dviResetFont(fi, key)
-struct fontinfo *fi;
-int key;
-{
- if (fi != 0) {
- applicationResetFont(fi, fi -> family);
- }
-}
-
-void
-dviResetAll()
-{
- SEnumerate(FontFinder, dviResetFont);
-}
-
-/*
- * Process the DVI commands for page #page. If the page number is
- * out of range, it is cropped to the end.
- *
- * Updates dviCurrentPage
- */
-void
-dviPreparePage(page)
-int page;
-{
- register int c;
- register i32 p;
- int advance;
-
- if (page < 0) {
- page = 0;
- }
-
- if (page >= dviTotalPages) {
- page = dviTotalPages - 1;
- }
-
- dviCurrentPage = page;
-
- fseek(dviFile, (long) pageOffset[page], 0);
-
- dviHH = dviHHMargin;
- dviVV = dviVVMargin;
-
- dvi_h = toSP(dviHH);
- dvi_v = toSP(dviVV);
-
- dvi_w = 0;
- dvi_x = 0;
- dvi_y = 0;
- dvi_z = 0;
-
- dvi_stackp = dvi_stack;
-
- for(;;) {
-/*
- * Get the DVI byte, and switch on its parameter length and type.
- * Note that getchar() returns unsigned values.
- */
-
- if (feof(dviFile)) {
- fprintf(stderr,"Unexpected end-of-file\n");
- exit(1);
- }
-
- c = getc(dviFile);
-
- if (DVI_IsChar(c)) {
- advance = 1;
- doDviChar(c, advance);
- } else {
-
- switch (DVI_OpLen(c)) {
-
- case DPL_NONE:
- break;
-
- case DPL_SGN1:
- p = getc(dviFile);
- p = Sign8(p);
- break;
-
- case DPL_SGN2:
- fGetWord(dviFile, p);
- p = Sign16(p);
- break;
-
- case DPL_SGN3:
- fGet3Byte(dviFile, p);
- p = Sign24(p);
- break;
-
- case DPL_SGN4:
- fGetLong(dviFile, p);
- break;
-
- case DPL_UNS1:
- p = UnSign8(getc(dviFile));
- break;
-
- case DPL_UNS2:
- fGetWord(dviFile, p);
- p = UnSign16(p);
- break;
-
- case DPL_UNS3:
- fGet3Byte(dviFile, p);
- p = UnSign24(p);
- break;
-
- default:
- panic("DVI_OpLen(%d) = %d", c, DVI_OpLen(c));
- /* NOTREACHED */
- }
-
- switch (DVI_DT(c)) {
-
- case DT_SET:
- c = p;
- doDviChar(c, 1);
- break;
-
- case DT_PUT:
- c = p;
- doDviChar(c, 0);
- break;
-
- case DT_SETRULE:
- case DT_PUTRULE:
-
- {
- i32 h, w, rw;
-
- fGetLong(dviFile, h);
- fGetLong(dviFile, rw);
-
- h = ConvRule(h);
- w = ConvRule(rw);
-
- applicationSetRule(dviHH, dviVV, h,w);
-
- if (DVI_DT(c) == DT_SETRULE) {
- dviHH += w;
- dvi_h += rw;
- w = fromSP(dvi_h);
- FIXDRIFT(dviHH, w);
- }
- }
- break;
-
- case DT_NOP:
- break;
-
- case DT_BOP:
-/*
- * Each beginning of page has 11 4-byte words telling us things
- * about the page. We ignore them.
- */
- {
- fseek(dviFile, (long) (11 * 4), 1);
- }
-
- break;
-
- case DT_EOP:
- return;
-
- case DT_PUSH:
- dvi_stackp->stack_hh = dviHH;
- dvi_stackp->stack_vv = dviVV;
- dvi_stackp->stack_dvi = dvi_current;
- dvi_stackp++;
- break;
-
- case DT_POP:
- dvi_stackp--;
- dviHH = dvi_stackp->stack_hh;
- dviVV = dvi_stackp->stack_vv;
- dvi_current = dvi_stackp->stack_dvi;
- break;
-
- case DT_W0: /* there should be a way to make these pretty */
- p = dvi_w;
- goto move_right;
-
- case DT_W:
- dvi_w = p;
- goto move_right;
-
- case DT_X0:
- p = dvi_x;
- goto move_right;
-
- case DT_X:
- dvi_x = p;
- goto move_right;
-
- case DT_RIGHT:
- move_right:
- dvi_h += p;
-/*
- * DVItype tells us that we must round motions in this way:
- * `When the horizontal motion is small, like a kern, hh
- * changes by rounding the kern; but when the motion is
- * large, hh changes by rounding the true position so that
- * accumulated rounding errors disappear.
- */
- if (p >= dviCurrentFont->pspace || p <= dviCurrentFont->nspace)
- dviHH = fromSP(dvi_h);
- else {
- dviHH += fromSP(p);
- p = fromSP(dvi_h);
- FIXDRIFT(dviHH, p);
- }
- break;
-
- case DT_Y0:
- p = dvi_y;
- goto move_down;
-
- case DT_Y:
- dvi_y = p;
- goto move_down;
-
- case DT_Z0:
- p = dvi_z;
- goto move_down;
-
- case DT_Z:
- dvi_z = p;
- goto move_down;
-
- case DT_DOWN:
- move_down:
- dvi_v += p;
-/*
- * `Vertical motion is done similarly, but with the threshold
- * between ``small and ``large increased by a factor of
- * 5. The idea is to make fractions like $1\over2$ round
- * consistently, but to absorb accumulated rounding errors in
- * the baseline-skip moves.
- */
- if (ABS(p) >= dviCurrentFont->vspace)
- dviVV = fromSP(dvi_v);
- else {
- dviVV += fromSP(p);
- p = fromSP(dvi_v);
- FIXDRIFT(dviVV, p);
- }
- break;
-
- case DT_FNTNUM:
- SelectFont((i32) (c - DVI_FNTNUM0));
- break;
-
- case DT_FNT:
- SelectFont(p);
- break;
-
- case DT_XXX:
- {
- char specialBuffer [2048];
- register char *cp;
- int sweetp = 0;
-
- if (p > 2047) {
- sweetp = p - 2047;
- p = 2047;
- }
-
- for (cp = specialBuffer ; p > 0; p--) {
- *cp = getc(dviFile);
- cp++;
- }
- *(cp) = 0;
-
- while(sweetp > 0) {
- getc(dviFile);
- }
-
- applicationDoSpecial(specialBuffer);
- }
- break;
-
- case DT_FNTDEF:
- SkipFontDef(dviFile);
- break;
-
- case DT_PRE:
- GripeUnexpectedOp("PRE");
- /* NOTREACHED */
-
- case DT_POST:
- GripeUnexpectedOp("POST");
- /* NOTREACHED */
-
- case DT_POSTPOST:
- GripeUnexpectedOp("POSTPOST");
- /* NOTREACHED */
-
- case DT_UNDEF:
- GripeUndefinedOp(c);
- /* NOTREACHED */
-
- default:
- panic("DVI_DT(%d) = %d", c, DVI_DT(c));
- /* NOTREACHED */
- }
- }
- }
-}
-
-/* Transpose bytes in each pair of bytes (0123 -> 1032) */
-/* Reverse bits in a byte (01234567 -> 76543210) */
-/* needed for sun386i */
-/* Gerhard Fleischanderl & Wolfgang Nejdl */
-
-#ifdef sun386
-static unsigned char pow2[]={1,2,4,8,16,32,64,128};
-
-unsigned char reverseByte(oldByte)
- unsigned char oldByte;
-{
- unsigned short i;
- unsigned char newByte=0;
-
- /* build newByte with bits mirrored */
-
- for(i=0;i<8;i++)
- if (oldByte & pow2[i])
- newByte |= pow2[7-i];
-
- return newByte;
-}
-
-#ifdef UNDEF
-#define transposeBytesMirrorBits(pairPtr) \
-/* B16 *pairPtr; */ \
-/* B16 comprises 2 bytes */ \
-{ \
- unsigned char c0,c1, *bP = (unsigned char *) pairPtr; \
- \
- /* transpose neighbouring bytes and \
- reverse bits in each byte */ \
- \
- c0 = *bP; \
- c1 = *(bP+1); \
- *bP = ReverseByteTable[c1]; \
- *(bP+1) = ReverseByteTable[c0]; \
-}
-
-#else
-#define transposeBytesMirrorBits(ptr) {*ptr = ReverseByteTable[ (*ptr)&0xff ];}
-#endif /* undef */
-
-#endif
-
-
-/*
- * The following routine is used to shrink a glyph by some
- * shrink factor (in the width & height dimension).
- *
- * These shrunken glyphs are more appropriate for previewers.
- *
- * To do this, we simple scan the original raster, counting the
- * number of pixels within a given area. If the number of on pixels is
- * at least twice the total number of pixels, we turn the pixel in
- * the shrunken glyph ON, else OFF.
- *
- * We use a lookup table to hasten the process of counting pixels.
- *
- * The method used should be independent of byte-order (I think).
- *
- * You need to define two types. One should be 32-bits long, and
- * the other 16 bits long.
- */
-
-typedef unsigned char B8;
-typedef unsigned short B16;
-typedef unsigned long B32;
-
-#define LOOKUP_BYTES 256
-#define LOOKUP_BITS 8
-#define LOOKUP_MASK 0xff
-
-static char dviLookUpTable[LOOKUP_BYTES];
-static char tableNotInitialized = 1;
-
-#ifdef sun386
-static unsigned char ReverseByteTable[LOOKUP_BYTES];
-#endif
-
-struct glyph *
-dviShrinkGlyph(gly, shrinkH, shrinkW)
-DviGlyph *gly;
-int shrinkH;
-int shrinkW;
-{
- int shrunkHeight;
- int shrunkWidth;
- int glyphWide;
- int glyphHigh;
- int glyphAdvance;
- int shrunkAdvance;
-
- int bytesWide;
- int shrunkBytesWide;
-
- struct glyph *ngly;
-
- B16 *shrunkRaster;
- int rasterSize;
-
- int x,y;
- B8 *cp;
- B8 *ptr;
-
- B32 shrinkMask;
-
- int sampleSize;
-
- if (gly == 0 || !HASRASTER(gly)) {
- return(0);
- }
-
- if (gly -> g_raster == 0) {
- gly-> g_raster = RASTER(gly, dviCurrentFont -> f, dviFontRotation);
- }
-
-/*
- * Initialize the lookup table of the number of bits in a given byte
- */
-
- if (tableNotInitialized) {
- register int i;
- register int j;
- register int k;
- register int acc;
- for (i = 0; i < LOOKUP_BYTES; i++) {
- j = i;
- acc = 0;
- for (k = 0; j != 0 && k < LOOKUP_BITS ; k++) {
- acc += (j & 1);
- j >>= 1;
- }
- dviLookUpTable[i] = acc;
- }
-
-#ifdef sun386
- for (i = 0; i < LOOKUP_BYTES; i++) {
- ReverseByteTable[i] = reverseByte(i);
- }
-#endif
-
- tableNotInitialized = 0;
- }
-
-/*
- * When shrinking the fonts, we convert them from byte alligned
- * to 16 bit-aligned fonts. I think that this is needed by X,
- * and also SunWindows. This is done rather than changing the
- * library routines because some device drivers, i.e. imagen1,
- * depend on the byte-alligned fonts.
- */
- glyphHigh = gly -> g_height;
- glyphWide = gly -> g_width;
-
- gly -> g_pixwidth = fromSP(gly -> g_tfmwidth);
- glyphAdvance = gly -> g_pixwidth;
-
- shrunkHeight = (glyphHigh + shrinkH - 1) / shrinkH;
- shrunkWidth = (glyphWide + shrinkW - 1) / shrinkW;
- shrunkAdvance = (glyphAdvance + shrinkW - 1) / shrinkW;
-
- bytesWide = (gly -> g_width + 7) >> 3;
-
- shrunkBytesWide = ((shrunkWidth + 15) >> 4) * 2;
-
- rasterSize = (shrunkHeight + 1) * shrunkBytesWide;
- shrunkRaster = (B16 *) malloc(rasterSize);
- bzero(shrunkRaster, rasterSize);
- ptr = (B8 *) shrunkRaster;
-
- if (shrunkRaster == NULL) {
- fprintf(stderr, "Out of memory!\n");
- exit(1);
- }
-
- for (y = 0; y < glyphHigh; y+= shrinkH) {
- cp = (B8 *) ptr;
- shrinkMask = 0x80;
- for (x = 0; x < glyphWide; x += shrinkW) {
- int i;
- int samples;
- B8 *baseP;
- int upper;
- register int thisShrinkW;
-
- baseP = (B8 *) gly -> g_raster + (y * bytesWide);
-
-/*
- * Set the upper limit on the height iteration so we dont count
- * off the end of the raster
- */
-
- upper = y + shrinkH;
- if (upper > glyphHigh) {
- upper = glyphHigh;
- }
-
- if (x + shrinkW > glyphWide) {
- thisShrinkW = glyphWide - x;
- } else {
- thisShrinkW = shrinkW;
- }
-
- samples = 0;
- sampleSize = thisShrinkW * (upper - y);
-
- for (i = y; i < upper; i++) {
- register int acc;
- register B8 *p;
- register B8 *ep;
-/*
- * Determine how many bytes our shrink window crosses (we might
- * overlap on byte-edges)
- */
-
- p = baseP + (x >> 3);
- ep = baseP + ( (x + thisShrinkW - 1) >> 3);
- baseP += bytesWide;
-
-/*
- * stuff everything in the accumulator
- */
-
- acc = 0;
- while (p <= ep) {
- acc = ((acc << 8) & ~0xff) | *p;
- p++;
- }
-
-/*
- * clean off the right hand-side of extra bits, then clean off
- * the left hand side of extra bits, and then count them.
- */
-
- acc = acc >> ( 7 - ((x + thisShrinkW - 1) & 0x7));
- acc &= ~(-1 << thisShrinkW);
- while (acc != 0) {
- samples += dviLookUpTable[ acc & LOOKUP_MASK ];
- acc >>= LOOKUP_BITS;
- }
- }
-/*
- * If at least 1/blackness of the bits are on, treat this entire sample as
- * being on.
- */
-
- if ((samples * dviBlackness) >= sampleSize) {
- *ptr |= shrinkMask;
- } else {
- *ptr &= ~ shrinkMask;
- }
- shrinkMask >>= 1;
- if (shrinkMask == 0) {
- shrinkMask = 0x80;
-#ifdef sun386
- transposeBytesMirrorBits(ptr)
-#endif
- ptr ++;
- }
- }
-#ifdef sun386
- transposeBytesMirrorBits(ptr)
-#endif
- ptr = (B8 *) (cp + shrunkBytesWide);
- }
-
-/*
- * Build a new glyph from the shrunken raster
- */
-
-#ifdef UNDEF
- if ( shrunkBytesWide != 2 )
- {
- printf("Old glyph:\n");
- seeGlyph(gly -> g_raster, glyphHigh, bytesWide);
- printf("%d ", shrunkBytesWide);
- printf("New glyph:\n");
- seeGlyph(shrunkRaster, shrunkHeight, shrunkBytesWide);
- }
-#endif UNDEF
-
- ngly = (struct glyph *) malloc(sizeof(struct glyph));
- bzero(ngly, sizeof(struct glyph));
-
- ngly -> g_raster = (char * ) shrunkRaster;
- ngly -> g_width = shrunkWidth;
- ngly -> g_pixwidth = shrunkAdvance;
- ngly -> g_height = shrunkHeight;
-
- ngly -> g_xorigin = gly -> g_xorigin / shrinkH;
- ngly -> g_yorigin = gly -> g_yorigin / shrinkW;
-
- ngly -> g_flags |= GF_SHRUNK; /* yes, its been shrunk */
-
- return(ngly);
-}
-
-#ifdef UNDEF
-
-seeGlyph(c, h, w)
-char *c;
-int h;
-int w;
-{
- int i,j;
-
- for (i = 0; i < h; i++ ) {
- for (j = 0; j < w; j++) {
- int k;
- register int ch;
- register int m;
- char str[9];
-
- ch = *(c++);
- m = 0x80;
- for (k = 0; k < 8; k++) {
- str[k] = '"' + ( (ch & m) ? 1 : 0 );
- m >>= 1;
- }
- str[8] = 0;
- printf("%s", str);
- }
- printf("\n");
- }
-}
-
-
-#endif UNDEF