DIRECTORY Basics, G3dEdgeBlt, Rope; G3dEdgeBltImpl: CEDAR PROGRAM IMPORTS Basics EXPORTS G3dEdgeBlt ~ BEGIN LongNumber: TYPE ~ Basics.LongNumber; BytePair: TYPE ~ Basics.BytePair; ROPE: TYPE ~ Rope.ROPE; EdgeDesc: TYPE ~ G3dEdgeBlt.EdgeDesc; EdgeSequence: TYPE ~ G3dEdgeBlt.EdgeSequence; EdgeBltTable: TYPE ~ G3dEdgeBlt.EdgeBltTable; EdgeBltOptions: TYPE ~ G3dEdgeBlt.EdgeBltOptions; Error: PUBLIC SIGNAL [code: ATOM, reason: ROPE] = CODE; longZero: LongNumber ~ [lc[0]]; longOne: LongNumber ~ [lc[1]]; Incr: PUBLIC PROC[edge: EdgeDesc, array: REF EdgeSequence _ NIL] RETURNS[EdgeDesc] ~ { edge.val _ edge.val + edge.lngthIncr; edge.bias _ edge.bias - 2*edge.hiccups; IF edge.bias <= 0 THEN { edge.val _ edge.val + edge.hicIncr; edge.bias _ edge.bias + 2*edge.length; }; edge.stepsLeft _ edge.stepsLeft - 1; IF edge.stepsLeft <= 0 -- Get next linked edge if this one exhausted THEN IF edge.nextEdge # 0 THEN edge _ array[edge.nextEdge]; RETURN[edge]; }; InlineIncr: PROC[edge: EdgeDesc, array: REF EdgeSequence _ NIL] RETURNS[EdgeDesc] ~ INLINE { edge.val _ edge.val + edge.lngthIncr; edge.bias _ edge.bias - 2*edge.hiccups; IF edge.bias <= 0 THEN { edge.val _ edge.val + edge.hicIncr; edge.bias _ edge.bias + 2*edge.length; }; edge.stepsLeft _ edge.stepsLeft - 1; IF edge.stepsLeft <= 0 -- Get next linked edge if this one exhausted THEN IF edge.nextEdge # 0 THEN edge _ array[edge.nextEdge]; RETURN[edge]; }; Blt: PUBLIC PROC[ebt: EdgeBltTable] ~ { DoByte: PROC[] ~ INLINE { dstAddr: LONG POINTER _ LOOPHOLE[Basics.DoubleShiftRight[LOOPHOLE[dst.val], 1]]; srcValue: BYTE; IF src.indirect THEN TRUSTED { -- get lo byte of word srcAddr: LONG POINTER _ LOOPHOLE[Basics.DoubleShiftRight[LOOPHOLE[src.val], 1]]; srcValue _ LOOPHOLE[srcAddr^, BytePair].low } ELSE srcValue _ LOOPHOLE[src.val, LongNumber.bytes].ll; -- lo byte, lo half of long IF Basics.DoubleAnd[LOOPHOLE[dst.val], longOne] # longZero -- lo byte? (right pixel) THEN TRUSTED { LOOPHOLE[dstAddr^, BytePair].low _ srcValue; } -- right pixel ELSE TRUSTED { LOOPHOLE[dstAddr^, BytePair].high _ srcValue; }; -- left pixel }; dst: EdgeDesc _ ebt.dst; src: EdgeDesc _ ebt.src; options: EdgeBltOptions _ ebt.options; IF NOT dst.indirect THEN Error[$Fatal, "Destination value must be address"]; dst.bias _ dst.bias + dst.length; -- initial bias to center hiccups src.bias _ src.bias + src.length; dst.stepsLeft _ dst.length; -- set stepsLeft for count down src.stepsLeft _ src.length; IF options.includeStart THEN DoByte[]; FOR i: CARDINAL IN (0 .. dst.length) DO dst _ InlineIncr[dst]; IF src.length > 0 THEN src _ InlineIncr[src]; DoByte[]; ENDLOOP; IF options.includeEnd THEN { dst _ InlineIncr[dst]; IF src.length > 0 THEN src _ InlineIncr[src]; DoByte[]; }; }; END. nG3dEdgeBltImpl.mesa Copyright Σ 1987 by Xerox Corporation. All rights reserved. Frank Crow, July 2, 1987 4:01:00 pm PDT A general-purpose Bresenham incrementer. Type Definitions 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: BOOLEAN _ TRUE, -- incrementing addresses if TRUE, else values nextEdge: CARD16 _ 0 -- next edge if part of a chain of edges (index in Sequence) ]; RECORD [length: NAT _ 0, s: SEQUENCE maxLength: NAT OF EdgeDesc]; Constants Basic Procedures The fractional increment Dx/Dy 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. Κ/˜™J™™JMšœ œ !™7Mšœœ &™:Mšœ œ '™;Mšœ œ ™1Mšœ œ ™4Mšœœ ?™TMšœ œœ .™HMšœ œ <™QM™——šœœ˜0Mš œ œ œ œœ ™B—Iašœœ˜0Nšœœ˜5Jš œ œœœ œœ˜<—šž ™ Mšœœ˜Mšœœ˜—šž™MšœΟgœ‘œΥ‘œ‘œZ‘œ‘œ)‘œ‘œ+‘œ‘œ™ψš Οnœœœœœœ˜VM˜%M˜'šœœ˜M˜#M˜&M˜—Mšœ#˜$šœ -˜KMšœœœ˜;—Mšœ˜ M˜—š ’ œœœœœ œ˜aM˜%M˜'šœœ˜M˜#M˜&M˜—Mšœ#˜$šœ -˜KMšœœœ˜;—Mšœ˜ M˜—š’œ œ˜'š’œœœ˜Mš œ œœœœ˜PMšœ œ˜šœ ˜šœœ ˜1Mš œ œœœœ˜PMšœ œ˜,M˜—Mšœ  œ œ ˜S—šœœ ˜TMš œœœ  ˜OMšœœœ*  ˜O—M˜—M˜M˜M˜'Mšœœœ4˜LMšœ# !˜DM˜!Mšœ ˜>M˜Mšœœ ˜&šœœœ˜'Mšœœœ$˜TMšœ˜—šœœ˜Mšœœœ&˜VM˜—M˜—M˜—Jšœ˜—…— ₯