Fonts.Mod.txt 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. MODULE Fonts; (*JG 18.11.90; PDR 8.6.12; NW 18.1.2019*)
  2. IMPORT SYSTEM, Files;
  3. CONST FontFileId = 0DBH;
  4. TYPE Font* = POINTER TO FontDesc;
  5. FontDesc* = RECORD
  6. name*: ARRAY 32 OF CHAR;
  7. height*, minX*, maxX*, minY*, maxY*: INTEGER;
  8. next*: Font;
  9. T: ARRAY 128 OF INTEGER;
  10. raster: ARRAY 2360 OF BYTE
  11. END ;
  12. LargeFontDesc = RECORD (FontDesc) ext: ARRAY 2560 OF BYTE END ;
  13. LargeFont = POINTER TO LargeFontDesc;
  14. RunRec = RECORD beg, end: BYTE END ;
  15. BoxRec = RECORD dx, x, y, w, h: BYTE END ;
  16. (* raster sizes: Syntax8 1367, Syntax10 1628, Syntax12 1688, Syntax14 1843, Syntax14b 1983,
  17. Syntax16 2271, Syntax20 3034, Syntac24 4274, Syntax24b 4302 *)
  18. VAR Default*, root*: Font;
  19. PROCEDURE GetPat*(fnt: Font; ch: CHAR; VAR dx, x, y, w, h, patadr: INTEGER);
  20. VAR pa: INTEGER; dxb, xb, yb, wb, hb: BYTE;
  21. BEGIN pa := fnt.T[ORD(ch) MOD 80H]; patadr := pa;
  22. SYSTEM.GET(pa-3, dxb); SYSTEM.GET(pa-2, xb); SYSTEM.GET(pa-1, yb); SYSTEM.GET(pa, wb); SYSTEM.GET(pa+1, hb);
  23. dx := dxb; x := xb; y := yb; w := wb; h := hb;
  24. IF yb < 128 THEN y := yb ELSE y := yb - 256 END
  25. END GetPat;
  26. PROCEDURE This*(name: ARRAY OF CHAR): Font;
  27. VAR F: Font; LF: LargeFont;
  28. f: Files.File; R: Files.Rider;
  29. NofRuns, NofBoxes: BYTE;
  30. NofBytes: INTEGER;
  31. height, minX, maxX, minY, maxY: BYTE;
  32. i, j, k, m, n: INTEGER;
  33. a, a0: INTEGER;
  34. b, beg, end: BYTE;
  35. run: ARRAY 16 OF RunRec;
  36. box: ARRAY 512 OF BoxRec;
  37. PROCEDURE RdInt16(VAR R: Files.Rider; VAR b0: BYTE);
  38. VAR b1: BYTE;
  39. BEGIN Files.ReadByte(R, b0); Files.ReadByte(R, b1)
  40. END RdInt16;
  41. BEGIN F := root;
  42. WHILE (F # NIL) & (name # F.name) DO F := F.next END;
  43. IF F = NIL THEN
  44. f := Files.Old(name);
  45. IF f # NIL THEN
  46. Files.Set(R, f, 0); Files.ReadByte(R, b);
  47. IF b = FontFileId THEN
  48. Files.ReadByte(R, b); (*abstraction*)
  49. Files.ReadByte(R, b); (*family*)
  50. Files.ReadByte(R, b); (*variant*)
  51. RdInt16(R, height); RdInt16(R, minX); RdInt16(R, maxX); RdInt16(R, minY); RdInt16(R, maxY); RdInt16(R, NofRuns);
  52. NofBoxes := 0; k := 0;
  53. WHILE k # NofRuns DO
  54. RdInt16(R, beg);
  55. run[k].beg := beg; RdInt16(R, end);
  56. run[k].end := end; NofBoxes := NofBoxes + end - beg; INC(k)
  57. END;
  58. NofBytes := 5; j := 0;
  59. WHILE j # NofBoxes DO
  60. RdInt16(R, box[j].dx); RdInt16(R, box[j].x); RdInt16(R, box[j].y);
  61. RdInt16(R, box[j].w); RdInt16(R, box[j].h);
  62. NofBytes := NofBytes + 5 + (box[j].w + 7) DIV 8 * box[j].h;
  63. INC(j)
  64. END;
  65. IF NofBytes < 2300 THEN NEW(F) ELSE NEW(LF); F := LF END ;
  66. F.name := name;
  67. F.height := height; F.minX := minX; F.maxX := maxX; F.maxY := maxY;
  68. IF minY >= 80H THEN F.minY := minY - 100H ELSE F.minY := minY END ;
  69. a0 := SYSTEM.ADR(F.raster);
  70. SYSTEM.PUT(a0, 0X); SYSTEM.PUT(a0+1, 0X); SYSTEM.PUT(a0+2, 0X); SYSTEM.PUT(a0+3, 0X); SYSTEM.PUT(a0+4, 0X);
  71. (*null pattern for characters not in a run*)
  72. INC(a0, 3); a := a0+2; j := 0; k := 0; m := 0;
  73. WHILE k < NofRuns DO
  74. WHILE (m < run[k].beg) & (m < 128) DO F.T[m] := a0; INC(m) END;
  75. WHILE (m < run[k].end) & (m < 128) DO
  76. F.T[m] := a+3;
  77. SYSTEM.PUT(a, box[j].dx); SYSTEM.PUT(a+1, box[j].x); SYSTEM.PUT(a+2, box[j].y);
  78. SYSTEM.PUT(a+3, box[j].w); SYSTEM.PUT(a+4, box[j].h); INC(a, 5);
  79. n := (box[j].w + 7) DIV 8 * box[j].h;
  80. WHILE n # 0 DO DEC(n); Files.ReadByte(R, b); SYSTEM.PUT(a, b); INC(a) END ;
  81. INC(j); INC(m)
  82. END;
  83. INC(k)
  84. END;
  85. WHILE m < 128 DO F.T[m] := a0; INC(m) END ;
  86. F.next := root; root := F
  87. ELSE (*bad file id*) F := Default
  88. END
  89. ELSE (*font file not available*) F := Default
  90. END
  91. END;
  92. RETURN F
  93. END This;
  94. PROCEDURE Free*; (*remove all but first two from font list*)
  95. BEGIN IF root.next # NIL THEN root.next.next := NIL END
  96. END Free;
  97. BEGIN root := NIL; Default := This("Oberon10.Scn.Fnt")
  98. END Fonts.