MODULE PtLabel; (* Module for annotating points in a drawing for inclusion in figures. *) IMPORT R2, PS, Circle; CONST DefaultDotSize = 2; PRIVATE VAR dotSize := DefaultDotSize; (* This module maintains a ``current dot size'', which is the radius of the dot drawn to label a point. The dot size is measured in points. *) PROC SetDotSize(sz) IS dotSize := sz END; UI SetTool(SetDotSize); (* Set the current dot size to "sz". *) UI Param(SetDotSize, DefaultDotSize); UI Param(SetDotSize, 0); UI Param(SetDotSize, 0.5); UI Param(SetDotSize, 1); UI Param(SetDotSize, 1.5); UI Param(SetDotSize, 2); UI Param(SetDotSize, 2.5); UI Param(SetDotSize, 3); UI Param(SetDotSize, 4); UI Param(SetDotSize, 5); PROC sz := GetDotSize() IS sz := dotSize END; (* Set "sz" to the current dot size. *) CONST DefaultOffset = 5; (* This module maintains a label offset, which is the size in points of any extra horizontal and vertical space inserted between a point and its label. *) PRIVATE VAR horOffset := DefaultOffset, verOffset := DefaultOffset; /* The current label offset. We maintain both a horizontal and vertical offset in case we want to generalize the interface to make a distinction between them in the future. */ PROC SetOffset(sz) IS horOffset := sz; verOffset := sz END; UI SetTool(SetOffset); (* Set the current label offset to "sz" points. *) UI Param(SetOffset, DefaultOffset); UI Param(SetOffset, 0); UI Param(SetOffset, 2); UI Param(SetOffset, 4); UI Param(SetOffset, 6); UI Param(SetOffset, 8); UI Param(SetOffset, 10); PROC sz := GetOffset() IS sz := horOffset END; (* Set "sz" to the current label offset in points. *) PRIVATE PROC DrawDot(p) IS IF dotSize > 0 -> Circle.Draw(p, R2.Plus(p, (dotSize, 0))); PS.Fill() | SKIP FI END; /* Draw a round dot with diameter "dotSize" at the point "p". This procedure does not preserve the PostScript state. */ PROC None(p) IS SAVE PS IN DrawDot(p) END END; (* Draw a dot at "p" in the current dot size. *) UI PointTool(None); PROC SW(p, txt) IS SAVE PS IN DrawDot(p); VAR asc, dec, w IN asc, dec := PS.FontHeight(); w := PS.StringWidth(txt); PS.Type(R2.Minus(p, (w + horOffset, asc)), txt) END END END; PROC NW(p, txt) IS SAVE PS IN DrawDot(p); VAR asc, dec, w IN asc, dec := PS.FontHeight(); w := PS.StringWidth(txt); PS.Type(R2.Plus(p, (-w - horOffset, dec + verOffset)), txt) END END END; PROC SE(p, txt) IS SAVE PS IN DrawDot(p); VAR asc, dec IN asc, dec := PS.FontHeight(); PS.Type(R2.Plus(p, (verOffset, -asc)), txt) END END END; PROC NE(p, txt) IS SAVE PS IN DrawDot(p); VAR asc, dec IN asc, dec := PS.FontHeight(); PS.Type(R2.Plus(p, (horOffset, verOffset + dec)), txt) END END END; PROC East(p, txt) IS SAVE PS IN DrawDot(p); VAR asc, dec IN asc, dec := PS.FontHeight(); PS.Type(R2.Plus(p, (2 * horOffset, (dec - asc) / 2)), txt) END END END; PROC West(p, txt) IS SAVE PS IN DrawDot(p); VAR asc, dec, w IN w := PS.StringWidth(txt); asc, dec := PS.FontHeight(); PS.Type(R2.Plus(p, (-w - 2 * horOffset, (dec - asc) / 2)), txt) END END END; PROC North(p, txt) IS SAVE PS IN DrawDot(p); VAR asc, dec, w IN w := PS.StringWidth(txt); asc, dec := PS.FontHeight(); PS.Type(R2.Plus(p, (-w / 2, dec + verOffset)), txt) END END END; PROC South(p, txt) IS SAVE PS IN DrawDot(p); VAR asc, dec, w IN w := PS.StringWidth(txt); asc, dec := PS.FontHeight(); PS.Type(R2.Plus(p, (-w / 2, -asc - verOffset)), txt) END END END; UI TextTool(SW); UI TextTool(NW); UI TextTool(SE); UI TextTool(NE); UI TextTool(East); UI TextTool(West); UI TextTool(North); UI TextTool(South); (* Draw a dot at "p" with label "txt". The dot is drawn in the current dot size. In each case, the name of the procedure indicates the location of the label relative to the dot. Both the dot and the label are drawn in the current color. *) PRIVATE VAR history := NIL; PROC Save() IS history := ([dotSize, horOffset, verOffset], history) END; PROC Restore() IS VAR head IN head := CAR(history); dotSize := CAR(head); horOffset := CAR(CDR(head)); verOffset := CAR(CDR(CDR(head))) END; history := CDR(history) END; UI PointTool(Save); UI PointTool(Restore); (* Save/restore the current dot size and offsets. *)