-- FontImpl.mesa
-- Last changed by Doug Wyatt, September 7, 1980 1:00 PM

DIRECTORY
Font,
Memory USING [zone, mds],
StringDefs USING [AppendString, CompareStrings, UpperCase];

FontImpl: PROGRAM
IMPORTS Memory,StringDefs
EXPORTS Font = {
OPEN Font;

zone: UNCOUNTED ZONE = Memory.zone;
mds: MDSZone = Memory.mds;

FNode: TYPE = RECORD [
link: FNodeRef,
fam: Fam,
family: STRING
];
FNodeRef: TYPE = LONG POINTER TO FNode;

flist: FNodeRef←NIL;

NewFam: PROCEDURE[family: STRING] RETURNS[Fam] = {
fam: Fam=(IF flist=NIL THEN 1 ELSE flist.fam+1);
flist←zone.NEW[FNode ← [link: flist, fam: fam,
family: CopyStringUC[family]]];
RETURN[fam];
};

CopyStringUC: PROCEDURE[s: STRING] RETURNS[STRING] = {
ucs: STRING=mds.NEW[StringBody[s.length]];
FOR i: CARDINAL IN[0..s.length) DO
ucs[i]←StringDefs.UpperCase[s[i]];
ENDLOOP;
ucs.length←s.length;
RETURN[ucs];
};

EncodeFam: PUBLIC PROC[family: STRING] RETURNS[Fam] = {
FOR f: FNodeRef ← flist, f.link UNTIL f=NIL DO
IF StringDefs.CompareStrings[family,f.family]=0 THEN
RETURN[f.fam]
ENDLOOP;
RETURN[NewFam[family]];
};

DecodeFam: PUBLIC PROC[fam: Fam, family: STRING] = {
FOR f: FNodeRef ← flist, f.link UNTIL f=NIL DO
IF f.fam=fam THEN {
StringDefs.AppendString[family,f.family]; RETURN
};
ENDLOOP;
};

EncodeFace: PUBLIC PROC[w: Weight, s: Slope, e: Expansion]
RETURNS[Face] = {
RETURN[
(SELECT s FROM italic=>1, ENDCASE=>0)+
(SELECT w FROM bold=>2, light=>4, ENDCASE=>0)+
(SELECT e FROM condensed=>6, expanded=>12, ENDCASE=>0)]
};

EncodeTexFace: PUBLIC PROC[halfPoints: [0..200]]
RETURNS[Face] = {
RETURN[54+halfPoints]
};

DecodeFace: PUBLIC PROC[f: Face]
RETURNS[w: Weight, s: Slope, e: Expansion] = {
w←medium; s←regular; e←regular;
IF f<54 THEN {
SELECT (f MOD 2) FROM 1=>s←italic; ENDCASE; f←f/2;
SELECT (f MOD 3) FROM 1=>w←bold; 2=>w←light; ENDCASE; f←f/3;
SELECT (f MOD 3) FROM 1=>e←condensed; 2=>e←expanded; ENDCASE;
};
RETURN[w,s,e];
};

DecodeTexFace: PUBLIC PROC[f: Face]
RETURNS[halfPoints: [0..200]] = {
IF f IN[54..254] THEN RETURN[f-54] ELSE RETURN[0];
};

}.