MODULE CharSet; IMPORT Text, R2, PS, Type, TypeLinesC, TypeLinesR; PRIVATE CONST Rows = 16, Cols = 16, XBorder = 3, YBorder = 2; /* "Rows" and "Cols" specify the total number of rows and columns of the grid. "XBorder" and "YBorder" specify the amount of horizontal and vertical space, respectively, to leave on each side of the widest/tallest character in the font. */ PRIVATE PROC w := MaxCharWidth() IS w := 0; VAR i = 0 IN DO i < 256 -> w := MAX(w, PS.StringWidth(Text.FromChar(i))); i := i + 1 OD END END; /* Set "w" to the width of the widest character in the current font at the current font size. */ PROC Show(p) IS SAVE PS IN PS.SetWidth(1); VAR row, col, h, asc, dec, w IN w := MaxCharWidth() + 2 * XBorder; asc, dec := PS.FontHeight(); h := asc + dec + 2 * YBorder; p := R2.Plus(p, (-w * Rows / 2, h * Cols / 2)); row := 0; DO row < Rows -> col := 0; DO col < Cols -> ShowChar(p, asc, w, h, row, col); col := col + 1 OD; GridLines(p, w, h, row); row := row + 1 OD; GridLines(p, w, h, Rows); ShowCodes(p, w, h) END END END; UI PointTool(Show); (* Display a 16 x 16 grid centered at "p"; the grid contains the 256 characters of the current font, rendered in the current size. *) PRIVATE PROC ShowChar(p, asc, w, h, row, col) IS VAR c, dx, dy IN c := Text.FromChar(col + row * Cols); dx := w * (col + 0.5); dy := -(row * h + YBorder + asc); p := R2.Plus(p, (dx, dy)); Type.C(p, c) END END; PRIVATE PROC GridLines(p, w, h, i) IS PS.MoveTo((CAR(p) + i * w, CDR(p))); PS.LineTo((CAR(p) + i * w, CDR(p) - h * Rows)); PS.MoveTo((CAR(p), CDR(p) - i * h)); PS.LineTo((CAR(p) + w * Cols, CDR(p) - i * h)); PS.Stroke() END; PRIVATE PROC ShowCodes(p, w, h) IS SAVE PS IN PS.SetFontFace("Helvetica"); ShowHCodes(p, w); ShowVCodes(p, h) END END; PRIVATE PROC ShowHCodes(p, w) IS VAR i = 0, q IN DO i < Cols -> q := R2.Plus(p, (w / 2 + w * i, 0)); TypeLinesC.South(q, HexChar(i)); i := i + 1 OD END END; PRIVATE PROC ShowVCodes(p, h) IS VAR i = 0, q IN DO i < Rows -> q := R2.Minus(p, (5, h / 2 + h * i)); TypeLinesR.East(q, HexChar(i)); i := i + 1 OD END END; PRIVATE VAR Zero := Text.GetChar("0", 0), A := Text.GetChar("A", 0); PRIVATE PROC txt := HexChar(i) IS IF 0 <= i AND i < 10 -> txt := Text.FromChar(Zero + i) | 10 <= i AND i < 16 -> txt := Text.FromChar(A + (i - 10)) FI END;