EdgeBlt.mesa
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
Frank Crow, June 12, 1987 3:49:32 pm PDT
A general-purpose Bresenham incrementer.
DIRECTORY
Rope     USING [ ROPE ];
EdgeBlt: CEDAR DEFINITIONS
~ BEGIN
Type Definitions
EdgeDesc: TYPE ~ RECORD[
val: INT32,     -- current value for incrementation, byte address or value
stepsLeft: WORD ← 0,  -- number of increments remaining
length: WORD ← 0,   -- total number of increments to make 
hiccups: WORD ← 0,   -- number of offsets (hiccups) to make
lngthIncr: INTEGER ← 0, -- amount to increment by
hicIncr: INTEGER ← 0,  -- amount to offset at hiccup
bias: INTEGER ← 0,   -- change to number of increments to first offset (for wizards)
indirect: BOOLEANTRUE, -- incrementing addresses if TRUE, else values
nextEdge: CARD16 ← 0 -- next edge if part of a chain of edges (index in Sequence)
];
EdgeSequence: TYPE ~ RECORD [length: NAT ← 0,
          s: SEQUENCE maxLength: NAT OF EdgeBlt.EdgeDesc ];
         
EdgeBltOptions: TYPE ~ RECORD[
includeStart: BOOLTRUE,   -- include start point
includeEnd: BOOLTRUE    -- include endpoint
];
defaultOptions: EdgeBltOptions ~ [TRUE, TRUE];
EdgeBltTable: TYPE ~ RECORD[
dst, src: EdgeDesc,
options: EdgeBltOptions ← defaultOptions
];
EdgeBltError: SIGNAL [reason: ErrorDesc];
ErrorDesc: TYPE ~ RECORD [code: ATOM, explanation: Rope.ROPE];
Basic Procedures
The fractional increment Dy/Dx must be added to y for every new position x. Whenever the fraction overflows, y is incremented, effectively subtracting 1 from the fraction. By removing the fractional part from y, we can instead increment by Dy until Dx is reached. To center the positions of the y-increments along x, the incrementation by Dy should be started at Dx/2. To further simplify, decrement by 2Dy and start at Dx, testing for < 0. In the following read Dx as longSize and Dy as shortSize.
Incr: PROC[edge: EdgeDesc, array: REF EdgeSequence ← NIL] RETURNS[EdgeDesc];
Increments EdgeDesc once unless runToHiccup is set
Blt: PROC[ebt: EdgeBltTable];
END.