<> <> <> DIRECTORY IPFont USING [FontKey, FontKeyRep], IPImagerBasic USING [Transformation], IPTransform USING [Concat, Scale], Rope USING [Equal, ROPE]; IPFontImpl: CEDAR MONITOR IMPORTS IPTransform, Rope EXPORTS IPFont = BEGIN OPEN IPImagerBasic, IPFont; ROPE: TYPE = Rope.ROPE; fontList: FontKey _ NIL; EqualT: PROC[t1, t2: Transformation] RETURNS[BOOL] = { RETURN[t1.a=t2.a AND t1.b=t2.b AND t1.c=t2.c AND t1.d=t2.d AND t1.e=t2.e AND t1.f=t2.f] }; Lookup: ENTRY PROC[name: ROPE, m: Transformation] RETURNS[FontKey] = { FOR key: FontKey _ fontList, key.link UNTIL key=NIL DO IF Rope.Equal[name, key.name, FALSE] AND EqualT[m, key.m] THEN RETURN[key]; ENDLOOP; RETURN[fontList _ NEW[FontKeyRep _ [link: fontList, name: name, m: m]]]; }; identity: Transformation = IPTransform.Scale[1]; New: PUBLIC PROC[name: ROPE] RETURNS[FontKey] = { RETURN[Lookup[name, identity]]; }; Modify: PUBLIC PROC[f: FontKey, m: Transformation] RETURNS[FontKey] = { RETURN[Lookup[f.name, IF f.m=identity THEN m ELSE IPTransform.Concat[m, f.m]]]; }; END.