MODULE Line;(* simple direct screen drawing procedures: line, dot, clear *)(* see TestLine.Mod for a sample *) IMPORT Display, Out; VAR tViewOriginX*, tViewOriginY*: INTEGER; tViewX1*, tViewY1*, tViewX2*, tViewY2*: INTEGER; tXUnit*, tYUnit*: REAL; (* unit on x-,y-axis *) Done: BOOLEAN; PROCEDURE Init*( ScreenWidth, ScreenHeight, ViewX1, ViewY1, ViewX2, ViewY2, ViewOriginX, ViewOriginY, UserWidth, UserHeight: INTEGER): BOOLEAN;(* Initialization of the ScreenTransformation *) BEGIN Done:=TRUE; tViewOriginX:=ViewOriginX; tViewOriginY:=ViewOriginY; tViewX1:=ViewX1; tViewY1:=ViewY1; tViewX2:=ViewX2; tViewY2:=ViewY2; tXUnit:=(ViewX2-ViewX1)/UserWidth; tYUnit:=(ViewY2-ViewY1)/UserHeight; (* Tests *) IF (ViewX2-ViewX1)<0 THEN Out.String("#TwoD.Init: ViewWidth error"); Out.Ln; Done:=FALSE; END; IF (ViewY1-ViewY2)<0 THEN Out.String("#TwoD.Init: ViewHeight error"); Out.Ln; Done:=FALSE; END; IF ViewX1<0 THEN Out.String("#TwoD.Init: ViewX1<0"); Out.Ln; Done:=FALSE; END; IF ViewY1>ScreenHeight THEN Out.String("#TwoD.Init: ViewY1 too big"); Out.Ln; Done:=FALSE; END; IF ViewY2<0 THEN Out.String("#TwoD.Init: ViewY2<0"); Out.Ln; Done:=FALSE; END; IF ViewX2>ScreenWidth THEN Out.String("#TwoD.Init: ViewX2 too big"); Out.Ln; Done:=FALSE; END; RETURN Done; END Init; PROCEDURE Line*(x1, y1, x2, y2, color, mode: INTEGER);(* draws a line (x1,y1)-(x2,y2) *) (* Draws a line into frame F from (x1,y1) to (x2,y2) with the specified color and mode *) VAR dx, dy, sx, sy, d, x, y: INTEGER; BEGIN x := x2 - x1; y := y2 - y1; IF x > 0 THEN sx := 1 ELSE sx := -1 END; IF y > 0 THEN sy := 1 ELSE sy := -1 END; dx := ABS(x); dy := ABS(y); x := x1; y := y1; IF dx > dy THEN d := 2 * dy - dx; Display.Dot(color, x, y, mode); WHILE x # x2 DO IF (d > 0) OR ((d = 0) & (sy = 1)) THEN y := y + sy; d := d - 2 * dx; END; x := x + sx; d := d + 2 * dy; Display.Dot(color, x, y, mode); END; ELSE d := 2 * dx - dy; Display.Dot(color, x, y, mode); WHILE y # y2 DO IF (d > 0) OR ((d = 0) & (sx = 1)) THEN x := x + sx; d := d - 2 * dy; END; y := y + sy; d := d + 2 * dx; Display.Dot(color, x, y, mode); END; END; END Line; PROCEDURE Dot* (x, y, color, mode: INTEGER); (* draws a dot *) BEGIN Display.Dot(color, x, y, mode); END Dot; PROCEDURE Clear*(x, y, w, h: INTEGER); BEGIN Display.ReplConst(Display.black, x, y, w, h, Display.replace); END Clear; PROCEDURE Transform*(x, y: REAL; VAR sx, sy: INTEGER); (* Transforms the user-coordinates (x, y) to screen-coordinates (sx, sy) *) BEGIN sx:=SHORT(ENTIER(tViewOriginX+tXUnit*x)); sy:=SHORT(ENTIER(tViewOriginY-tYUnit*y)); END Transform; BEGIN END Line.