sk@ukc.UUCP (S.Kenyon) (04/10/85)
#!/bin/sh echo 'Start of jerq layers code, part 02 of 04:' echo 'x - plot/plot.c' sed 's/^X//' > plot/plot.c << '/' X X/* X * File: plot.c X * X * Sccs-id: @(#)plot.c 1.4 85/03/24 X * X * Description: This file contains the one function plot, which X * given a bitmap sb, a rectangle r and a scale factor size X * create a plot file suitable for the Printronix. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/02/22 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include <stdio.h> X X#include "../h/layers.h" X Xint bitptr; /* bit pointer into scan line being X constructed */ X X/* X * Name: plot X * X * Description: Given a bitmap sb, a rectangle r and a scale factor size X * create a plot file suitable for the Printronix. X * X * Synopsis: plot (sb, r, size) X * struct Bitmap *sb; X * struct Rectangle r; X * int size; X * X * Globals: bitptr (w) X * X * Calls: printf (libc) X * append (append.c) X * reformat (reformat.c) X * outline (outline.c) X * X * Called by: This is a top level function. X */ Xplot (sb, r, size) Xstruct Bitmap *sb; Xstruct Rectangle r; Xint size; X{ X int Index; X int Delta; X int sx; X int sy; X int dx; X int dy; X int w; X int h; X int startBits; X int endBits; X int start; X int end; X int word; X int nWords; X int scanline; X int linecount; X unsigned short srcWord; X X w = r.corner.x - r.origin.x; X h = r.corner.y - r.origin.y; X if ((w <= 0) || (h <= 0)) X return; X sx = r.origin.x; X sy = r.origin.y; X startBits = sx % WORDSIZE; X endBits = (sx + w - 1) % WORDSIZE; X if (w <= (WORDSIZE - startBits)) X nWords = 1; X else X nWords = (w - (WORDSIZE - startBits) - 1) / WORDSIZE + 2; X Index = (sy - sb -> rect.origin.y) * sb -> width + X (sx / WORDSIZE) - X (sb -> rect.origin.x / WORDSIZE); X Delta = sb -> width - nWords; X/* X * gunge at start of plotfile X */ X printf ("\n\n\n"); X for (scanline = 1; scanline <= h; scanline++) { X /* X * gunge at start of plot line X */ X bitptr = 0; X X start = startBits; X end = WORDSIZE - 1; X for (word = 1; word <= nWords; word++) { X srcWord = *(sb -> base + Index); X append (srcWord, start, end, size); X Index++; X if (word == (nWords - 1)) { X start = 0; X end = endBits; X } X else { X start = 0; X end = WORDSIZE - 1; X } X } X /* X * gunge at end of line X */ X append ((short) 0, 0, 15, 1); /* kludge (I'm sorry) */ X reformat (); X for (linecount = 0; linecount < size; linecount++) X outline (); X Index += Delta; X } X} / echo 'x - src/addobs.c' sed 's/^X//' > src/addobs.c << '/' X X/* X * File: addobs.c X * X * Sccs-id: @(#)addobs.c 1.4 85/03/24 X * X * Description: This file contains the one function addobs which X * adds obscured rectangle argr to obscured list op X * of layer lp, subdividing obscured portions X * of layers as necessary. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/02/27 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: addobs X * X * Description: Add obscured rectangle argr to obscured list op X * of layer lp, subdividing obscured portions X * of layers as necessary. X * X * Synopsis: boolean addobs (op, argr, newr, lp) X * struct Obscured *op; X * struct Rectangle argr; X * struct Rectangle newr; X * struct Layer *lp; X * X * Globals: None. X * X * Calls: rectXrect (rectxrect.c) X * addobs (addobs.c) X * addrect (addrect.c) X * balloc (balloc.c) X * malloc (libc) X * bitblt (bitblt.c) X * X * Called by: newlayer (newlayer.c) X * addobs (addobs.c) X */ Xboolean addobs (op, argr, newr, lp) Xstruct Obscured *op; Xstruct Rectangle argr; /* struct Obscured rectangle */ Xstruct Rectangle newr; /* complete rectangle of new layer */ Xstruct Layer *lp; /* layer op belongs to */ X{ X struct Obscured *newop; X struct Rectangle r; X struct Bitmap *bp; X struct Rectangle temp; X X struct Bitmap *balloc (); X char *malloc (); X X r = argr; /* argr will be unchanged through X addobs() */ X if (rectXrect (r, newr)) { X /* X * this is much like layerop() X */ X if (r.origin.y < newr.origin.y) { X /* X * temp = piece of r below newr; X */ X temp = r; X temp.corner.y = newr.origin.y; X (void) addobs (op, temp, newr, lp); X r.origin.y = newr.origin.y; X } X if (r.corner.y > newr.corner.y) { X /* X * temp = piece of r above newr; X */ X temp = r; X temp.origin.y = newr.corner.y; X (void) addobs (op, temp, newr, lp); X r.corner.y = newr.corner.y; X } X if (r.origin.x < newr.origin.x) { X /* X * temp = piece of r to the left of newr; X */ X temp = r; X temp.corner.x = newr.origin.x; X (void) addobs (op, temp, newr, lp); X r.origin.x = newr.origin.x; X } X if (r.corner.x > newr.corner.x) { X /* X * temp = piece of r to the right of newr; X */ X temp = r; X temp.origin.x = newr.corner.x; X (void) addobs (op, temp, newr, lp); X r.corner.x = newr.corner.x; X } X /* X * r is now contained in rectangle of new layer X */ X if ((r.origin.x == argr.origin.x) &&/* no clip, just bookkeeping */ X (r.origin.y == argr.origin.y) && X (r.corner.x == argr.corner.x) && X (r.corner.y == argr.corner.y)) { X (void) addrect (r, op -> lobs); X return (FALSE); /* no subdivision */ X } X (void) addrect (r, op -> lobs); X } X bp = balloc (r); X /* X * newop = new struct Obscured X */ X newop = (struct Obscured *) malloc ((unsigned) sizeof (struct Obscured)); X /* X * copy the subdivided portion of the image X */ X (void) bitblt (op -> bmap, r, bp, bp -> rect.origin, NULL, S); X newop -> bmap = bp; X newop -> rect = r; X newop -> lobs = op -> lobs; X /* X * link newop into end of lp -> obs X */ X if (lp -> endobs != NULL) X lp -> endobs -> next = newop; X else X lp -> obs = newop; X newop -> prev = lp -> endobs; X newop -> next = NULL; X lp -> endobs = newop; X return (TRUE); /* subdivision */ X} / echo 'x - src/pass.c' sed 's/^X//' > src/pass.c << '/' X X/* X * File: pass.c X * X * Sccs-id: @(#)pass.c 1.4 85/03/24 X * X * Description: The file contains the one function Pass, which creates X * the rectangle/bitmap pair list which is used by lbitblt () X * to bitblt between two layers. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/02/21 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: Pass X * X * Description: Create a rectangle/bitmap pair list. X * X * Synopsis: Pass (lp, r, sb, op, l, p2, p3, p4) X * struct Layer *lp; X * struct Rectangle r; X * struct Bitmap *sb; X * struct Obscured *op; X * struct ListElement **l; X * int *p2; X * int *p3; X * int *p4; X * X * Globals: None. X * X * Calls: lessthan (lessthan.c) X * malloc (libc) X * X * Called by: lbitblt (lbitblt.c) X */ XPass (lp, r, sb, op, l, p2, p3, p4) Xstruct Layer *lp; Xstruct Rectangle r; Xstruct Bitmap *sb; Xstruct Obscured *op; Xstruct ListElement **l; Xint *p2; /* unused */ Xint *p3; /* unused */ Xint *p4; /* unused */ X{ X struct ListElement *e; X struct ListElement *pe; X struct ListElement *newe; X X char *malloc (); X X pe = NULL; X for (e = *l; e != NULL; e = e -> next) {/* e = each element of l */ X if (!lessthan (r, e -> rect)) { X /* X * insert {sb,r} into l before e; X */ X newe = (struct ListElement *) X malloc ((unsigned) sizeof (struct ListElement)); X newe -> bp = sb; X newe -> rect = r; X newe -> next = e; X if (pe != NULL) X pe -> next = newe; X else X *l = newe; X return; X } X pe = e; X } X /* X * append {sb,r} to l; X */ X newe = (struct ListElement *) X malloc ((unsigned) sizeof (struct ListElement)); X newe -> bp = sb; X newe -> rect = r; X newe -> next = NULL; X if (pe != NULL) X pe -> next = newe; X else X *l = newe; X} / echo 'x - src/rlayerop.c' sed 's/^X//' > src/rlayerop.c << '/' X X/* X * File: rlayerop.c X * X * Sccs-id: @(#)rlayerop.c 1.4 85/03/24 X * X * Description: This file contains the one routine Rlayerop which X * given a layer lp, a rectangle r, a bitmap operator fn, X * and the obscured list of the layer op, recursively chain X * along the obscured list of the layer, performing the X * operation on the intersection of the argument rectangle X * and the obscured bitmap, and pass nonintersecting portions on X * to be intersected with other bitmaps on the obscured list. X * when the obscured list is empty, the rectangle must be drawn X * on the screen. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xextern struct Bitmap *display; X X/* X * Name: Rlayerop X * X * Description: Given a layer lp, a rectangle r, a bitmap operator fn, X * and the obscured list of the layer op, recursively chain X * along the obscured list of the layer, performing the X * operation on the intersection of the argument rectangle X * and the obscured bitmap, and pass nonintersecting portions on X * to be intersected with other bitmaps on the obscured list. X * when the obscured list is empty, the rectangle must be drawn X * on the screen. X * X * Synopsis: Rlayerop (lp, fn, r, op, p1, p2, p3, p4) X * struct Layer *lp; X * int (*fn) (); X * struct Rectangle r; X * struct Obscured *op; X * int *p1; X * int *p2; X * int *p3; X * int *p4; X * X * Globals: display (r/w) X * X * Calls: (*fn) <=> addpiece (addpiece.c) by newlayer (newlayer.c) X * LBblt (lbblt.c) lblt (lblt.c) X * Pass (pass.c) lbitblt (lbitblt.c) X * rectXrect (rectxrect.c) X * Rlayerop (rlayerop.c) X * X * Called by: layerop (layerop.c) X * Rlayerop (rlayerop.c) X */ XRlayerop (lp, fn, r, op, p1, p2, p3, p4) Xstruct Layer *lp; Xint (*fn) (); Xstruct Rectangle r; Xstruct Obscured *op; /* element of obscured list with which X to intersect r */ Xint *p1; Xint *p2; Xint *p3; Xint *p4; X{ X struct Rectangle temp; X X /* X * recursively subdivide and intersect rectangle r X * with the obscured bitmaps in layer lp. X */ X if (op == NULL) /* this rectangle is not obscured */ X (void) (*fn) (lp, r, display, op, p1, p2, p3, p4);/* draw on screen */ X else X if (rectXrect (r, op -> rect) == FALSE)/* they miss */ X (void) Rlayerop (lp, fn, r, op -> next, p1, p2, p3, p4); X /* chain */ X else { /* they must intersect */ X if (r.origin.y < op -> rect.origin.y) { X /* X * temp = piece of r below op -> rect; X */ X temp = r; X temp.corner.y = op -> rect.origin.y; X (void) Rlayerop (lp, fn, temp, op -> next, p1, p2, p3, p4); X r.origin.y = op -> rect.origin.y; X } X if (r.corner.y > op -> rect.corner.y) { X /* X * temp = piece of r above op -> rect; X */ X temp = r; X temp.origin.y = op -> rect.corner.y; X (void) Rlayerop (lp, fn, temp, op -> next, p1, p2, p3, p4); X r.corner.y = op -> rect.corner.y; X } X if (r.origin.x < op -> rect.origin.x) { X /* X * temp = piece of r to the left of op -> rect; X */ X temp = r; X temp.corner.x = op -> rect.origin.x; X (void) Rlayerop (lp, fn, temp, op -> next, p1, p2, p3, p4); X r.origin.x = op -> rect.origin.x; X } X if (r.corner.x > op -> rect.corner.x) { X /* X * temp = piece of r right of op -> rect; X */ X temp = r; X temp.origin.x = op -> rect.corner.x; X (void) Rlayerop (lp, fn, temp, op -> next, p1, p2, p3, p4); X r.corner.x = op -> rect.corner.x; X } X /* X * what's left goes in this obscured bitmap X */ X (void) (*fn) (lp, r, op -> bmap, op, p1, p2, p3, p4); X } X} / echo 'x - src/upfront.c' sed 's/^X//' > src/upfront.c << '/' X X/* X * File: upfront.c X * X * Sccs-id: @(#)upfront.c 1.4 85/03/24 X * X * Description: This file contains the one routine upfront which X * pulls layer lp to the front of the screen. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xextern struct Layer *TopLayer; Xextern struct Layer *BottomLayer; X X/* X * Name: upfront X * X * Description: Pull layer lp to the front of the screen. X * X * Synopsis: upfront (lp) X * struct Layer *lp; X * X * Globals: BottomLayer (r/w) X * TopLayer (r/w) X * X * Calls: screenswap (screenswap.c) X * rectXrect (rectxrect.c) X * X * Called by: This is a top level routine. X * dellayer (dellayer.c) X * newlayer (newlayer.c) X */ Xupfront (lp) Xstruct Layer *lp; X{ X struct Layer *fr; /* a layer in front of lp */ X struct Layer *beh; /* a layer behind lp */ X struct Obscured *op; X struct Obscured *nop; X X if (lp -> front == NULL) X return; /* lp is at the front already */ X for (fr = lp -> front; fr != NULL; fr = fr -> front) X /* fr = each layer in front of lp */ X for (op = lp -> obs; op != NULL;) { X /* op = each obscured portion of lp */ X nop = op; X op = op -> next; X if (nop -> lobs == fr) { /* fr obscures nop */ X (void) screenswap (nop -> bmap, nop -> bmap -> rect); X /* X * unlink nop from lp X */ X if (nop -> prev != NULL) X nop -> prev -> next = nop -> next; X else X lp -> obs = nop -> next; X if (nop -> next != NULL) X nop -> next -> prev = nop -> prev; X else X lp -> endobs = nop -> prev; X /* X * link nop into end of fr X */ X if (fr -> endobs != NULL) X fr -> endobs -> next = nop; X else X fr -> obs = nop; X nop -> prev = fr -> endobs; X nop -> next = NULL; X fr -> endobs = nop; X } X } X /* X * move lp to front of layer list by X * unlinking lp from layer list... X */ X if (lp -> back != NULL) X lp -> back -> front = lp -> front; X else X BottomLayer = lp -> front; X if (lp -> front != NULL) X lp -> front -> back = lp -> back; X else X TopLayer = lp -> back; X /* X * ...and linking lp in at head of list X */ X TopLayer -> front = lp; X lp -> front = NULL; X lp -> back = TopLayer; X TopLayer = lp; X for (beh = BottomLayer; beh != lp; beh = beh -> front) X /* beh = all other layers from back to X front */ X for (op = beh -> obs; op != NULL; op = op -> next) X /* op = each obscured portion of beh */ X if (rectXrect (lp -> rect, op -> rect)) X op -> lobs = lp; /* mark op obscured by lp */ X} / echo 'x - test/hilbert.c' sed 's/^X//' > test/hilbert.c << '/' X X/* X * File: hilbert.c X * X * Sccs-id: @(#)hilbert.c 1.3 85/03/24 X * X * Description: This file contains code to plot hilbert curves X * as described in X * Algorithms + Data Structures = Programs X * by N. Wirth. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 85/03/15 Created. X * SCK 1.2 85/03/22 Tidied up for release. X * SCK 1.3 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xstruct Layer *drawP; X X/* X * Name: hilbert X * X * Description: Control routine for drawing hilbert curves. X * X * Synopsis: hilbert (depth, grid) X * int depth; X * int grid; X * X * Globals: None. X * X * Calls: a (hilbert.c) X * X * Called by: test (test.c) X */ Xhilbert (depth, grid) Xint depth; /* draw hilbert curves of orders 1 to X depth */ Xint grid; /* size to draw them */ X{ X struct Point home; X struct Point old; X struct Point cur; X int i; X int h; X X h = grid; X home.x = h / 2; X home.y = h / 2; X for (i = 1; i <= depth; i++) { X h = h / 2; X home.x += (h / 2); X home.y += (h / 2); X cur = old = home; X a (i, h, &old, &cur); X } X} X X/* X * Name: do_plot X * X * Description: Draw a line from old to cur. X * X * Synopsis: do_plot (old, cur) X * struct Point *old; X * struct Point *cur; X * X * Globals: drawP (r/w) X * X * Calls: lline (lline.c) X * X * Called by: test (test.c) X */ Xdo_plot (old, cur) Xstruct Point *old; Xstruct Point *cur; X{ X lline (drawP, *old, *cur, S); X *old = *cur; X} X X/* X * Name: a X * X * Description: Recursive procedure used to draw hilbert curves. X * X * Synopsis: a (i, h, old, cur) X * int i; X * int h; X * struct Point *cur; X * struct Point *old; X * X * Globals: None. X * X * Calls: d (hilbert.c) X * do_plot (hilbert.c) X * a (hilbert.c) X * b (hilbert.c) X * X * Called by: hilbert.c (hilbert.c) X * a (hilbert.c) X * b (hilbert.c) X * d (hilbert.c) X */ Xa (i, h, old, cur) Xint i; Xint h; Xstruct Point *cur; Xstruct Point *old; X{ X if (i > 0) { X d (i - 1, h, old, cur); X cur -> x -= h; X do_plot (old, cur); X a (i - 1, h, old, cur); X cur -> y -= h; X do_plot (old, cur); X a (i - 1, h, old, cur); X cur -> x += h; X do_plot (old, cur); X b (i - 1, h, old, cur); X } X} X X/* X * Name: b X * X * Description: Recursive procedure used to draw hilbert curves. X * X * Synopsis: b (i, h, old, cur) X * int i; X * int h; X * struct Point *cur; X * struct Point *old; X * X * Globals: None. X * X * Calls: c (hilbert.c) X * do_plot (hilbert.c) X * b (hilbert.c) X * a (hilbert.c) X * X * Called by: a (hilbert.c) X * b (hilbert.c) X * c (hilbert.c) X */ Xb (i, h, old, cur) Xint i; Xint h; Xstruct Point *cur; Xstruct Point *old; X{ X if (i > 0) { X c (i - 1, h, old, cur); X cur -> y += h; X do_plot (old, cur); X b (i - 1, h, old, cur); X cur -> x += h; X do_plot (old, cur); X b (i - 1, h, old, cur); X cur -> y -= h; X do_plot (old, cur); X a (i - 1, h, old, cur); X } X} X X/* X * Name: c X * X * Description: Recursive procedure used to draw hilbert curves. X * X * Synopsis: c (i, h, old, cur) X * int i; X * int h; X * struct Point *cur; X * struct Point *old; X * X * Globals: None. X * X * Calls: b (hilbert.c) X * do_plot (hilbert.c) X * c (hilbert.c) X * d (hilbert.c) X * X * Called by: b (hilbert.c) X * c (hilbert.c) X * d (hilbert.c) X */ Xc (i, h, old, cur) Xint i; Xint h; Xstruct Point *cur; Xstruct Point *old; X{ X if (i > 0) { X b (i - 1, h, old, cur); X cur -> x += h; X do_plot (old, cur); X c (i - 1, h, old, cur); X cur -> y += h; X do_plot (old, cur); X c (i - 1, h, old, cur); X cur -> x -= h; X do_plot (old, cur); X d (i - 1, h, old, cur); X } X} X X/* X * Name: d X * X * Description: Recursive procedure used to draw hilbert curves. X * X * Synopsis: d (i, h, old, cur) X * int i; X * int h; X * struct Point *cur; X * struct Point *old; X * X * Globals: None. X * X * Calls: a (hilbert.c) X * do_plot (hilbert.c) X * d (hilbert.c) X * c (hilbert.c) X * X * Called by: a (hilbert.c) X * c (hilbert.c) X * d (hilbert.c) X */ Xd (i, h, old, cur) Xint i; Xint h; Xstruct Point *cur; Xstruct Point *old; X{ X if (i > 0) { X a (i - 1, h, old, cur); X cur -> y -= h; X do_plot (old, cur); X d (i - 1, h, old, cur); X cur -> x -= h; X do_plot (old, cur); X d (i - 1, h, old, cur); X cur -> y += h; X do_plot (old, cur); X c (i - 1, h, old, cur); X } X} / echo 'x - test/jerq.c' sed 's/^X//' > test/jerq.c << '/' X X/* X * File: jerq.c X * X * Sccs-id: @(#)jerq.c 1.5 85/03/24 X * X * Description: This file contains the test harness for the layers code. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/04 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/21 Tidied up for release. X * SCK 1.4 85/03/22 Moved initialisation to layers.c. X * SCK 1.5 85/03/24 Changed the include files around. X */ X X#include <stdio.h> X X#include "../h/layers.h" X X/* X * Name: main X * X * Description: Main line program to call the layers code test routine. X * X * Synopsis: main(argc, argv) X * int argc; X * char **argv; X * X * Globals: None. X * X * Calls: atoi (libc) X * freopen (libc) X * fprintf (libc) X * done (jerq.c) X * usage (jerq.c) X * layers (layers.c) X * test (test.c) X * X * Called by: Operating System. X */ Xmain (argc, argv) Xint argc; Xchar **argv; X{ X char *cp; X int pltsiz; X int testno; X X pltsiz = 1; X testno = 1; X for (; argc > 1; argc--) { X argv++; X if (**argv == '-') { X switch (*++*argv) { X case 'o': /* define output file */ X if (argc >= 2) { X /* X * open output file X */ X if (freopen (*++argv, "w", stdout) == NULL) { X fprintf (stderr, "jerq: cannot open %s\n", *argv); X done (1); X } X argc--; X } X continue; X case 's': /* plot size */ X pltsiz = atoi (++*argv); X continue; X case 't': /* test no. */ X testno = atoi (++*argv); X continue; X default: X fprintf (stderr, "jerq: unknown option %s\n", *argv); X usage (); X continue; X } X } X } X test (testno, pltsiz); /* test the "Layers" code */ X done (0); X} X X/* X * Name: usage X * X * Description: Print usage message on stderr and exit. X * X * Synopsis: usage () X * X * Globals: None. X * X * Calls: fprintf (libc) X * done (jerq.c) X * X * Called by: main (jerq.c) X */ Xusage () { X fprintf (stderr, "usage: jerq [-o plotfile] [-sn] [-tn]\n"); X done (1); X} X X/* X * Name: done X * X * Description: Exit with appropriate status. X * X * Synopsis: done (n) X * int n; X * X * Globals: None. X * X * Calls: exit (libc) X * X * Called by: main (jerq.c) X * usage (jerq.c) X */ Xdone (n) Xint n; X{ X exit (n); X} / echo 'Part 02 of jerq layers code complete.' exit
sk@ukc.UUCP (S.Kenyon) (04/10/85)
#!/bin/sh echo 'Start of jerq layers code, part 03 of 04:' echo 'x - README' sed 's/^X//' > README << '/' X X Jerq X by X Simon Kenyon X (c) 1985 X XThis is a collection of files that tries to implement the layers code Xdescribed by Rob Pike in "Graphics in overlapping bitmap layers", XACM Transactions on Graphics, 2 135 (1983). This original paper has Xbeen augmented by two others, "Hardware/Software Trade-offs for Bitmap XGraphics on the Blit", Software - Practice and Experience, Vol 15(2) X131-151 (Feb 1985) and "The Blit: a multiplexed graphics terminal", XBSTJ 63 No 8 Part 2 1607 1631 (October 1984). XI have the first two, but have only briefly read the last. X XAnyway, this code might be of use to somebody, so here it is. XThe line drawing as described in the first paper is not included as XI don't have the clipping working. In it's place is a generalised line Xdrawing algorithm taken from the 1st Smalltalk-80 book, as is the Xbitblt code. X XSend any problem, suggestions or enhancements to me and I will try Xand deal with them as and when I can, but as this is a part-time Xactivity, don't hold your breath. X XThis is in the public domain, Rob having given his permission for me Xto publish this. I have had no access whatsoever to the Blit hardware Xor software, which I'm sure is pretty obvious, so there are no licencing Xhassles in me distributing this code. As a matter of fact it was debugged Xon a Printronix 300 printer/plotter. If you use it, it would be nice if Xyou left my name in the code. X XSimon Kenyon X ...!mcvax!simon X ...!ukc!sk X XWork: Home: X XPrime Computer (Ireland) Limited XClonshaugh Industrial Estate 10 Castle Avenue XCoolock Clontarf XDublin 5 Dublin 3 XIreland Ireland X X+353 1 477888 x 319 +353 1 331497 / echo 'x - h/layers.h' sed 's/^X//' > h/layers.h << '/' X X/* X * File: layers.h X * X * Sccs-id: @(#)layers.h 1.1 85/03/24 X * X * Description: This file contains all the defined constants and type X * declarations that are used in the jerq routines. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 85/03/24 Created by amalgamating all the X * other include files into one. X */ X X#ifndef NULL X#define NULL 0 X#endif NULL X X#define FALSE 0 X#define TRUE 1 X X#define boolean int X X#define WORDSIZE 16 /* size of words used in bit map */ X#define BYTESIZE 8 X X#define MAXLINE 128 X X#define CLR 1 X#define OR 2 X#define XOR 3 X#define STORE 4 X X#define ALL_ZEROS 0 X#define S_AND_D 1 X#define S_AND_ND 2 X#define S 3 X#define NS_AND_D 4 X#define D 5 X#define S_XOR_D 6 X#define S_OR_D 7 X#define NS_AND_ND 8 X#define NS_XOR_D 9 X#define ND 10 X#define S_OR_ND 11 X#define NS 12 X#define NS_OR_D 13 X#define NS_OR_ND 14 X#define ALL_ONES 15 X Xstruct Point { X int x; /* x and y coordinates of point */ X int y; X}; X Xstruct Rectangle { X struct Point origin; /* min x,y */ X struct Point corner; /* max x,y */ X}; X Xstruct Bitmap { X unsigned short *base; /* start of data */ X int width; /* width in words */ X struct Rectangle rect; /* image rectangle */ X struct Obscured *obs; /* linked list of obscured rectangles, X for compatability with Layer */ X struct Obscured *endobs; /* end of above linked list */ X}; X Xstruct Layer { X unsigned short *base; /* start of data */ X int width; /* width in words */ X struct Rectangle rect; /* image rectangle */ X struct Obscured *obs; /* linked list of obscured rectangles */ X struct Obscured *endobs; /* end of above linked list */ X struct Layer *front; /* adjacent layer in front */ X struct Layer *back; /* adjacent layer behind */ X}; X Xstruct Obscured { X struct Layer *lobs; /* frontmost obscuring layer */ X struct Bitmap *bmap; /* where the obscured data resides */ X struct Rectangle rect; /* image rectangle */ X struct Obscured *next; /* next bitmap in obscured list */ X struct Obscured *prev; /* previous bitmap in obscured list */ X}; X Xstruct ListElement { X struct Rectangle rect; X struct Bitmap *bp; X struct ListElement *next; X}; / echo 'x - man/jerq.3x' sed 's/^X//' > man/jerq.3x << '/' X X.TH JERQ 3X 85/03/26 "PR1ME Computer" X.SH NAME Xjerq \- routines to handle "overlapping asynchronous windows" ala Rob X.SH SYNOPSIS X.nf X.B background (rect) X.B struct Rectangle rect; X.PP X.B dellayer (lp) X.B struct Layer *lp; X.PP X.B layers () X.PP X.B lbitblt (sl, rect, dl, pt, hb, f) X.B struct Layer *sl; X.B struct Rectangle rect; X.B struct Layer *dl; X.B struct Point *pt; X.B struct Bitmap *hb; X.B int f; X.PP X.B lblt (l, sb, r, hb, pt, f) X.B struct Layer *l; X.B struct Bitmap *sb; X.B struct Rectangle r; X.B struct Bitmap *hb; X.B struct Point pt; X.B int f; X.PP X.B lline (lp, p0, p1, f) X.B struct Layer *lp; X.B struct Point p0; X.B struct Point p1; X.B int f; X.PP X.B struct Layer newlayer (bp, r, hb) X.B struct Bitmap *bp; X.B struct Rectangle r; X.B struct Bitmap *hb; X.PP X.B plot (sb, r, size) X.B struct Bitmap *sb; X.B struct Rectangle r; X.B int size; X.PP X.B upfront (lp) X.B struct Layer *lp; X.fi X.SH DESCRIPTION X.I Background Xfills X.I rect Xwith the background colour. X.PP X.I Dellayer Xdeletes layer X.I lp Xfrom the display and fills it in with the background colour. X.PP X.I Layers Xinitialises the layers package, Xcreating the display bitmap and Xfilling it in with the background colour. X.PP X.I Lbitblt Xperforms a bitblt operation from the source rectangle X.I rect Xin layer X.I sl Xto the corresponding rectangle with origin X.I pt Xin the destination layer X.IR dl . XThe bitmap X.I hb Xis Xan optional halftone pattern. X.PP X.IR Lblt , Xgiven a layer X.IR l , Xa bitmap X.IR sb , Xa rectangle X.I r Xand a function code X.IR f , Xcopies the off-screen bitmap X.I sb Xto a rectangle X.I r Xwithin layer X.IR l . X.PP X.I Lline Xdraws a line from X.I p0 Xto X.I p1 Xin a layer X.IR lp , Xusing code X.IR f . X.PP X.I Newlayer Xcreates a new layer in rectangle X.I r Xof bitmap X.I bp Xand eithers fill the layer with optional halftone X.I hb Xor clears it. XIt returns a pointer to the new layer. X.PP X.IR Plot , Xgiven a bitmap X.IR sb , Xa rectangle X.I r Xand a scale factor X.I size Xcreates a plot file suitable for the Printronix. X.PP X.I Upfront Xpulls layer X.I lp Xto the front of the screen, Xso that it is obscured by no other layer. X.SH SEE ALSO Xjerq(5) X.SH AUTHOR XSimon Kenyon X.SH BUGS XIn X.I background Xthe bitmap and the background colour to fill it with Xare hard-coded into the routine. X.PP XIn X.I layers Xthe display bitmap and the background colour Xare hard-coded into the routine. X.PP XThe code in X.I lline Xis nowhere as efficient as the restartable dda Xdescribed in Rob's original paper, Xbut I was having so much hassle with the clipping in that, Xand I wanted to ship this... X.PP XIn X.I plot Xthe output is sent to X.IR stdout . / echo 'x - plot/reformat.c' sed 's/^X//' > plot/reformat.c << '/' X X/* X * File: reformat.c X * X * Sccs-id: @(#)reformat.c 1.4 85/03/24 X * X * Description: This file contains one routine reformat which X * diddles the bits in a plot line so that the X * Printronix printer/plotter understands them. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xextern int bitptr; Xextern unsigned short line[]; Xextern unsigned short wordmask[]; X Xunsigned short bytemask[] = { X 0x80, 0x40, 0x20, 0x10, X 0x08, 0x04, 0x02, 0x01 X}; Xunsigned char outlin[1024]; Xint outptr; X X/* X * Name: reformat X * X * Description: Diddle the bits in a plot line so that the X * Printronix printer/plotter understands them. X * X * Synopsis: reformat () X * X * Globals: bitptr (r) X * line (r) X * wordmask (r) X * bytemask (r) X * outlin (w) X * outptr (r/w) X * X * Calls: Nothing. X * X * Called by: plot (plot.c) X */ Xreformat () X{ X int i; X X /* X * note that because this code runs under PRIMOS X * the top bit of each byte is being set X */ X outlin[0] = 0x85; /* that's what the man said */ X outptr = 15; X for (i = 0; i < bitptr; i++) { X if (line[i / WORDSIZE] & wordmask[i % WORDSIZE]) X outlin[outptr / BYTESIZE] |= bytemask[outptr % BYTESIZE]; X else X outlin[outptr / BYTESIZE] &= ~bytemask[outptr % BYTESIZE]; X if ((outptr % BYTESIZE) == 2) { X outlin[outptr / BYTESIZE] |= 0xC0; X outptr += 13; /* left as an exercise to the reader */ X } X else X outptr--; X } X} / echo 'x - src/addrect.c' sed 's/^X//' > src/addrect.c << '/' X X/* X * File: addrect.c X * X * Sccs-id: @(#)addrect.c 1.4 85/03/24 X * X * Description: This file contains one routine addrect which X * adds rectangle r to the obscured list of new layer lp X * iff it is unique. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/01 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xextern struct Obscured *obs; Xextern struct Obscured *endobs; X X/* X * Name: addrect X * X * Description: Add rectangle r to the obscured list of new layer lp X * iff it is unique. (no spelling mistake) X * X * Synopsis: addrect (r, lp) X * struct Rectangle r; X * struct Layer *lp; X * X * Globals: obs (r/w) X * endobs (r/w) X * X * Calls: malloc (libc) X * X * Called by: addpiece (addpiece.c) X * addobs (addobs.c) X */ Xaddrect (r, lp) Xstruct Rectangle r; Xstruct Layer *lp; /* layer currently occupying rectangle r X on screen */ X{ X struct Obscured *op; X struct Obscured *newop; X X char *malloc (); X X for (op = obs; op != NULL; op = op -> next)/* op = each element of obs */ X if ((op -> rect.origin.x == r.origin.x) && X (op -> rect.origin.y == r.origin.y)) X return; /* not unique */ X /* X * newop = new struct Obscured X */ X newop = (struct Obscured *) malloc ((unsigned) sizeof (struct Obscured)); X newop -> rect = r; X newop -> lobs = lp; X newop -> bmap = NULL; X /* X * link newop into end of obs list X */ X if (endobs != NULL) X endobs -> next = newop; X else X obs = newop; X newop -> prev = endobs; X newop -> next = NULL; X endobs = newop; X} / echo 'x - src/balloc.c' sed 's/^X//' > src/balloc.c << '/' X X/* X * File: balloc.c X * X * Sccs-id: @(#)balloc.c 1.4 85/03/24 X * X * Description: This file contains the one function balloc which X * allocates a bitmap and return a pointer to it, X * using the rectangle r, which is the on-screen X * rectangle that corresponds to the bitmap image. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: balloc X * X * Description: Allocate a bitmap and return a pointer to it, X * using the rectangle r, which is the on-screen X * rectangle that corresponds to the bitmap image. X * X * Synopsis: struct Bitmap *balloc (r) X * struct Rectangle r; X * X * Globals: None. X * X * Calls: malloc (libc) X * X * Called by: newlayer (newlayer.c) X * addobs (addobs.c) X */ Xstruct Bitmap *balloc (r) Xstruct Rectangle r; X{ X struct Bitmap *b; X int h; X int w; X int startBits; X int nWords; X int size; X X char *malloc (); X X /* X * allocate storage for a bitmap and return a pointer to it X */ X w = r.corner.x - r.origin.x; X h = r.corner.y - r.origin.y; X startBits = WORDSIZE - (r.origin.x % WORDSIZE); X if (w <= startBits) X nWords = 1; X else X nWords = (w - startBits - 1) / WORDSIZE + 2; X size = nWords * h + 1; /* the extra word is because of the way X my implementation of bitblt works */ X b = (struct Bitmap *) malloc ((unsigned) sizeof (struct Bitmap)); X b -> base = (unsigned short *) malloc ((unsigned) (size * 2)); X b -> width = nWords; X b -> rect = r; X b -> obs = NULL; /* not used in a bitmap */ X return (b); X} / echo 'x - src/dellayer.c' sed 's/^X//' > src/dellayer.c << '/' X X/* X * File: dellayer.c X * X * Sccs-id: @(#)dellayer.c 1.4 85/03/24 X * X * Description: This file contains one routine dellayer which X * deletes layer lp from the screen. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/02/27 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xextern struct Layer *TopLayer; Xextern struct Layer *BottomLayer; X X/* X * Name: dellayer X * X * Description: Delete layer lp from the screen. X * X * Synopsis: dellayer (lp) X * struct Layer *lp; X * X * Globals: BottomLayer (r/w) X * TopLayer (w) X * X * Calls: upfront (upfront.c) X * background (background.c) X * bfree (bfree.c) X * free (libc) X * X * Called by: This is a top level routine. X */ Xdellayer (lp) Xstruct Layer *lp; X{ X struct Obscured *op; X struct Obscured *nop; X X /* X * pull the layer to the front X * it now has no obscured pieces, X * and is a contiguous rectangle on the screen X */ X (void) upfront (lp); X /* X * colour the screen rectangle the background colour X */ X (void) background (lp -> rect); X /* X * push the layer to the back using upfront() X */ X while (lp -> back != NULL) /* lp not rearmost layer */ X (void) upfront (BottomLayer); /* rearmost layer */ X /* X * all storage needed for the obscured portions of the layer X * is now bound to the layer, X * since it obscures no other layer, X * so free all storage associated with the layer X */ X for (op = lp -> obs; op != NULL;) { X /* op = each obscured part of lp */ X nop = op; X op = op -> next; X (void) bfree (nop -> bmap); X free ((char *) nop); X } X /* X * unlink the layer from the layer list X */ X if (lp -> back != NULL) X lp -> back -> front = lp -> front; X else X BottomLayer = lp -> front; X if (lp -> front != NULL) X lp -> front -> back = lp -> back; X else X TopLayer = lp -> back; X /* X * free the layer storage X */ X free ((char *) lp); X} / echo 'x - src/layerop.c' sed 's/^X//' > src/layerop.c << '/' X X/* X * File: layerop.c X * X * Sccs-id: @(#)layerop.c 1.4 85/03/24 X * X * Description: This file contains the one routine layerop which X * given a layer lp, a rectangle within the layer r, X * and a bitmap operator fn, recursively subdivide X * the rectangle r into rectangles contained within X * single bitmaps, and invokes the operator on the X * rectangle/bitmap pairs. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: layerop X * X * Description: Given a layer lp, a rectangle within the layer r, X * and a bitmap operator fn, recursively subdivide X * the rectangle r into rectangles contained within X * single bitmaps, and invokes the operator on the X * rectangle/bitmap pairs. X * Also passed is a pointer to a set of parameters X * for the bitmap operator otherargs. X * X * Synopsis: layerop (lp, fn, r, p1, p2, p3, p4) X * struct Layer *lp; X * int (*fn) (); X * struct Rectangle r; X * int *p1; X * int *p2; X * int *p3; X * int *p4; X * X * Globals: None. X * X * Calls: rectXrect (rectxrect.c) X * intersection (intersection.c) X * Rlayerop (rlayerop.c) X * X * Called by: newlayer (newlayer.c) X * lblt (lblt.c) X * lbitblt (lbitblt.c) X */ Xlayerop (lp, fn, r, p1, p2, p3, p4) Xstruct Layer *lp; Xint (*fn) (); /* pointer to bitmap operator */ Xstruct Rectangle r; Xint *p1; /* other arguments used by (*fn)() */ Xint *p2; Xint *p3; Xint *p4; X{ X struct Rectangle intersection (); X X /* X * clip to outer rectangle of layer, then call Rlayerop() X */ X if (rectXrect (r, lp -> rect)) { X r = intersection (r, lp -> rect); X (void) Rlayerop (lp, fn, r, lp -> obs, p1, p2, p3, p4); X } X} / echo 'x - src/layers.c' sed 's/^X//' > src/layers.c << '/' X X/* X * File: layers.c X * X * Sccs-id: @(#)layers.c 1.2 85/03/24 X * X * Description: This file contains the one routine layers which X * initialises the layers code. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 85/03/21 Created. X * SCK 1.2 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xstruct Layer *TopLayer; Xstruct Layer *BottomLayer; Xstruct Bitmap *display; Xstruct Rectangle disprect = {{ X 0, 0 X}, { X 256, 256 X} X}; X X/* X * Name: layers X * X * Description: Initialise my implementation of Layers X * as described in X * X * acm Transactions On Graphics, X * April 1983 - Vol. 2, No. 2. X * X * and also in X * X * Software - Practice and Experience, X * February 1985 - Vol. 15, No. 2. X * X * Synopsis: layers () X * X * Globals: TopLayer (w) X * BottomLayer (w) X * display (w) X * disprect (r/w) X * X * Calls: balloc (balloc.c) X * background (background.c) X * X * Called by: This is a top-level routine. X */ Xlayers () X{ X struct Bitmap *balloc (); X X TopLayer = NULL; X BottomLayer = NULL; X display = balloc (disprect); X (void) background (display -> rect); X} / echo 'x - src/lbitblt.c' sed 's/^X//' > src/lbitblt.c << '/' X X/* X * File: lbitblt.c X * X * Sccs-id: @(#)lbitblt.c 1.4 85/03/24 X * X * Description: This file contains one routine lbitblt which X * bitblts the source rectangle rect in layer sl X * to the corresponding rectangle with origin pt X * in the destination layer dl. The bitmap hb is X * an optional halftone pattern. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xstruct Point delta; X X/* X * Name: lbitblt X * X * Description: Bitblt the source rectangle rect in layer sl X * to the corresponding rectangle with origin pt X * in the destination layer dl. The bitmap hb is X * an optional halftone pattern. X * X * Synopsis: lbitblt (sl, rect, dl, pt, hb, f) X * struct Layer *sl; X * struct Rectangle rect; X * struct Layer *dl; X * struct Point pt; X * struct Bitmap *hb; X * int f; X * X * Globals: Pass () (pass.c) X * delta (r/w) X * X * Calls: layerop (layerop.c) X * lblt (lblt.c) X * X * Called by: This is a top level function. X */ Xlbitblt (sl, rect, dl, pt, hb, f) Xstruct Layer *sl; Xstruct Rectangle rect; Xstruct Layer *dl; Xstruct Point pt; Xstruct Bitmap *hb; /* halftone bitmap */ Xint f; X{ X struct ListElement *SrcList; X struct ListElement *s; X struct Rectangle r; X struct Point p; X X int Pass (); X X SrcList = NULL; X delta.x = pt.x - rect.origin.x; X delta.y = pt.y - rect.origin.y; X (void) layerop (sl, Pass, rect, &SrcList, NULL, NULL, NULL); X for (s = SrcList; s != NULL; s = s -> next) { X /* X * s = each element of SrcList X */ X p.x = s -> rect.origin.x + delta.x; X p.y = s -> rect.origin.y + delta.y; X (void) lblt (dl, s -> bp, s -> rect, hb, p, f); X } X} / echo 'x - src/lline.c' sed 's/^X//' > src/lline.c << '/' X X/* X * File: lline.c X * X * Sccs-id: @(#)lline.c 1.3 85/03/24 X * X * Description: This file contains a generalised line drawing routine. X * X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 85/03/01 Created. X * SCK 1.2 85/03/08 Tidied up for release. X * SCK 1.3 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xunsigned short penmap[] = { X 0xFFFF X}; Xstruct Bitmap pen = { X penmap, 1, {{ X 0, 0 X }, { X 1, 1 X } X }, 0, 0 X}; X X/* X * Name: sign X * X * Description: Return the sign of the argument a. X * X * Synopsis: int sign (a) X * int a; X * X * Globals: None. X * X * Calls: Nothing. X * X * Called by: lline (lline.c) X */ Xint sign (a) Xint a; X{ X if (a < 0) X return (-1); X else X if (a > 0) X return (1); X else X return (0); X} X X/* X * Name: lline X * X * Description: Draw a line from p0 to p1 in a layer lp, using code f. X * (This was snarfed from the 1st Smalltalk-80 book. It X * is nowhere as efficient as the restartable dda described X * in Rob's original paper, but I was having so much hassle X * with the clipping in that, and I wanted to ship this...) X * X * Synopsis: lline (lp, p0, p1, f) X * struct Layer *lp; X * struct Point p0; X * struct Point p1; X * int f; X * X * Globals: pen (r) X * X * Calls: lblt (lblt.c) X * X * Called by: This is a top level routine. X */ Xlline (lp, p0, p1, f) Xstruct Layer *lp; Xstruct Point p0; Xstruct Point p1; Xint f; X{ X int dx; X int dy; X int px; X int py; X int p; X struct Point pt; X int i; X X dx = sign (p1.x - p0.x); X dy = sign (p1.y - p0.y); X px = abs (p1.y - p0.y); X py = abs (p1.x - p0.x); X pt.x = p0.x + lp -> rect.origin.x; X pt.y = p0.x + lp -> rect.origin.x; X lblt (lp, &pen, pen.rect, NULL, pt, f);/* first point */ X if (py > px) { /* more horizontal */ X p = py / 2; X for (i = 1; i < py; i++) { X pt.x += dx; X if ((p -= px) < 0) { X pt.y += dy; X p += py; X } X lblt (lp, &pen, pen.rect, NULL, pt, f); X } X } X else { /* more horizontal */ X p = px / 2; X for (i = 1; i <= px; i++) { X pt.y += dy; X if ((p -= py) < 0) { X pt.x += dx; X p += px; X } X lblt (lp, &pen, pen.rect, NULL, pt, f); X } X } X} / echo 'x - src/merge.c' sed 's/^X//' > src/merge.c << '/' X X/* X * File: merge.c X * X * Sccs-id: @(#)merge.c 1.4 85/03/24 X * X * Description: This file contains the one function merge which X * merges sourceWord with destinationWord using the X * boolean operation specified by the function code f. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/02/26 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xextern unsigned short AllOnes; X X/* X * Name: merge X * X * Description: Merge sourceWord with destinationWord using the X * boolean operation specified by the function code f. X * X * Synopsis: unsigned short merge (sourceWord, destinationWord, f) X * unsigned short sourceWord; X * unsigned short destinationWord; X * int f; X * X * Globals: AllOnes (r) X * X * Calls: Nothing. X * X * Called by: bitblt (bitblt.c) X */ Xunsigned short merge (sourceWord, destinationWord, f) Xunsigned short sourceWord; Xunsigned short destinationWord; Xint f; X{ X /* X * these are the 16 combination rules X */ X switch (f) { X case ALL_ZEROS: X return (0); X case S_AND_D: X return (sourceWord & destinationWord); X case S_AND_ND: X return (sourceWord & ~destinationWord); X case S: X return (sourceWord); X case NS_AND_D: X return (~sourceWord & destinationWord); X case D: X return (destinationWord); X case S_XOR_D: X return (sourceWord ^ destinationWord); X case S_OR_D: X return (sourceWord | destinationWord); X case NS_AND_ND: X return (~sourceWord & ~destinationWord); X case NS_XOR_D: X return (~sourceWord ^ destinationWord); X case ND: X return (~destinationWord); X case S_OR_ND: X return (sourceWord | ~destinationWord); X case NS: X return (~sourceWord); X case NS_OR_D: X return (~sourceWord | destinationWord); X case NS_OR_ND: X return (~sourceWord | ~destinationWord); X case ALL_ONES: X return (AllOnes); X } X} / echo 'Part 03 of jerq layers code complete.' exit
sk@ukc.UUCP (S.Kenyon) (04/10/85)
#!/bin/sh echo 'Start of jerq layers code, part 04 of 04:' echo 'x - man/jerq.5' sed 's/^X//' > man/jerq.5 << '/' X X.TH JERQ 5 85/03/28 "PR1ME Computer" X.SH NAME Xjerq \- jerq code data structures X.SH SYNOPSIS X.B #include "jerq/h/layers.h" X.SH DESCRIPTION XHere are the definitions of the data structures that are passed in and out Xof the layers routines. X.PP X.nf Xstruct Point { X int x; /* x and y coordinates of point */ X int y; X}; X Xstruct Rectangle { X struct Point origin; /* min x,y */ X struct Point corner; /* max x,y */ X}; X Xstruct Bitmap { X unsigned short *base; /* start of data */ X int width; /* width in words */ X struct Rectangle rect; /* image rectangle */ X struct Obscured *obs; /* linked list of obscured rectangles, X for compatability with Layer */ X struct Obscured *endobs; /* end of above linked list */ X}; X Xstruct Layer { X unsigned short *base; /* start of data */ X int width; /* width in words */ X struct Rectangle rect; /* image rectangle */ X struct Obscured *obs; /* linked list of obscured rectangles */ X struct Obscured *endobs; /* end of above linked list */ X struct Layer *front; /* adjacent layer in front */ X struct Layer *back; /* adjacent layer behind */ X}; X.fi X.SH SEE ALSO Xjerq(3X) X.SH AUTHOR XSimon Kenyon X.SH BUGS X.I XEndobs Xis not stricly necessary, Xbut it made coding a lot easier. / echo 'x - plot/addbit.c' sed 's/^X//' > plot/addbit.c << '/' X X/* X * File: addbit.c X * X * Sccs-id: @(#)addbit.c 1.5 85/03/24 X * X * Description: This file contains the one function addbit which X * adds a bit onto the end of the current plot line. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/22 Fixed up global variable declarations. X * SCK 1.5 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xextern int bitptr; X Xunsigned short line[512]; Xunsigned short wordmask[] = { X 0x8000, 0x4000, 0x2000, 0x1000, X 0x0800, 0x0400, 0x0200, 0x0100, X 0x0080, 0x0040, 0x0020, 0x0010, X 0x0008, 0x0004, 0x0002, 0x0001 X}; X X/* X * Name: addbit X * X * Description: Add a bit onto the end of the current plot line. X * X * Synopsis: addbit (bit) X * int bit; X * X * Globals: bitptr (r/w) X * line (w) X * wordmask (r) X * X * Calls: Nothing. X * X * Called by: append (append.c) X */ Xaddbit (bit) Xint bit; /* 0 or 1 */ X{ X int wordidx; X int bitidx; X X wordidx = bitptr / WORDSIZE; X bitidx = bitptr % WORDSIZE; X if (bit) X line[wordidx] |= wordmask[bitidx]; X else X line[wordidx] &= ~wordmask[bitidx]; X bitptr++; X} / echo 'x - plot/append.c' sed 's/^X//' > plot/append.c << '/' X X/* X * File: append.c X * X * Sccs-id: @(#)append.c 1.4 85/03/24 X * X * Description: This file contains the one function append which X * adds some more bits to the end of the plot line. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: append X * X * Description: Add some more bits to the end of the plot line. X * X * Synopsis: append (bits, start, end, size) X * unsigned short bits; X * int start; X * int end; X * int size; X * X * Globals: None. X * X * Calls: addbit (addbit.c) X * X * Called by: plot (plot.c) X */ Xappend (bits, start, end, size) Xunsigned short bits; Xint start; Xint end; Xint size; X{ X int i; X int j; X X for (i = start; i <= end; i++) X for (j = 0; j < size; j++) X if (bits & (1 << (WORDSIZE - (i + 1)))) X addbit (1); X else X addbit (0); X} / echo 'x - plot/outline.c' sed 's/^X//' > plot/outline.c << '/' X X/* X * File: outline.c X * X * Sccs-id: @(#)outline.c 1.4 85/03/24 X * X * Description: This file contains the one function outline which X * sends the next output line to the Printronix plotter. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include <stdio.h> X X#include "../h/layers.h" X Xextern int outptr; Xextern unsigned char outlin[]; X X/* X * Name: outline X * X * Description: Send the next output line to the Printronix plotter. X * X * Synopsis: outline () X * X * Globals: outptr (r) X * outlin (r) X * X * Calls: printf (libc) X * X * Called by: plot (plot.c) X */ Xoutline () X{ X int i; X X for (i = 0; i < (outptr / BYTESIZE); i++) X printf ("%c", outlin[i]); X printf ("\n"); X} / echo 'x - src/addpiece.c' sed 's/^X//' > src/addpiece.c << '/' X X/* X * File: addpiece.c X * X * Sccs-id: @(#)addpiece.c 1.4 85/03/24 X * X * Description: This file contains the one routine addpiece which X * adds to the obscured list the rectangles that are currently X * unobscured (i.e. that only have one layer), but that will X * be obscured by the new layer X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/02/27 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: addpiece X * X * Description: Add to the obscured list the rectangles that are currently X * unobscured (i.e. that only have one layer), but that will X * be obscured by the new layer X * X * Synopsis: addpiece (lp, r, bp, op, flp, p2, p3, p4) X * struct Layer *lp; X * struct Rectangle r; X * struct Bitmap *bp; X * struct Obscured *op; X * struct Layer *flp; X * int *p2; X * int *p3; X * int *p4; X * X * Globals: None. X * X * Calls: addrect (addrect.c) X * X * Called by: newlayer (newlayer.c) X */ Xaddpiece (lp, r, bp, op, flp, p2, p3, p4) Xstruct Layer *lp; Xstruct Rectangle r; Xstruct Bitmap *bp; Xstruct Obscured *op; Xstruct Layer *flp; Xint *p2; /* unused */ Xint *p3; /* unused */ Xint *p4; /* unused */ X{ X if (op == NULL) /* this piece is occupied by only one X layer */ X (void) addrect (r, flp); X /* X * otherwise it's already in obs list X */ X} / echo 'x - src/background.c' sed 's/^X//' > src/background.c << '/' X X/* X * File: background.c X * X * Sccs-id: @(#)background.c 1.4 85/03/24 X * X * Description: This file contains the one function background which X * paints rectangle rect of the display bitmap X * the background colour. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xextern struct Bitmap *display; X Xunsigned short bght[] = { /* background halftone bitmap */ X 0x8888, 0x0000, 0x2222, 0x0000, X 0x8888, 0x0000, 0x2222, 0x0000, X 0x8888, 0x0000, 0x2222, 0x0000, X 0x8888, 0x0000, 0x2222, 0x0000 X}; Xstruct Bitmap back = { X bght, 1, {{ X 0, 0 X }, { X WORDSIZE, WORDSIZE X } X }, 0 X}; X X/* X * Name: background X * X * Description: Paint rectangle rect of the display bitmap X * the background colour. X * X * Synopsis: background (rect) X * struct Rectangle rect; X * X * Globals: display (r/w) X * back (r) X * X * Calls: bitblt (bitblt.c) X * X * Called by: dellayer (dellayer.c) X */ Xbackground (rect) Xstruct Rectangle rect; X{ X (void) bitblt (NULL, rect, display, rect.origin, &back, S); X} / echo 'x - src/bfree.c' sed 's/^X//' > src/bfree.c << '/' X X/* X * File: bfree.c X * X * Sccs-id: @(#)bfree.c 1.4 85/03/24 X * X * Description: This file contains the one routine bfree which X * frees the storage used by bitmap b. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: bfree X * X * Description: Free the storage used by bitmap b. X * X * Synopsis: bfree (b) X * struct Bitmap *b; X * X * Globals: None. X * X * Calls: free (libc) X * X * Called by: newlayer (newlayer.c) X * dellayer (dellayer.c) X */ Xbfree (b) Xstruct Bitmap *b; X{ X /* X * return storage for bitmap b from whence it came X */ X free ((char *) b -> base); X free ((char *) b); X} / echo 'x - src/intersection.c' sed 's/^X//' > src/intersection.c << '/' X X/* X * File: intersection.c X * X * Sccs-id: @(#)intersection.c 1.5 85/03/24 X * X * Description: This file contains the one function intersect which X * calculates the intersection of the two rectangles r and s. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/22 Moved min and max definitions X * from defines.h to here. X * SCK 1.5 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X#define min(a, b) ((a) < (b) ? (a) : (b)) X#define max(a, b) ((a) > (b) ? (a) : (b)) X X/* X * Name: intersection X * X * Description: Calculate the intersection of the two rectangles r and s. X * X * Synopsis: struct Rectangle intersection (r, s) X * struct Rectangle r; X * struct Rectangle s; X * X * Globals: None. X * X * Calls: Nothing. X * X * Called by: layerop (layerop.c) X */ Xstruct Rectangle intersection (r, s) Xstruct Rectangle r; Xstruct Rectangle s; X{ X struct Rectangle t; X X t.origin.x = max (r.origin.x, s.origin.x); X t.origin.y = max (r.origin.y, s.origin.y); X t.corner.x = min (r.corner.x, s.corner.x); X t.corner.y = min (r.corner.y, s.corner.y); X return (t); X} / echo 'x - src/lbblt.c' sed 's/^X//' > src/lbblt.c << '/' X X/* X * File: lbblt.c X * X * Sccs-id: @(#)lbblt.c 1.4 85/03/24 X * X * Description: This file contains the one function LBblt which X * given a layer l, a rectangle r, a bitmap db, a bitmap sb, X * a function code f and an obscured list o, bitblts using X * the function code f, the rectangular area r from sb into db. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/12/10 Made it work. X * SCK 1.3 85/02/22 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: LBblt X * X * Description: Given a layer l, a rectangle r, a bitmap db, a bitmap sb, X * a function code f and an obscured list o, bitblt using X * the function code f, the rectangular area r from sb into db. X * X * Synopsis: LBblt (l, r, db, o, sb, hb, dp, f) X * struct Layer *l; X * struct Rectangle r; X * struct Bitmap *db; X * struct Obscured *o; X * struct Bitmap *sb; X * struct Bitmap *hb; X * struct Point *dp; X * int *f; X * X * Globals: None. X * X * Calls: rsubp (rsubp.c) X * bitblt (bitblt.c) X * X * Called by: Rlayerop (rlayerop.c) X */ XLBblt (l, r, db, o, sb, hb, dp, f) Xstruct Layer *l; Xstruct Rectangle r; Xstruct Bitmap *db; /* destination bitmap */ Xstruct Obscured *o; Xstruct Bitmap *sb; /* source bitmap */ Xstruct Bitmap *hb; /* halftone bitmap */ Xstruct Point *dp; Xint *f; /* function code */ X{ X struct Rectangle rsubp (); X X (void) bitblt (sb, rsubp (r, *dp), db, r.origin, hb, *f); X} / echo 'x - src/lblt.c' sed 's/^X//' > src/lblt.c << '/' X X/* X * File: lblt.c X * X * Sccs-id: @(#)lblt.c 1.4 85/03/24 X * X * Description: This file contains the one function lblt, which X * provides the bitblt function between and off-screen X * bitmap and a layer. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: lblt X * X * Description: Given a layer l, a bitmap sb, a rectangle r X * and a function code f, copy the off-screen bitmap sb X * to a rectangle r within layer l, using the function code f. X * X * Synopsis: lblt (l, sb, r, hb, pt, f) X * struct Layer *l; X * struct Bitmap *sb; X * struct Rectangle r; X * struct Bitmap *hb; X * struct Point pt; X * int f; X * X * Globals: LBblt () X * X * Calls: layerop (layerop.c) X * raddp (raddp.c) X * X * Called by: This is a top-level function. X * lbitblt (lbitblt.c) X */ Xlblt (l, sb, r, hb, pt, f) Xstruct Layer *l; Xstruct Bitmap *sb; Xstruct Rectangle r; Xstruct Bitmap *hb; Xstruct Point pt; Xint f; X{ X struct Point dp; X X int LBblt (); X struct Rectangle raddp (); X X dp.x = pt.x - r.origin.x; X dp.y = pt.y - r.origin.y; X (void) layerop (l, LBblt, raddp (r, dp), sb, hb, &dp, &f); X} / echo 'x - src/lessthan.c' sed 's/^X//' > src/lessthan.c << '/' X X/* X * File: lessthan.c X * X * Sccs-id: @(#)lessthan.c 1.4 85/03/24 X * X * Description: This file contains the one routine lessthan which X * defines an ordering on the rectangles a and b, X * so that bitblt will be called by lbitblt X * in the correct order. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xextern struct Point delta; X X/* X * Name: lessthan X * X * Description: Define an ordering on the rectangles a and b, X * so that bitblt will be called by lbitblt X * in the correct order. X * X * Synopsis: boolean lessthan (a, b) X * struct Rectangle a; X * struct Rectangle b; X * X * Globals: delta (r) X * X * Calls: Nothing. X * X * Called by: Pass (pass.c) X */ Xboolean lessthan (a, b) Xstruct Rectangle a; Xstruct Rectangle b; X{ X if ((a.origin.y < b.corner.y) && (b.origin.y < a.corner.y)) X return (((a.origin.x - b.origin.x) * delta.x) >= 0); X else X return (((a.origin.y - b.origin.y) * delta.y) >= 0); X} / echo 'x - src/raddp.c' sed 's/^X//' > src/raddp.c << '/' X X/* X * File: raddp.c X * X * Sccs-id: @(#)raddp.c 1.4 85/03/24 X * X * Description: This file contains the one function raddp which X * given a point p and a rectangle r, adds the point X * to the origin of the rectangle. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: raddp X * X * Description: Given a point p and a rectangle r, add the point X * to the origin of the rectangle. X * X * Synopsis: struct Rectangle raddp (r, p) X * struct Rectangle r; X * struct Point p; X * X * Globals: None. X * X * Calls: Nothing. X * X * Called by: lblt (lblt.c) X */ Xstruct Rectangle raddp (r, p) Xstruct Rectangle r; Xstruct Point p; X{ X /* X * add p to r X */ X r.origin.x += p.x; X r.origin.y += p.y; X r.corner.x += p.x; X r.corner.y += p.y; X return (r); X} / echo 'x - src/rectf.c' sed 's/^X//' > src/rectf.c << '/' X X/* X * File: rectf.c X * X * Sccs-id: @(#)rectf.c 1.5 85/03/24 X * X * Description: This file contains the one function rectf which X * performs the function specified by integer code f, X * in a rectangle r, in a bitmap b. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/21 Added STORE after reading X * Rob's latest paper. X * SCK 1.5 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: rectf X * X * Description: Perform the function specified by integer code f, X * in a rectangle r, in a bitmap b. X * X * Synopsis: rectf (b, r, f) X * struct Bitmap *b; X * struct Rectangle r; X * int f; X * X * Globals: None. X * X * Calls: bitblt (bitblt.c) X * X * Called by: newlayer (newlayer.c) X */ Xrectf (b, r, f) Xstruct Bitmap *b; Xstruct Rectangle r; Xint f; X{ X switch (f) { X case CLR: X /* X * clear r to zeros X */ X (void) bitblt (NULL, r, b, r.origin, NULL, ALL_ZEROS); X break; X case OR: X case STORE: X /* X * set r to ones X */ X (void) bitblt (NULL, r, b, r.origin, NULL, ALL_ONES); X break; X case XOR: X /* X * invert bits in r X */ X (void) bitblt (NULL, r, b, r.origin, NULL, ND); X break; X } X} / echo 'x - src/rectxrect.c' sed 's/^X//' > src/rectxrect.c << '/' X X/* X * File: rectxrect.c X * X * Sccs-id: @(#)rectxrect.c 1.4 85/03/24 X * X * Description: This file contains the one function rectXrect which X * tests to see if the two rectangles r and s intersect. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: rectXrect X * X * Description: Test to see if the two rectangles r and s intersect. X * X * Synopsis: boolean rectXrect (r, s) X * struct Rectangle r; X * struct Rectangle s; X * X * Globals: None. X * X * Calls: Nothing. X * X * Called by: newlayer (newlayer.c) X * addobs (addobs.c) X * layerop (layerop.c) X * Rlayerop (Rlayerop.c) X * upfront (upfront.c) X */ Xboolean rectXrect (r, s) Xstruct Rectangle r; Xstruct Rectangle s; X{ X return ((r.origin.x < s.corner.x) && X (s.origin.x < r.corner.x) && X (r.origin.y < s.corner.y) && X (s.origin.y < r.corner.y)); X} / echo 'x - src/rsubp.c' sed 's/^X//' > src/rsubp.c << '/' X X/* X * File: rsubp.c X * X * Sccs-id: @(#)rsubp.c 1.4 85/03/24 X * X * Description: This file contains the one function rsubp which X * given a point p and a rectangle r, subtracts the point X * from the origin of the rectangle. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X X/* X * Name: rsubp X * X * Description: Given a point p and a rectangle r, subtract the point X * from the origin of the rectangle. X * X * Synopsis: struct Rectangle rsubp (r, p) X * struct Rectangle r; X * struct Point p; X * X * Globals: None. X * X * Calls: Nothing. X * X * Called by: LBblt (lbblt.c) X */ Xstruct Rectangle rsubp (r, p) Xstruct Rectangle r; Xstruct Point p; X{ X /* X * subtract p from r X */ X r.origin.x -= p.x; X r.origin.y -= p.y; X r.corner.x -= p.x; X r.corner.y -= p.y; X return (r); X} / echo 'x - src/screenswap.c' sed 's/^X//' > src/screenswap.c << '/' X X/* X * File: screenswap.c X * X * Sccs-id: @(#)screenswap.c 1.4 85/03/24 X * X * Description: This file contains the one function screenswap which X * interchanges the data in the bitmap b with the contents X * of the rectangle r on the screen. X * X * Author: Simon Kenyon. X * X * History: SCK 1.1 83/10/03 Created. X * SCK 1.2 84/11/29 Made it work. X * SCK 1.3 85/03/04 Tidied up for release. X * SCK 1.4 85/03/24 Changed the include files around. X */ X X#include "../h/layers.h" X Xextern struct Bitmap *display; X X/* X * Name: screenswap X * X * Description: Interchange the data in the bitmap b with the contents X * of the rectangle r on the screen. X * X * Synopsis: screenswap (b, r) X * struct Bitmap *b; X * struct Rectangle r; X * X * Globals: display (r/w) X * X * Calls: bitblt (bitblt.c) X * X * Called by: upfront (upfront.c) X */ Xscreenswap (b, r) Xstruct Bitmap *b; Xstruct Rectangle r; X{ X /* X * implemented, without auxialiary storage, using three X * calls to bitblt() with function code XOR X */ X (void) bitblt (display, r, b, r.origin, NULL, S_XOR_D); X (void) bitblt (b, r, display, r.origin, NULL, S_XOR_D); X (void) bitblt (display, r, b, r.origin, NULL, S_XOR_D); X} / echo 'Part 04 of jerq layers code complete.' exit