<> <> <> <> <<>> DIRECTORY Basics USING [ BITSHIFT, BytePair, DoubleAnd, DoubleShiftRight, LongNumber ], EdgeBlt USING [ EdgeBltTable, EdgeBltOptions, EdgeDesc,EdgeSequence, ErrorDesc ]; EdgeBltImpl: CEDAR PROGRAM IMPORTS Basics EXPORTS EdgeBlt ~ BEGIN <> LongNumber: TYPE ~ Basics.LongNumber; BytePair: TYPE ~ Basics.BytePair; EdgeDesc: TYPE ~ EdgeBlt.EdgeDesc; <> <> <> <> <> <> <> <> <> <> <<];>> EdgeSequence: TYPE ~ EdgeBlt.EdgeSequence; <> EdgeBltTable: TYPE ~ EdgeBlt.EdgeBltTable; EdgeBltOptions: TYPE ~ EdgeBlt.EdgeBltOptions; EdgeBltError: PUBLIC SIGNAL [reason: EdgeBlt.ErrorDesc] = 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 EdgeBltError[[$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.