home *** CD-ROM | disk | FTP | other *** search
- Subject: v12i061: A PostScript interpreter, Part12/18
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rs@uunet.UU.NET
-
- Submitted-by: Crispin Goswell <caag@vd.rl.ac.uk>
- Posting-number: Volume 12, Issue 61
- Archive-name: postscript/part12
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 12 (of 18)."
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'source/X.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'source/X.c'\"
- else
- echo shar: Extracting \"'source/X.c'\" \(15122 characters\)
- sed "s/^X//" >'source/X.c' <<'END_OF_FILE'
- X/*
- X * Copyright (C) Rutherford Appleton Laboratory 1987
- X *
- X * This source may be copied, distributed, altered or used, but not sold for profit
- X * or incorporated into a product except under licence from the author.
- X * It is not in the public domain.
- X * This notice should remain in the source unaltered, and any changes to the source
- X * made by persons other than the author should be marked as such.
- X *
- X * Crispin Goswell @ Rutherford Appleton Laboratory caag@uk.ac.rl.vd
- X */
- X#include "X/Xlib.h"
- X
- X#include "main.h"
- X#include "graphics.h"
- X
- X#define TRANSFER_SIZE 256
- X#define XMAX 65535
- X
- Xstatic int transfer [TRANSFER_SIZE + 1];
- X
- Xstatic unsigned char reverse [0x100];
- X
- Xstruct hardware
- X {
- X Window win;
- X struct bitmap *bm;
- X int width, height;
- X };
- X
- Xstruct bitmap
- X {
- X short *data;
- X Bitmap xbm;
- X int width, height;
- X };
- X
- Xstruct hardcolour
- X {
- X int pixel;
- X Pixmap tile;
- X };
- X
- Xstruct screen
- X {
- X float val;
- X int sx, sy;
- X Pixmap shade;
- X } *screen = NULL;
- X
- Xstatic int screen_size, screen_side;
- X
- Xchar *malloc ();
- X
- Xstatic Display *theDisplay;
- Xstatic float magnification;
- X
- Xstatic void InitTransfer ();
- Xstatic struct hardcolour HardColour ();
- X
- Xstruct hardware *InitHardware ()
- X {
- X if ((theDisplay = XOpenDisplay ("")) == NULL)
- X {
- X fprintf (stderr, "Could not open display\n");
- X exit (1);
- X }
- X magnification = DisplayHeight () / (11.0 * 72);
- X XSetDisplay (theDisplay);
- X InitReversal ();
- X InitRopMap ();
- X InitTransfer ();
- X
- X return 0;
- X }
- X
- Xstatic struct hardware *NewHardware (win, bm, width, height) Window win; struct bitmap *bm; int width, height;
- X {
- X struct hardware *res = (struct hardware *) malloc (sizeof (struct hardware));
- X
- X res->win = win;
- X res->bm = bm;
- X res->width = width;
- X res->height = height;
- X
- X return res;
- X }
- X
- XSetClipHardware (bm, clip) struct hardware *bm, *clip;
- X {
- X }
- X
- Xint hard_size (width, height) int width, height;
- X {
- X return ((width + 15) / 16) * height;
- X }
- X
- Xstatic struct bitmap *NewBM (width, height) int width, height;
- X {
- X struct bitmap *res = (struct bitmap *) malloc (sizeof (struct bitmap));
- X
- X res->data = (short *) calloc (hard_size (width, height), sizeof (short));
- X res->width = width;
- X res->height = height;
- X res->xbm = 0;
- X
- X return res;
- X }
- X
- Xstatic void DestroyBM (bm) struct bitmap *bm;
- X {
- X free ((char *) bm->data);
- X if (bm->xbm != 0)
- X XFreeBitmap (bm->xbm);
- X free ((char *) bm);
- X }
- X
- Xstatic Bitmap NeedBitmap (bm) struct bitmap *bm;
- X {
- X if (bm->xbm == 0)
- X {
- X bm->xbm = XStoreBitmap (bm->width, bm->height, bm->data);
- X }
- X return bm->xbm;
- X }
- X
- Xstatic OODBitmap (bm) struct bitmap *bm;
- X {
- X if (bm->xbm != 0)
- X {
- X XFreeBitmap (bm->xbm);
- X bm->xbm = 0;
- X }
- X }
- X
- Xstruct hardware *NewWindowHardware (width, height) int width, height;
- X {
- X Window win = XCreateWindow (RootWindow, 0, 0, width, height, 1, BlackPixmap, WhitePixmap);
- X
- X if (win == 0)
- X return NULL;
- X XMapWindow (win);
- X
- X return NewHardware (win, NULL, width, height);
- X }
- X
- Xstruct hardware *NewBitmapHardware (width, height) int width, height;
- X {
- X return NewHardware (0, NewBM (width, height), width, height);
- X }
- X
- Xvoid DestroyHardware (h) struct hardware *h;
- X {
- X if (IsWindowHardware (h))
- X XDestroyWindow (h->win);
- X else
- X DestroyBM (h->bm);
- X free ((char *) h);
- X }
- X
- XMatrix DeviceMatrix (width, height) int width, height;
- X {
- X return NewMatrix (magnification, 0.0, 0.0, -magnification, 0.0, (float) height);
- X }
- X
- XDevicePoint HardwareExtent (h) struct hardware *h;
- X {
- X return h == NULL ? NewDevicePoint (0, 0) : NewDevicePoint (h->width, h->height);
- X }
- X
- Xint IsWindowHardware (h) struct hardware *h;
- X {
- X return h->win != 0;
- X }
- X
- Xstatic int single_rop [16];
- X
- Xstatic InitRopMap ()
- X {
- X single_rop [ROP_FALSE] = single_rop [ROP_NOTAND] = single_rop [ROP_NOR] = single_rop [ROP_NOTSOURCE] = ROP_FALSE;
- X single_rop [ROP_AND] = single_rop [ROP_DEST] = single_rop [ROP_NXOR] = single_rop [ROP_NOTOR] = ROP_DEST;
- X single_rop [ROP_ANDNOT] = single_rop [ROP_XOR] = single_rop [ROP_NOTDEST] = single_rop [ROP_NAND] = ROP_NOTDEST;
- X single_rop [ROP_SOURCE] = single_rop [ROP_OR] = single_rop [ROP_ORNOT] = single_rop [ROP_TRUE] = ROP_TRUE;
- X }
- X
- Xstatic int Xvalue (ax, ay, bx, by, cy) int ax, ay, bx, by, cy;
- X {
- X return bx + (cy - by) * (ax - bx) / (float) (ay - by);
- X }
- X
- Xstatic void PaintBlob (to, top, bottom, left, right, col)
- X struct hardware *to;
- X int top, bottom, *left, *right;
- X struct hardcolour col;
- X {
- X int i, op, offset = top;
- X
- X if (col.tile == 0)
- X for (i = top; i <= bottom; i++)
- X XPixSet (to->win, left[i - offset], i, right[i - offset] - left[i - offset] + 1, 1, col.pixel);
- X else
- X for (i = top; i <= bottom; i++)
- X XTileSet (to->win, left[i - offset], i, right[i - offset] - left[i - offset] + 1, 1, col.tile);
- X }
- X
- Xvoid PaintTrapezoid (to, lefttop, leftbottom, righttop, rightbottom, top, bottom, colour)
- X struct hardware *to;
- X DevicePoint lefttop, leftbottom, righttop, rightbottom;
- X int top, bottom;
- X Colour colour;
- X {
- X struct hardcolour col;
- X int i, j, temp; char c;
- X static int left [1024], right [1024];
- X
- X int ltx = Xvalue (lefttop.dx, lefttop.dy, leftbottom.dx, leftbottom.dy, top),
- X rtx = Xvalue (righttop.dx, righttop.dy, rightbottom.dx, rightbottom.dy, top),
- X lbx = Xvalue (lefttop.dx, lefttop.dy, leftbottom.dx, leftbottom.dy, bottom),
- X rbx = Xvalue (righttop.dx, righttop.dy, rightbottom.dx, rightbottom.dy, bottom);
- X
- X col = HardColour (colour);
- X
- X if (ltx == lbx && rtx == rbx)
- X {
- X if (rtx < ltx)
- X temp = rtx, rtx = ltx, ltx = temp;
- X
- X if (col.tile == 0)
- X XPixSet (to->win, ltx, top, rtx - ltx + 1, bottom - top + 1, col.pixel);
- X else
- X XTileSet (to->win, ltx, top, rtx - ltx + 1, bottom - top + 1, col.tile);
- X return;
- X }
- X
- X for (i = top, j = 0; i <= bottom; i++, j++)
- X {
- X int lx = Xvalue (lefttop.dx, lefttop.dy, leftbottom.dx, leftbottom.dy, i),
- X rx = Xvalue (righttop.dx, righttop.dy, rightbottom.dx,rightbottom.dy, i);
- X
- X if (rx < lx)
- X temp = rx, rx = lx, lx = temp;
- X
- X left [j] = lx; right [j] = rx;
- X }
- X PaintBlob (to, top, bottom, left, right, col);
- X }
- X
- Xstatic void RasterBlob (to, top, bottom, left, right, rop)
- X struct hardware *to;
- X int top, bottom, *left, *right, rop;
- X {
- X int i, op, offset = top;
- X
- X switch (rop)
- X {
- X case ROP_FALSE: op = GXclear; break;
- X case ROP_DEST: return;
- X case ROP_NOTDEST: op = GXinvert; break;
- X case ROP_TRUE: op = GXset; break;
- X }
- X for (i = top; i <= bottom; i++)
- X XCopyArea (to->win, 0, 0, left[i - offset], i, right[i - offset] - left[i - offset] + 1, 1, op, ~0);
- X }
- X
- Xstatic void RasterTrapezoid (to, lefttop, leftbottom, righttop, rightbottom, top, bottom, rop)
- X struct hardware *to;
- X DevicePoint lefttop, leftbottom, righttop, rightbottom;
- X int top, bottom, rop;
- X {
- X int i, j, temp; char c;
- X static int left [1024], right [1024];
- X
- X int ltx = Xvalue (lefttop.dx, lefttop.dy, leftbottom.dx, leftbottom.dy, top),
- X rtx = Xvalue (righttop.dx, righttop.dy, rightbottom.dx, rightbottom.dy, top),
- X lbx = Xvalue (lefttop.dx, lefttop.dy, leftbottom.dx, leftbottom.dy, bottom),
- X rbx = Xvalue (righttop.dx, righttop.dy, rightbottom.dx, rightbottom.dy, bottom);
- X
- X if (ltx == lbx && rtx == rbx)
- X {
- X int op;
- X
- X if (rtx < ltx)
- X temp = rtx, rtx = ltx, ltx = temp;
- X
- X switch (rop)
- X {
- X case ROP_FALSE: op = GXclear; break;
- X case ROP_DEST: return;
- X case ROP_NOTDEST: op = GXinvert; break;
- X case ROP_TRUE: op = GXset; break;
- X }
- X XCopyArea (to->win, 0, 0, ltx, top, rtx - ltx + 1, bottom - top + 1, op, ~0);
- X return;
- X }
- X
- X for (i = top, j = 0; i <= bottom; i++, j++)
- X {
- X int lx = Xvalue (lefttop.dx, lefttop.dy, leftbottom.dx, leftbottom.dy, i),
- X rx = Xvalue (righttop.dx, righttop.dy, rightbottom.dx,rightbottom.dy, i);
- X
- X if (rx < lx)
- X temp = rx, rx = lx, lx = temp;
- X
- X left [j] = lx; right [j] = rx;
- X }
- X RasterBlob (to, top, bottom, left, right, single_rop [rop]);
- X }
- X
- Xvoid Paint (from, to, fromPoint, toPoint, extent, colour)
- X struct hardware *from, *to;
- X DevicePoint fromPoint, toPoint, extent;
- X Colour colour;
- X {
- X if (to == NULL)
- X return;
- X if (from && IsWindowHardware (from))
- X {
- X fprintf (stderr, "driver for Paint cannot use Window as source\n");
- X exit (1);
- X }
- X if (IsWindowHardware (to))
- X {
- X struct hardcolour col;
- X
- X col = HardColour (colour);
- X if (col.tile == 0)
- X if (from == NULL)
- X XPixSet (to->win, toPoint.dx, toPoint.dy, extent.dx, extent.dy, col.pixel);
- X else
- X {
- X Pixmap pm = XMakePixmap (NeedBitmap (from->bm), AllPlanes, 0);
- X
- X XPixmapPut (to->win, fromPoint.dx, fromPoint.dy, toPoint.dx, toPoint.dy, extent.dx, extent.dy, pm, GXandInverted, AllPlanes);
- X XFreePixmap (pm);
- X pm = XMakePixmap (NeedBitmap (from->bm), col.pixel, 0);
- X
- X XPixmapPut (to->win, fromPoint.dx, fromPoint.dy, toPoint.dx, toPoint.dy, extent.dx, extent.dy, pm, GXor, AllPlanes);
- X XFreePixmap (pm);
- X }
- X else
- X if (from == NULL)
- X XTileSet (to->win, toPoint.dx, toPoint.dy, extent.dx, extent.dy, col.tile);
- X else
- X {
- X Pixmap pm = XMakePixmap (NeedBitmap (from->bm), BlackPixel, WhitePixel);
- X
- X XPixmapPut (to->win, fromPoint.dx, fromPoint.dy, toPoint.dx, toPoint.dy, extent.dx, extent.dy, pm, GXandInverted, AllPlanes);
- X XFreePixmap (pm);
- X }
- X }
- X else
- X {
- X fprintf (stderr, "driver for Paint cannot use Window as source\n");
- X exit (1);
- X }
- X }
- X
- Xvoid BitBlt (from, to, fromPoint, toPoint, extent, rop)
- X struct hardware *from, *to;
- X DevicePoint fromPoint, toPoint, extent;
- X int rop;
- X {
- X if (to == NULL)
- X return;
- X if (IsWindowHardware (to))
- X {
- X fprintf (stderr, "driver for BitBlt cannot use Window as Destination\n");
- X exit (1);
- X }
- X else
- X {
- X if (rop == ROP_SOURCE && fromPoint.dx == 0 && fromPoint.dy == 0 && toPoint.dx == 0 && toPoint.dy == 0)
- X {
- X DevicePoint exfrom, exto;
- X
- X exfrom = HardwareExtent (from); exto = HardwareExtent (to);
- X if (exfrom.dx == extent.dx && exfrom.dy == extent.dy && exto.dx == extent.dx && exto.dy == extent.dy)
- X {
- X Bcopy ((char *) (to->bm->data), (char *) (from->bm->data), sizeof (short) * hard_size (to->width, to->height));
- X OODBitmap (to->bm);
- X
- X return;
- X }
- X
- X }
- X }
- X fprintf (stderr, "driver for BitBlt can't cope with general case\n");
- X exit (1);
- X }
- X
- Xvoid PaintLine (h, fromPoint, toPoint, colour) struct hardware *h; DevicePoint fromPoint, toPoint; Colour colour;
- X {
- X struct hardcolour col;
- X
- X col = HardColour (colour);
- X
- X if (col.tile == screen[0].shade)
- X col.pixel = BlackPixel,
- X col.tile = 0;
- X else if (col.tile == screen[screen_size].shade)
- X col.pixel == WhitePixel,
- X col.tile = 0;
- X else
- X ;
- X if (!IsWindowHardware (h))
- X {
- X fprintf (stderr, "driver for PaintLine cannot cope with bitmaps\n");
- X return;
- X }
- X if (col.tile == 0)
- X XLine (h->win, fromPoint.dx, fromPoint.dy, toPoint.dx, toPoint.dy, 1, 1, col.pixel, GXcopy, AllPlanes);
- X else
- X {
- X fprintf (stderr, "driver for PaintLine cannot cope with textured lines\n");
- X XLine (h->win, fromPoint.dx, fromPoint.dy, toPoint.dx, toPoint.dy, 1, 1, col.pixel, GXcopy, AllPlanes);
- X }
- X }
- X
- Xvoid Line (h, fromPoint, toPoint, rop) struct hardware *h; DevicePoint fromPoint, toPoint; Colour rop;
- X {
- X }
- X
- Xstruct hardware *HardwareFromString (s, width, height) unsigned char *s; int width, height;
- X {
- X int words = (width + 15) / 16;
- X struct bitmap *BM = NewBM (width, height);
- X short *d = BM->data;
- X int odd = ((width + 7) / 8) & 1;
- X int i, j;
- X
- X for (i = 0; i < height; i++)
- X {
- X for (j = 0; j < words - odd; j++)
- X {
- X short word = reverse [*s++];
- X
- X *d++ = word | (reverse [*s++] << 8);
- X }
- X if (odd)
- X *d++ = reverse [*s++];
- X }
- X return NewHardware (0, BM, width, height);
- X }
- X
- Xchar *StringFromHardware (h) struct hardware *h;
- X {
- X int words = (h->width + 15) / 16;
- X char *string = malloc ((h->width + 7) / 8 * h->height), *s = string;
- X int i, j, odd = ((h->width + 7) / 8) & 1;
- X short *d = h->bm->data;
- X
- X for (i = 0; i < h->height; i++)
- X {
- X for (j = 0; j < words - odd; j++)
- X {
- X short word = *d++;
- X
- X *s++ = reverse [word & 0xFF];
- X *s++ = reverse [(word >> 8) & 0xFF];
- X }
- X if (odd)
- X *s++ = reverse [*d++ & 0xFF];
- X }
- X return string;
- X }
- X
- XInitReversal ()
- X {
- X int i, j;
- X
- X for (i = 0; i < 0x100; i++)
- X {
- X unsigned char r = 0;
- X
- X for (j = 0; j < 8; j++)
- X r |= (1 & (i >> j)) << (7 - j);
- X reverse [i] = r;
- X }
- X }
- X
- Xvoid HardUpdate ()
- X {
- X XFlush ();
- X }
- X
- Xstatic struct hardcolour HardColour (colour) Colour colour;
- X {
- X struct hardcolour res;
- X int col;
- X
- X if (DisplayPlanes () != 1)
- X {
- X Color def;
- X float r, g, b;
- X
- X ColourRGB (colour, &r, &g, &b);
- X def.red = XMAX * r;
- X def.green = XMAX * g;
- X def.blue = XMAX * b;
- X
- X XGetHardwareColor (&def);
- X
- X res.tile = 0;
- X res.pixel = def.pixel;
- X
- X return res;
- X }
- X
- X col = transfer [(int) (TRANSFER_SIZE * colour.brightness + .5)];
- X
- X res.tile = screen[(int) (col * (float) screen_size / TRANSFER_SIZE + 0.5)].shade;
- X
- X return res;
- X }
- X
- Xstatic void InitTransfer ()
- X {
- X int i;
- X
- X for (i = 0; i <= TRANSFER_SIZE; i++)
- X transfer [i] = i;
- X }
- X
- Xint TransferSize ()
- X {
- X return TRANSFER_SIZE;
- X }
- X
- Xvoid SetTransfer (tran) float *tran;
- X {
- X int i;
- X
- X for (i = 0; i < TRANSFER_SIZE; i++)
- X transfer [i] = (TRANSFER_SIZE - 1) * tran[i] + .5;
- X }
- X
- Xint ScreenSize (freq, rot) float freq, rot;
- X {
- X int size = magnification * 72 / freq + 0.5;
- X
- X return size * size;
- X }
- X
- Xvoid BuildScreen (freq, rotation, x, y) float freq, rotation, *x, *y;
- X {
- X int size = magnification * 72 / freq + 0.5;
- X int i, j;
- X
- X for (i = 0; i < size; i++)
- X for (j = 0; j < size; j++)
- X *x++ = (2 * i - size + 1) / (float) size,
- X *y++ = (2 * j - size + 1) / (float) size;
- X }
- X
- Xstatic sgn (a) float a;
- X {
- X if (a == 0)
- X return 0;
- X else if (a < 0)
- X return -1;
- X else
- X return 1;
- X }
- X
- Xstatic int screen_cmp (a, b) char *a, *b;
- X {
- X struct screen *aa = (struct screen *) a, *bb = (struct screen *) b;
- X
- X return sgn (aa->val - bb->val);
- X }
- X
- Xvoid SetScreen (freq, rotation, thresh) float freq, rotation, *thresh;
- X {
- X struct bitmap *temp;
- X int i, j, size = magnification * 72 / freq + 0.5;
- X struct screen *p;
- X
- X if (screen)
- X {
- X for (i = 0; i < screen_size; i++)
- X XFreePixmap (screen [i].shade);
- X free ((char *) screen);
- X }
- X p = screen = (struct screen *) malloc (((screen_size = size * size) + 1) * sizeof (struct screen));
- X screen_side = size;
- X for (i = 0; i < size; i++)
- X for (j = 0; j < size; j++)
- X {
- X p->val = *thresh++;
- X p->sx = i;
- X p->sy = j;
- X ++p;
- X }
- X qsort ((char *) screen, (unsigned) screen_size, sizeof (struct screen), screen_cmp);
- X
- X temp = NewBM (size, size);
- X
- X for (i = 0; i < screen_size; i++)
- X {
- X screen [i].shade = XMakePixmap (NeedBitmap (temp), WhitePixel, BlackPixel);
- X SetBit (temp, screen[i].sx, screen[i].sy);
- X OODBitmap (temp);
- X }
- X screen[screen_size].shade = XMakePixmap (NeedBitmap (temp), WhitePixel, BlackPixel);
- X OODBitmap (temp);
- X }
- X
- XSetBit (bm, x, y) struct bitmap *bm; int x, y;
- X {
- X int words = ((bm->width + 15) / 16);
- X
- X OODBitmap (bm);
- X bm->data[y * words + (x >> 4)] |= 1 << (x & 0xF);
- X }
- X
- XUpdateControl (h, i) struct hardware *h; int i;
- X {
- X }
- END_OF_FILE
- if test 15122 -ne `wc -c <'source/X.c'`; then
- echo shar: \"'source/X.c'\" unpacked with wrong size!
- fi
- # end of 'source/X.c'
- fi
- if test -f 'source/cache.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'source/cache.c'\"
- else
- echo shar: Extracting \"'source/cache.c'\" \(14908 characters\)
- sed "s/^X//" >'source/cache.c' <<'END_OF_FILE'
- X/*
- X * Copyright (C) Rutherford Appleton Laboratory 1987
- X *
- X * This source may be copied, distributed, altered or used, but not sold for profit
- X * or incorporated into a product except under licence from the author.
- X * It is not in the public domain.
- X * This notice should remain in the source unaltered, and any changes to the source
- X * made by persons other than the author should be marked as such.
- X *
- X * Crispin Goswell @ Rutherford Appleton Laboratory caag@uk.ac.rl.vd
- X */
- X#include "main.h"
- X#include "graphics.h"
- X
- Xstatic struct cache
- X {
- X struct cache *cache_next, *cache_prev;
- X int fid;
- X Matrix mat; /* character -> device */
- X int width, height, swidth, sheight; /* device coords */
- X } cache_header = { &cache_header, &cache_header },
- X *cache_ring = &cache_header;
- X
- Xstatic struct char_table {
- X Object char_key;
- X struct cache *char_cache;
- X
- X struct device *char_device;
- X Point char_width; /* character coords */
- X} *CharTable;
- X
- Xstatic int bsize = 0, bmax = 0;
- Xstatic int msize = 0, mmax = 0;
- Xstatic int csize = 0, cmax = 0;
- X
- Xstatic int maxbits = 0;
- X
- Xstatic int CacheStatus ();
- Xstatic int PSetCharWidth ();
- Xstatic int SetCacheLimit ();
- Xstatic int PCurrentCharWidth ();
- Xstatic int PSetCacheDevice ();
- Xstatic int SetCache ();
- Xstatic int SaveCurrentFont ();
- X
- Xint SetCacheDevice ();
- Xstatic struct cache *NewCache (), *CacheRemove ();
- X
- XInitCache ()
- X {
- X InstallOp ("cachestatus", CacheStatus, 0, 7, 0, 0);
- X InstallOp ("setcachedevice", PSetCacheDevice, 6, 0, 0, 0, Float, Float, Float, Float, Float, Float);
- X InstallOp ("setcharwidth", PSetCharWidth, 2, 0, 0, 0, Float, Float);
- X InstallOp (".currentcharwidth", PCurrentCharWidth, 0, 2, 0, 0);
- X InstallOp ("setcachelimit", SetCacheLimit, 1, 0, 0, 0, Integer);
- X InstallOp ("setcache", SetCache, 3, 0, 0, 0, Integer, Integer, Integer);
- X InstallOp ("savecurrentfont", SaveCurrentFont, 0, 0, 0, 0);
- X }
- X
- Xstatic InitCharTable ()
- X {
- X int i;
- X
- X CharTable = (struct char_table *) Malloc ((unsigned) (sizeof (struct char_table) * cmax));
- X for (i = 0; i < cmax; i++)
- X CharTable[i].char_cache = NULL;
- X }
- X
- Xstatic struct char_table *CharAddition (table, cache, key, size)
- X struct char_table *table;
- X struct cache *cache;
- X Object key;
- X int size;
- X {
- X int i, h = (BodyInteger (key) + (int) cache) % size;
- X
- X for (i = h;;)
- X {
- X if (table[i].char_cache == NULL)
- X {
- X table[i].char_key = key;
- X table[i].char_cache = cache;
- X
- X return &table[i];
- X }
- X if (++i == size)
- X i = 0;
- X if (i == h)
- X return NULL;
- X }
- X }
- X
- XCharStore (key, width, dev) Object key; Point width; struct device *dev;
- X {
- X struct char_table *p;
- X
- X while (csize == cmax)
- X DestroyCache (CacheRemove (cache_ring->cache_prev));
- X
- X if (p = CharAddition (CharTable, gstate->show->ccache, key, cmax))
- X {
- X p->char_width = width;
- X p->char_device = dev;
- X ++csize;
- X }
- X else
- X Panic ("dictionary full in CharStore");
- X }
- X
- Xstatic struct char_table *CharFind (table, cache, key, size)
- X struct char_table *table;
- X struct cache *cache;
- X Object key;
- X int size;
- X {
- X int i, h = (BodyInteger (key) + (int) cache) % size;
- X
- X for (i = h;;)
- X {
- X/* if (table[i].char_cache == NULL)
- X return NULL;
- X*/ if (table[i].char_cache == cache && Equal (key, table[i].char_key))
- X return &table[i];
- X if (++i == size)
- X i = 0;
- X if (i == h)
- X break;
- X }
- X return NULL;
- X }
- X
- Xstatic struct char_table *CharLoad (key) Object key;
- X {
- X return CharFind (CharTable, gstate->show->ccache, key, cmax);
- X }
- X
- Xstatic FlushChars (p) struct cache *p;
- X {
- X int i;
- X
- X for (i = 0; i < cmax; i++)
- X if (CharTable[i].char_cache == p)
- X {
- X CharTable[i].char_cache = NULL;
- X --csize;
- X }
- X }
- X
- X/* convert bounding box to equivalent one in device coordinates */
- XDeviceBBox (left, right, top, bottom, llx, urx, ury, lly) float *left, *right, *top, *bottom, llx, urx, ury, lly;
- X {
- X HardPoint ll;
- X
- X ll = ExtToInt (NewPoint (llx, lly));
- X
- X *left = *right = ll.hx; *top = *bottom = ll.hy;
- X
- X Bound (left, right, top, bottom, ExtToInt (NewPoint (urx, lly)));
- X Bound (left, right, top, bottom, ExtToInt (NewPoint (llx, ury)));
- X Bound (left, right, top, bottom, ExtToInt (NewPoint (urx, ury)));
- X }
- X
- Xint EqVector (a, b) Vector a, b;
- X {
- X return (int) a.vx == (int) b.vx && (int) a.vy == (int) b.vy;
- X }
- X
- Xstatic int PCurrentCharWidth ()
- X {
- X VOID Push (OpStack, MakeReal (gstate->show->Width.x));
- X VOID Push (OpStack, MakeReal (gstate->show->Width.y));
- X return TRUE;
- X }
- X
- Xstatic int PSetCharWidth (wx, wy) Object wx, wy;
- X {
- X if (!gstate->show->InShow)
- X return Error (PUndefined);
- X SetCharWidth (NewPoint (BodyReal (wx), BodyReal (wy)));
- X return TRUE;
- X }
- X
- XSetCharWidth (width) Point width;
- X {
- X gstate->show->Width = width;
- X }
- X
- Xstatic int PSetCacheDevice (wx, wy, llx, lly, urx, ury) Object wx, wy, llx, lly, urx, ury;
- X {
- X if (!gstate->show->InShow)
- X return Error (PUndefined);
- X return SetCacheDevice (gstate->show->CharName,
- X NewPoint (BodyReal (wx), BodyReal (wy)),
- X BodyReal (llx), BodyReal (lly),
- X BodyReal (urx), BodyReal (ury));
- X }
- X
- Xstatic int CharTooBig (width, height) float width, height;
- X {
- X return width * height > maxbits * 8;
- X }
- X
- Xint SetCacheDevice (name, char_width, llx, lly, urx, ury)
- X Object name; Point char_width; float llx, lly, urx, ury;
- X {
- X float left, right, top, bottom, width, height;
- X struct device *new_char;
- X struct cache *ccache = gstate->show->ccache;
- X
- X SetCharWidth (char_width);
- X if (!ccache)
- X return TRUE;
- X DeviceBBox (&left, &right, &top, &bottom, llx, urx, ury, lly);
- X width = right - left; height = top - bottom;
- X
- X if (CharTooBig (width, height))
- X return TRUE;
- X
- X new_char = NewCacheDevice (ccache->mat, ccache->width, ccache->height, ccache->swidth, ccache->sheight);
- X CharStore (name, char_width, LinkDevice (new_char));
- X SetDevice (new_char);
- X
- X PathFree (gstate->clip);
- X gstate->clip = NewClipPath (0.0, width, height, 0.0);
- X gstate->CTM.tx = ccache->swidth;
- X gstate->CTM.ty = ccache->sheight;
- X VOID MoveTo (gstate->path, ExtToInt (NewPoint (0.0, 0.0)));
- X
- X return TRUE;
- X }
- X
- XprintMatrix (m) Matrix m;
- X {
- X printf ("[%g %g]\n", m.A, m.B);
- X printf ("[%g %g]\n", m.C, m.D);
- X printf ("[%g %g]\n", m.tx, m.ty);
- X }
- X
- X#ifdef notdef
- Xint EqFont (m, n, bbox) Matrix m, n; float *bbox;
- X {
- X Vector morigin, norigin, mright, nright, mbottom, nbottom;
- X
- X morigin = Transform (NewVector (bbox [BBOX_LEFT], bbox [BBOX_TOP], 1.0), m);
- X norigin = Transform (NewVector (bbox [BBOX_LEFT], bbox [BBOX_TOP], 1.0), n);
- X mright = DiffVector (Transform (NewVector (bbox [BBOX_RIGHT], bbox [BBOX_TOP], 1.0), m), morigin);
- X nright = DiffVector (Transform (NewVector (bbox [BBOX_RIGHT], bbox [BBOX_TOP], 1.0), n), norigin);
- X mbottom = DiffVector (Transform (NewVector (bbox [BBOX_LEFT], bbox [BBOX_BOTTOM], 1.0), m), morigin);
- X nbottom = DiffVector (Transform (NewVector (bbox [BBOX_LEFT], bbox [BBOX_BOTTOM], 1.0), n), norigin);
- X
- X return EqVector (mbottom, nbottom) && EqVector (mright, nright);
- X }
- X#endif
- X
- Xint EqFont (m, n) Matrix m, n;
- X {
- X return m.A == n.A && m.B == n.B && m.C == n.C && m.D == n.D;
- X }
- X
- Xextern float fontbboxCache[];
- Xextern int fidCache;
- X
- Xstruct cache *SearchCache (m, fid) Matrix m; int fid;
- X {
- X struct cache *p;
- X
- X for (p = cache_ring->cache_next; p != cache_ring; p = p->cache_next)
- X if (p->fid == fid && EqFont (m, p->mat))
- X {
- X if (cache_ring->cache_next != p)
- X CacheInsert (cache_ring->cache_next, CacheRemove (p));
- X return cache_ring->cache_next;
- X }
- X
- X return NULL;
- X }
- X
- Xint FindCache ()
- X {
- X HardPoint origin;
- X float left, right, top, bottom;
- X int width, height, swidth, sheight;
- X
- X if ((gstate->show->ccache = SearchCache (gstate->CTM, fidCache)) != NULL)
- X return TRUE;
- X Message ("building a new cache");
- X DeviceBBox (&left, &right, &top, &bottom,
- X fontbboxCache[BBOX_LEFT], fontbboxCache[BBOX_RIGHT], fontbboxCache[BBOX_BOTTOM], fontbboxCache[BBOX_TOP]);
- X
- X width = right - left; height = top - bottom;
- X if (CharTooBig ((float) width, (float) height))
- X {
- X Message ("character too big to cache");
- X return TRUE;
- X }
- X
- X if (msize == mmax)
- X DestroyCache (CacheRemove (cache_ring->cache_prev));
- X
- X origin = ExtToInt (NewPoint (0.0, 0.0));
- X swidth = origin.hx - left; sheight = origin.hy - bottom;
- X
- X CacheInsert (cache_ring->cache_next,
- X NewCache (fidCache,
- X gstate->CTM,
- X width, height,
- X swidth, sheight));
- X gstate->show->ccache = cache_ring->cache_next;
- X
- X LoadDiskCache (gstate->CTM, fontbboxCache);
- X
- X return TRUE;
- X }
- X
- Xint CacheShow (name, cp) Object name; HardPoint cp;
- X {
- X struct char_table *b;
- X struct cache *ccache = gstate->show->ccache;
- X DevicePoint from, to, extent;
- X
- X if (!ccache)
- X return FALSE;
- X gstate->show->CharName = name;
- X if ((b = CharLoad (name)) == NULL)
- X return FALSE;
- X /* SetCharWidth (b->char_width); */
- X gstate->show->Width = b->char_width;
- X
- X from.dx = from.dy = 0;
- X to.dx = cp.hx - ccache->swidth;
- X to.dy = cp.hy - ccache->sheight;
- X extent.dx = ccache->width; extent.dy = ccache->height;
- X
- X Paint (b->char_device->dev, gstate->device->dev, from, to, extent, gstate->colour);
- X
- X return TRUE;
- X }
- X
- Xstatic struct cache *NewCache (fid, m, width, height, swidth, sheight)
- X int fid; Matrix m; int width, height, swidth, sheight;
- X {
- X struct cache *res = (struct cache *) Malloc (sizeof (struct cache));
- X
- X m.tx = m.ty = 0.0;
- X res->fid = fid;
- X res->mat = m;
- X res->width = width;
- X res->height = height;
- X res->swidth = swidth;
- X res->sheight = sheight;
- X
- X return res;
- X }
- X
- Xstatic DestroyCache (p) struct cache *p;
- X {
- X FlushChars (p);
- X Free ((char *) p);
- X }
- X
- Xstatic CacheInsert (where, cache) struct cache *where, *cache;
- X {
- X cache->cache_next = where; cache->cache_prev = where->cache_prev;
- X where->cache_prev->cache_next = cache;
- X where->cache_prev = cache;
- X ++msize;
- X }
- X
- Xstatic struct cache *CacheRemove (item) struct cache *item;
- X {
- X item->cache_prev->cache_next = item->cache_next;
- X item->cache_next->cache_prev = item->cache_prev;
- X --msize;
- X
- X return item;
- X }
- X
- Xstatic int SetCacheLimit (mb) Object mb;
- X {
- X int b = BodyInteger (mb);
- X if (b < 0)
- X return Error (PRangeCheck);
- X maxbits = b;
- X return TRUE;
- X }
- X
- Xstatic int SetCache (bitmap, fonts, chars) Object bitmap, fonts, chars;
- X {
- X int b = BodyInteger (bitmap);
- X int f = BodyInteger (fonts);
- X int c = BodyInteger (chars);
- X
- X if (b < 0 || f < 0 || c < 0)
- X return Error (PRangeCheck);
- X bmax = b; mmax = f; cmax = c;
- X InitCharTable ();
- X return TRUE;
- X }
- X
- Xstatic int CacheStatus ()
- X {
- X VOID Push (OpStack, MakeInteger (bsize));
- X VOID Push (OpStack, MakeInteger (bmax));
- X VOID Push (OpStack, MakeInteger (msize));
- X VOID Push (OpStack, MakeInteger (mmax));
- X VOID Push (OpStack, MakeInteger (csize));
- X VOID Push (OpStack, MakeInteger (cmax));
- X VOID Push (OpStack, MakeInteger (maxbits));
- X
- X return TRUE;
- X}
- X
- XLoadDiskCache (m, bbox) Matrix m; float *bbox;
- X {
- X Object font_name;
- X FILE *fp;
- X Vector origin, right, bottom;
- X char disk_name [BUFSIZE], *bits, mess[BUFSIZ];
- X/* struct hardware *screen = gstate->device->dev; */
- X
- X Message ("Attempting to find a cache on disk");
- X font_name = DictLoad (gstate->font, FontName);
- X if (TypeOf (font_name) != Name)
- X return;
- X origin = Transform (NewVector (bbox [BBOX_LEFT], bbox [BBOX_TOP], 1.0), m);
- X right = DiffVector (Transform (NewVector (bbox [BBOX_RIGHT], bbox [BBOX_TOP], 1.0), m), origin);
- X bottom = DiffVector (Transform (NewVector (bbox [BBOX_LEFT], bbox [BBOX_BOTTOM], 1.0), m), origin);
- X VOID sprintf (disk_name,
- X "%s/cache/%.*s/%3d%3d%3d%3d",
- X library,
- X lengthName (font_name), BodyName (font_name),
- X (int) right.vx, (int) right.vy, (int) bottom.vx, (int) bottom.vy);
- X Message (disk_name);
- X if ((fp = fopen (disk_name, "r")) == NULL)
- X return;
- X Message ("found a disk cache");
- X VOID GSave ();
- X bits = Malloc ((unsigned) maxbits);
- X
- X sprintf (mess, "width = %d, height = %d\n", gstate->show->ccache->width, gstate->show->ccache->height);
- X Message (mess);
- X sprintf (mess, "computed length = %d", gstate->show->ccache->height * ((gstate->show->ccache->width + 7) / 8));
- X Message (mess);
- X
- X while (!feof (fp))
- X {
- X char char_name [BUFSIZE];
- X struct hardware *newdev;
- X int width, height, length;
- X
- X if (fscanf (fp, "%s %d %d %d\n",
- X char_name,
- X &width, &height,
- X &length) == EOF)
- X break;
- X VOID fread (bits, (unsigned) length, 1, fp);
- X VOID getc (fp);
- X newdev = HardwareFromString (bits, gstate->show->ccache->width, gstate->show->ccache->height);
- X /* VOID BitBlt (newdev, screen,
- X NewDevicePoint (0, 0), NewDevicePoint (200, 200),
- X NewDevicePoint (gstate->show->ccache->width, gstate->show->ccache->height),
- X ROP_SOURCE);
- X*/
- X VOID SetCacheDevice (NameFrom (char_name),
- X NewPoint ((float) width, (float) height),
- X bbox [BBOX_LEFT], bbox [BBOX_TOP],
- X bbox [BBOX_RIGHT], bbox [BBOX_BOTTOM]);
- X
- X VOID BitBlt (newdev, gstate->device->dev,
- X NewDevicePoint (0, 0), NewDevicePoint (0, 0),
- X NewDevicePoint (gstate->show->ccache->width, gstate->show->ccache->height),
- X ROP_SOURCE);
- X DestroyHardware (newdev);
- X }
- X Free (bits);
- X VOID GRestore ();
- X VOID fclose (fp);
- X Message ("load completed");
- X }
- X
- Xstatic int SaveCurrentFont ()
- X {
- X Matrix fm, m;
- X Vector origin, right, bottom;
- X Object font_name;
- X FILE *fp;
- X char disk_name [BUFSIZE];
- X int i;
- X float bbox[4];
- X struct cache *ccache;
- X
- X ExtractMatrix (&fm, DictLoad (gstate->font, FontMatrix));
- X m = MatMult (fm, gstate->CTM);
- X ExtractBBox (bbox, DictLoad (gstate->font, FontBBox));
- X font_name = DictLoad (gstate->font, FontName);
- X
- X origin = Transform (NewVector (bbox [BBOX_LEFT], bbox [BBOX_TOP], 1.0), m);
- X right = DiffVector (Transform (NewVector (bbox [BBOX_RIGHT], bbox [BBOX_TOP], 1.0), m), origin);
- X bottom = DiffVector (Transform (NewVector (bbox [BBOX_LEFT], bbox [BBOX_BOTTOM], 1.0), m), origin);
- X
- X if ((ccache = SearchCache (m, BodyFontID (DictLoad (gstate->font, Fid)))) == NULL)
- X return Error (PInvFont);
- X
- X Message (disk_name);
- X VOID sprintf (disk_name,
- X "%s/cache/%.*s/%3d%3d%3d%3d",
- X library,
- X lengthName (font_name), BodyName (font_name),
- X (int) right.vx, (int) right.vy, (int) bottom.vx, (int) bottom.vy);
- X
- X if ((fp = fopen (disk_name, "w")) == NULL)
- X return Error (PInvFileAccess);
- X
- X for (i = 0; i < cmax; i++)
- X if (CharTable[i].char_cache == ccache)
- X {
- X Object char_name;
- X char *bits;
- X DevicePoint extent;
- X int length;
- X
- X char_name = CharTable[i].char_key;
- X extent = HardwareExtent (CharTable[i].char_device->dev);
- X length = (extent.dx + 7) / 8 * extent.dy;
- X bits = StringFromHardware (CharTable[i].char_device->dev);
- X VOID fprintf (fp,
- X "%.*s %d %d %d\n",
- X lengthName (char_name), BodyName (char_name),
- X (int) CharTable [i].char_width.x,
- X (int) CharTable [i].char_width.y,
- X length);
- X VOID fwrite (bits, (unsigned) length, 1, fp);
- X putc ('\n', fp);
- X/* Free (bits);*/
- X
- X }
- X
- X VOID fclose (fp);
- X
- X return TRUE;
- X }
- END_OF_FILE
- if test 14908 -ne `wc -c <'source/cache.c'`; then
- echo shar: \"'source/cache.c'\" unpacked with wrong size!
- fi
- # end of 'source/cache.c'
- fi
- if test -f 'source/fill.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'source/fill.c'\"
- else
- echo shar: Extracting \"'source/fill.c'\" \(14650 characters\)
- sed "s/^X//" >'source/fill.c' <<'END_OF_FILE'
- X/*
- X * Copyright (C) Rutherford Appleton Laboratory 1987
- X *
- X * This source may be copied, distributed, altered or used, but not sold for profit
- X * or incorporated into a product except under licence from the author.
- X * It is not in the public domain.
- X * This notice should remain in the source unaltered, and any changes to the source
- X * made by persons other than the author should be marked as such.
- X *
- X * Crispin Goswell @ Rutherford Appleton Laboratory caag@uk.ac.rl.vd
- X */
- X#include "main.h"
- X#include "graphics.h"
- X
- X#define MAXPATHELEMENTS 15000
- X
- X/*
- X * Trapezoid decomposition algorithm:
- X *
- X * Edges are characterised by a line description, with topY, bottomY, topX, bottomX, startingY
- X * Build edge lists from path.
- X * Sort edges on top Y value.
- X * find topmost interestingY value, which will be the minimum topY. This becomes interestingY.
- X * loop
- X * examine edge list from here to end. Move edges with topY value less than interestingY into
- X * interesting edge set, computing intersections for each as you go. This should establish next
- X * interestingY value, nextY.
- X * form the pairings for all edges in the interesting set, according to the fill rule at interestingY.
- X * to do this, while inside, keep a pointer to the last up-transition edge, and pair it with the
- X * next down-transition edge.
- X * for any edges which have changed pairing, emit a trapezoid from their startingY to interestingY,
- X * (if they were paired) and set their startingY to interestingY
- X * break if (ninteresting == 0 && nedges_left == 0)
- X * interestingY := nextY
- X * pool
- X */
- X
- Xstatic struct edge
- X {
- X int topX, topY, bottomX, bottomY; short dir;
- X struct edge *pair;
- X int startingY, where, up, clip;
- X int name;
- X };
- X
- Xint names = 0;
- X
- Xextern int in_stroke;
- X
- Xint InitClip ();
- Xstatic int Clip ();
- Xstatic int EOClip ();
- Xint Fill ();
- Xstatic int EOFill ();
- Xstatic int PClipPath ();
- X
- XInitFill ()
- X {
- X InstallOp ("initclip", InitClip, 0, 0, 0, 0);
- X InstallOp ("clip", Clip, 0, 0, 0, 0);
- X InstallOp ("eoclip", EOClip, 0, 0, 0, 0);
- X InstallOp ("fill", Fill, 0, 0, 0, 0);
- X InstallOp ("eofill", EOFill, 0, 0, 0, 0);
- X InstallOp ("clippath", PClipPath, 0, 0, 0, 0);
- X }
- X
- Xstatic struct hardware *output_device;
- Xstatic Colour output_colour;
- X
- Xstatic int FillIt ();
- Xstatic int EoRule (), NwRule ();
- X
- Xstatic void EmitTrapezoid (left, right, top, bottom) struct edge *left, *right; int top, bottom;
- X {
- X struct edge *temp;
- X
- X if (left->topX > right->topX || left->bottomX > right->bottomX)
- X temp = left, left = right, right = temp;
- X PaintTrapezoid (output_device,
- X NewDevicePoint (left->topX, left->topY),
- X NewDevicePoint (left->bottomX, left->bottomY),
- X NewDevicePoint (right->topX, right->topY),
- X NewDevicePoint (right->bottomX, right->bottomY),
- X top, bottom,
- X output_colour);
- X }
- X
- Xint Fill ()
- X {
- X int res;
- X
- X if (gstate->device->dev == NULL)
- X return PNewPath ();
- X
- X output_device = gstate->device->dev;
- X output_colour = gstate->colour;
- X res = FillIt (gstate->path, NwRule, gstate->clip, NwRule, EmitTrapezoid);
- X /* XXX needs optimising */
- X
- X VOID PNewPath ();
- X
- X return res;
- X }
- X
- Xstatic int EOFill ()
- X {
- X int res;
- X
- X if (gstate->device->dev == NULL)
- X return PNewPath ();
- X
- X output_device = gstate->device->dev;
- X output_colour = gstate->colour;
- X res = FillIt (gstate->path, EoRule, gstate->clip, NwRule, EmitTrapezoid);
- X /* XXX needs optimising */
- X
- X VOID PNewPath ();
- X
- X return res;
- X }
- X
- Xstatic Path output_path;
- X
- Xstatic void PathTrapezoid (left, right, top, bottom) struct edge *left, *right; int top, bottom;
- X {
- X int ll, ul, lr, ur;
- X struct edge *temp;
- X
- X if (left->topX > right->topX || left->bottomX > right->bottomX)
- X temp = left, left = right, right = temp;
- X
- X ll = Xvalue (left->topX, left->topY, left->bottomX, left->bottomY, bottom);
- X ul = Xvalue (left->topX, left->topY, left->bottomX, left->bottomY, top);
- X lr = Xvalue (right->topX, right->topY, right->bottomX, right->bottomY, bottom);
- X ur = Xvalue (right->topX, right->topY, right->bottomX, right->bottomY, top);
- X
- X MoveTo (output_path, NewHardPoint ((float) ll, (float) bottom));
- X LineTo (output_path, NewHardPoint ((float) lr, (float) bottom));
- X LineTo (output_path, NewHardPoint ((float) ur, (float) top));
- X LineTo (output_path, NewHardPoint ((float) ul, (float) top));
- X ClosePath (output_path);
- X }
- X
- Xint InitClip ()
- X {
- X PathFree (gstate->clip);
- X gstate->clip = PathCopy (gstate->device->default_clip);
- X
- X UnlinkDevice (gstate->clipdevice);
- X gstate->clipdevice = NULL;
- X
- X SetClipHardware (gstate->device->dev, NULL);
- X
- X return TRUE;
- X }
- X
- Xstatic int Clip ()
- X {
- X int res;
- X
- X
- X output_path = NewPath ();
- X res = FillIt (gstate->path, NwRule, gstate->clip, NwRule, PathTrapezoid);
- X /* XXX - needs optimising */
- X
- X PathFree (gstate->clip);
- X gstate->clip = output_path;
- X
- X if (res)
- X {
- X gstate->clipdevice = UniqueDevice (gstate->clipdevice);
- X SetClipHardware (gstate->device->dev, gstate->clipdevice->dev);
- X
- X output_device = gstate->clipdevice->dev;
- X output_colour = NewColour (0.0, 0.0, 0.0);
- X res = FillIt (gstate->clip, NwRule, gstate->device->default_clip, NwRule, EmitTrapezoid);
- X }
- X return res;
- X }
- X
- Xstatic int EOClip ()
- X {
- X int res;
- X
- X output_path = NewPath ();
- X res = FillIt (gstate->path, EoRule, gstate->clip, NwRule, PathTrapezoid);
- X /* XXX - needs optimising */
- X
- X PathFree (gstate->clip);
- X gstate->clip = output_path;
- X
- X if (res)
- X {
- X gstate->clipdevice = UniqueDevice (gstate->clipdevice);
- X SetClipHardware (gstate->device->dev, gstate->clipdevice->dev);
- X
- X output_device = gstate->clipdevice->dev;
- X output_colour = NewColour (0.0, 0.0, 0.0);
- X res = FillIt (gstate->clip, NwRule, gstate->device->default_clip, NwRule, EmitTrapezoid);
- X }
- X return res;
- X }
- X
- Xstatic int PClipPath ()
- X {
- X PathFree (gstate->path);
- X gstate->path = PathCopy (gstate->clip);
- X gstate->cp_defined = TRUE;
- X gstate->cp = gstate->path->last->pe.point;
- X
- X return TRUE;
- X }
- X
- X/****************************/
- X
- Xstatic struct edge edge [MAXPATHELEMENTS];
- X
- Xstatic struct edge *interesting [MAXPATHELEMENTS];
- X
- Xstatic int nedges, here, ninteresting;
- X
- Xstatic int interestingY, nextY;
- X
- Xstatic int infinity;
- X
- Xstatic int FillIt (path_a, rule_a, path_b, rule_b, emitfn)
- X Path path_a, path_b; int (*rule_a)(), (*rule_b)(); void (*emitfn)();
- X {
- X Path new;
- X static int edgecmp ();
- X static void Trapezoids (), BuildEdgeList ();
- X
- X if (EmptyPath (path_a) || EmptyPath (path_b))
- X return TRUE;
- X
- X path_a = FlattenPath (path_a);
- X path_b = FlattenPath (path_b);
- X
- X if (!CloseAll (path_a) || !CloseAll (path_b))
- X {
- X PathFree (path_a);
- X PathFree (path_b);
- X
- X return FALSE;
- X }
- X
- X nedges = 0;
- X BuildEdgeList (path_a, TRUE);
- X BuildEdgeList (path_b, FALSE);
- X qsort ((char *) edge, (unsigned) nedges, sizeof (struct edge), edgecmp);
- X PathFree (path_a);
- X PathFree (path_b);
- X Trapezoids (rule_a, rule_b, emitfn);
- X
- X return TRUE;
- X }
- X
- Xstatic void AddLowest ();
- X
- Xstatic void Trapezoids (rule_a, rule_b, emitfn) int (*rule_a)(), (*rule_b)(); void (*emitfn)();
- X {
- X static void FindInfinity (), AddInteresting ();
- X
- X nextY = edge[0].topY;
- X AddLowest (nextY);
- X FindInfinity ();
- X
- X here = 0;
- X ninteresting = 0;
- X names = 0;
- X
- X while (here != nedges || ninteresting)
- X {
- X static void RemoveEdges ();
- X
- X interestingY = nextY;
- X ProcessEdges (rule_a, rule_b, emitfn);
- X
- X AddInteresting ();
- X
- X RemoveEdges (interestingY, emitfn);
- X
- X ProcessEdges (rule_a, rule_b, emitfn);
- X }
- X }
- X
- XProcessEdges (rule_a, rule_b, emitfn) int (*rule_a)(), (*rule_b)(); void (*emitfn)();
- X {
- X struct edge *up_edge;
- X int i, count_a = 0, count_b = 0;
- X static void RemoveEdges ();
- X
- X for (i = 0; i < ninteresting; i++)
- X {
- X static void Emit ();
- X int d_a = 0, d_b = 0;
- X
- X if (interesting[i]->clip)
- X d_a = interesting[i]->dir;
- X else
- X d_b = interesting[i]->dir;
- X
- X if (UpEdge (count_a, count_b, d_a, d_b, rule_a, rule_b))
- X up_edge = interesting[i];
- X else if (DownEdge (count_a, count_b, d_a, d_b, rule_a, rule_b))
- X ThisBit (up_edge, interesting[i], interestingY, emitfn);
- X else
- X NotThisBit (interesting[i], interestingY, emitfn);
- X
- X count_a += d_a;
- X count_b += d_b;
- X }
- X if (count_a || count_b)
- X fprintf (stderr, "count_a = %dcount_b = %d\n", count_a, count_b);
- X PanicIf (count_a || count_b, "something wrong in area fill");
- X }
- X
- XThisBit (left, right, where, emitfn) struct edge *left, *right; int where; void (*emitfn)();
- X {
- X if (left->pair != right || right->up)
- X {
- X if (left->pair != NULL)
- X {
- X (*emitfn) (left, left->pair, left->startingY, left->where);
- X left->pair->startingY = left->pair->where;
- X left->pair->pair->startingY = left->pair->pair->where;
- X left->pair->pair = NULL;
- X }
- X if (right->pair != NULL)
- X {
- X (*emitfn) (right, right->pair, right->startingY, right->where);
- X right->pair->startingY = right->pair->where;
- X right->pair->pair->startingY = right->pair->pair->where;
- X right->pair->pair = NULL;
- X }
- X
- X left->pair = right;
- X right->pair = left;
- X left->startingY = right->startingY = where;
- X }
- X left->where = right->where = where;
- X left->up = TRUE; right->up = FALSE;
- X }
- X
- XNotThisBit (edge, where, emitfn) struct edge *edge; int where; void (*emitfn)();
- X {
- X if (edge->pair != NULL)
- X {
- X (*emitfn) (edge, edge->pair, edge->startingY, where);
- X edge->pair->startingY = where;
- X edge->pair->where = where;
- X edge->pair->pair = NULL;
- X edge->pair = NULL;
- X }
- X edge->startingY = where;
- X edge->where = where;
- X }
- X
- Xstatic void RemoveEdges (interestingY, emitfn) int interestingY; void (*emitfn)();
- X {
- X int i, j = 0;
- X
- X for (i = 0; i < ninteresting; i++)
- X if (interesting [i]->bottomY > interestingY)
- X interesting [j++] = interesting [i];
- X else
- X NotThisBit (interesting[i], interestingY, emitfn);
- X ninteresting = j;
- X }
- X
- Xstatic int UpEdge (count_a, count_b, inc_a, inc_b, rule_a, rule_b) int count_a, count_b, inc_a, inc_b, (*rule_a) (), (*rule_b) ();
- X {
- X return (*rule_b)(count_b + inc_b) && !(*rule_a) (count_a) && (*rule_a) (count_a + inc_a) ||
- X (*rule_a)(count_a + inc_a) && !(*rule_b) (count_b) && (*rule_b) (count_b + inc_b);
- X }
- X
- Xstatic int DownEdge (count_a, count_b, inc_a, inc_b, rule_a, rule_b) int count_a, count_b, inc_a, inc_b, (*rule_a) (), (*rule_b) ();
- X {
- X return (*rule_b)(count_b + inc_b) && (*rule_a) (count_a) && !(*rule_a) (count_a + inc_a) ||
- X (*rule_a)(count_a + inc_a) && (*rule_b) (count_b) && !(*rule_b) (count_b + inc_b);
- X }
- X
- Xstatic int EoRule (n) int n;
- X {
- X return n & 1;
- X }
- X
- Xstatic int NwRule (n) int n;
- X {
- X return n;
- X }
- X
- Xstatic float Yintersect (a, b) struct edge *a, *b;
- X {
- X float
- X num = (a->bottomX * a->topY - a->bottomY * a->topX) * (b->topY - b->bottomY) -
- X (b->bottomX * b->topY - b->bottomY * b->topX) * (a->topY - a->bottomY),
- X denom = (a->bottomX - a->topX) * (b->topY - b->bottomY) -
- X (b->bottomX - b->topX) * (a->topY - a->bottomY);
- X
- X if (denom == 0)
- X {
- X return infinity;
- X }
- X return num / denom;
- X }
- X
- Xstatic int Xvalue (ax, ay, bx, by, cy) int ax, ay, bx, by, cy;
- X {
- X return bx + (cy - by) * (ax - bx) / (float) (ay - by);
- X }
- X
- Xstatic int intercmp (aa, bb) char *aa, *bb;
- X {
- X struct edge *a = *(struct edge **) aa, *b = *(struct edge **) bb;
- X int sign;
- X
- X sign = Xvalue (a->topX, a->topY, a->bottomX, a->bottomY, interestingY + 1) -
- X Xvalue (b->topX, b->topY, b->bottomX, b->bottomY, interestingY + 1);
- X if (sign == 0)
- X return a->bottomX - b->bottomX;
- X return sign;
- X }
- X
- Xstatic void AddInteresting ()
- X {
- X int i;
- X
- X nextY = infinity;
- X for (; here < nedges && edge[here].topY <= interestingY; here++) /* look at each new interesting edge */
- X {
- X int i, n;
- X
- X for (i = 0; i < ninteresting; i++) /* look at all possible intersections */
- X {
- X int inter = Yintersect (&edge[here], interesting[i]);
- X
- X if (inter >= interestingY && inter <= edge[here].bottomY && inter <= interesting[i]->bottomY)
- X AddLowest (inter);
- X }
- X n = ninteresting++;
- X interesting[n] = &edge[here];
- X interesting[n]->pair = NULL;
- X interesting[n]->up = FALSE;
- X interesting[n]->startingY = interesting[n]->where = edge[here].topY;
- X interesting[n]->name = names++;
- X }
- X i = NextLowest (interestingY);
- X if (i)
- X nextY = i;
- X if (here != nedges && edge[here].topY < nextY)
- X nextY = edge[here].topY;
- X for (i = 0; i < ninteresting; i++)
- X {
- X if (interesting[i]->topY > interestingY && interesting[i]->topY < nextY)
- X nextY = interesting[i]->topY;
- X if (interesting[i]->bottomY > interestingY && interesting[i]->bottomY < nextY)
- X nextY = interesting[i]->bottomY;
- X }
- X qsort ((char *) interesting, (unsigned) ninteresting, sizeof (struct edge *), intercmp);
- X }
- X
- Xstatic void FindInfinity ()
- X {
- X int i;
- X
- X infinity = edge[0].topY;
- X for (i = 0; i < nedges; i++)
- X if (edge[i].bottomY > infinity)
- X infinity = edge[i].bottomY;
- X }
- X
- X/***************************/
- X
- Xstatic int edgecmp (a, b) char *a, *b;
- X {
- X struct edge *aa = (struct edge *) a, *bb = (struct edge *) b;
- X
- X return aa->topY - bb->topY;
- X }
- X
- Xstatic int AddEdge (e, from, to, clip) struct edge *e; HardPoint from, to; int clip;
- X {
- X int dir = 1;
- X HardPoint temp;
- X
- X if ((int) (from.hy) == (int) (to.hy))
- X return 0;
- X if ((int) (from.hy) > (int) (to.hy))
- X {
- X temp = from; from = to; to = temp;
- X dir = -dir;
- X }
- X e->topX = from.hx;
- X e->topY = from.hy;
- X e->bottomX = to.hx;
- X e->bottomY = to.hy;
- X e->dir = dir;
- X e->clip = clip;
- X
- X return 1;
- X }
- X
- Xstatic void BuildEdgeList (path, clip) Path path; int clip;
- X {
- X Path p;
- X HardPoint move, here;
- X
- X for (p = path->next; p != path; p = p->next)
- X switch (p->ptype)
- X {
- X case EMove: move = here = p->pe.point; break;
- X case ELine:
- X nedges += AddEdge (&edge[nedges], here, p->pe.point, clip);
- X here = p->pe.point;
- X break;
- X
- X case EClose:
- X nedges += AddEdge (&edge[nedges], here, move, clip);
- X here = move;
- X break;
- X }
- X }
- X
- X/* keep list of interesting entries to come */
- X
- Xstruct lowest
- X {
- X struct lowest *higher;
- X int e;
- X } *lowest_free = NULL, *lowest = NULL;
- X
- Xstatic int NextLowest (y) int y;
- X {
- X int res;
- X struct lowest *p;
- X
- X for (p = lowest; p && p->e <= y; p = lowest) /* delete any which are now irrelevent */
- X {
- X lowest = p->higher;
- X p->higher = lowest_free;
- X lowest_free = p;
- X }
- X
- X if (lowest == NULL)
- X return 0;
- X res = lowest->e;
- X
- X return res;
- X }
- X
- Xstatic void AddLowest (e) int e;
- X {
- X struct lowest *res, *p, *q;
- X
- X for (p = lowest; p && p->e < e; q = p, p = p->higher)
- X ;
- X
- X if (p && p->e == e)
- X return;
- X if (lowest_free == NULL)
- X res = (struct lowest *) Malloc (sizeof (struct lowest));
- X else
- X res = lowest_free, lowest_free = lowest_free->higher;
- X
- X res->e = e;
- X res->higher = p;
- X if (p != lowest)
- X q->higher = res;
- X else
- X lowest = res;
- X }
- END_OF_FILE
- if test 14650 -ne `wc -c <'source/fill.c'`; then
- echo shar: \"'source/fill.c'\" unpacked with wrong size!
- fi
- # end of 'source/fill.c'
- fi
- echo shar: End of archive 12 \(of 18\).
- cp /dev/null ark12isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 18 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-