<> <> <> <<>> DIRECTORY ImagerFont USING [Char, CharSet, Class, CorrectionType, Extents, Font, FontRep, nullChar, OptionalReal], ImagerTransformation USING [Scale, Transformation], Prop USING [Get, Put], RefText USING [Map], Rope USING [ActionType, Map, ROPE], SymTab USING [Create, Fetch, Ref, Store], Vector2 USING [VEC]; ImagerFontImpl: CEDAR MONITOR IMPORTS ImagerTransformation, Prop, RefText, Rope, SymTab EXPORTS ImagerFont ~ BEGIN ROPE: TYPE ~ Rope.ROPE; VEC: TYPE ~ Vector2.VEC; Transformation: TYPE ~ ImagerTransformation.Transformation; Font: TYPE ~ ImagerFont.Font; FontRep: TYPE ~ ImagerFont.FontRep; <> <> <> <> <> Class: TYPE ~ ImagerFont.Class; Char: TYPE ~ ImagerFont.Char; -- CARDINAL nullChar: Char ~ ImagerFont.nullChar; CharSet: TYPE ~ ImagerFont.CharSet; CorrectionType: TYPE ~ ImagerFont.CorrectionType; -- {none, space, mask}; Extents: TYPE ~ ImagerFont.Extents; -- RECORD[leftExtent, rightExtent, descent, ascent: REAL]; OptionalReal: TYPE ~ ImagerFont.OptionalReal; -- RECORD[exists: BOOLEAN, value: REAL]; identityTransformation: Transformation ~ ImagerTransformation.Scale[1]; FindVal: TYPE ~ REF FindValRep; FindValRep: TYPE ~ RECORD[ name: ROPE, -- font name file: ROPE, -- file name create: PROC[ROPE] RETURNS[Font], -- creation proc locked: BOOL _ FALSE, -- true a Find is in progress font: Font _ NIL -- font, once created ]; findTab: SymTab.Ref ~ SymTab.Create[mod: 101, case: FALSE]; aliasTab: SymTab.Ref ~ SymTab.Create[mod: 17, case: FALSE]; Register: PUBLIC PROC[name: ROPE, file: ROPE, create: PROC[ROPE] RETURNS[Font]] ~ { val: FindVal ~ NEW[FindValRep _ [name: name, file: file, create: create]]; [] _ SymTab.Store[x: findTab, key: name, val: val]; }; Alias: PUBLIC PROC[alias: ROPE, for: ROPE] ~ { [] _ SymTab.Store[x: aliasTab, key: alias, val: for]; }; released: CONDITION; Acquire: ENTRY PROC[val: FindVal] ~ { WHILE val.locked DO WAIT released ENDLOOP; val.locked _ TRUE; }; Release: ENTRY PROC[val: FindVal] ~ { val.locked _ FALSE; BROADCAST released; }; Find: PUBLIC PROC[name: ROPE] RETURNS[Font] ~ { found: BOOL; ref: REF; [found, ref] _ SymTab.Fetch[x: findTab, key: name]; IF found THEN { val: FindVal ~ NARROW[ref]; Acquire[val]; IF val.font=NIL THEN { val.font _ val.create[val.file ! UNWIND => Release[val]]; val.font.name _ val.name; }; Release[val]; RETURN[val.font]; }; [found, ref] _ SymTab.Fetch[x: aliasTab, key: name]; IF found THEN RETURN[Find[NARROW[ref]]]; RETURN[NIL]; }; Modify: PUBLIC PROC[font: Font, m: Transformation] RETURNS[Font] ~ { RETURN[font.class.Modify[font, m]]; }; Scale: PUBLIC PROC[font: Font, s: REAL] RETURNS[Font] ~ { RETURN[font.class.Modify[font, ImagerTransformation.Scale[s]]]; }; Contains: PUBLIC PROC[font: Font, char: Char] RETURNS[BOOL] ~ { RETURN[font.class.Contains[font, char]]; }; NextChar: PUBLIC PROC[font: Font, char: Char] RETURNS[next: Char] ~ { RETURN[font.class.NextChar[font, char]]; }; BoundingBox: PUBLIC PROC[font: Font, char: Char] RETURNS[Extents] ~ { RETURN[font.class.BoundingBox[font, char]]; }; Width: PUBLIC PROC[font: Font, char: Char] RETURNS[VEC] ~ { RETURN[font.class.Width[font, char]]; }; Amplified: PUBLIC PROC[font: Font, char: Char] RETURNS[BOOL] ~ { RETURN[font.class.Amplified[font, char]]; }; Correction: PUBLIC PROC[font: Font, char: Char] RETURNS[CorrectionType] ~ { RETURN[font.class.Correction[font, char]]; }; Kern: PUBLIC PROC[font: Font, char, successor: Char] RETURNS[VEC] ~ { RETURN[font.class.Kern[font, char, successor]]; }; NextKern: PUBLIC PROC[font: Font, char, successor: Char] RETURNS[Char] ~ { RETURN[font.class.NextKern[font, char, successor]]; }; Ligature: PUBLIC PROC[font: Font, char, successor: Char] RETURNS[Char] ~ { RETURN[font.class.Ligature[font, char, successor]]; }; NextLigature: PUBLIC PROC[font: Font, char, successor: Char] RETURNS[Char] ~ { RETURN[font.class.NextLigature[font, char, successor]]; }; CharInfo: PUBLIC PROC[font: Font, char: Char, key: ATOM] RETURNS[OptionalReal] ~ { RETURN[font.class.CharInfo[font, char, key]]; }; MaskChar: PUBLIC PROC[font: Font, char: Char, imager: REF] ~ { font.class.MaskChar[font, char, imager]; }; PutProp: PUBLIC PROC[font: Font, key: REF, value: REF] ~ { font.props _ Prop.Put[font.props, key, value]; }; GetProp: PUBLIC PROC[font: Font, key: REF] RETURNS[value: REF] ~ { RETURN[Prop.Get[font.props, key]]; }; MapRope: PUBLIC PROC[action: PROC[Char], rope: ROPE, start: INT _ 0, len: INT _ INT.LAST, set: CharSet _ 0] ~ { p: Rope.ActionType ~ { action[ORD[c]] }; [] _ Rope.Map[base: rope, start: start, len: len, action: p]; }; MapText: PUBLIC PROC[action: PROC[Char], text: REF READONLY TEXT, start: NAT _ 0, len: NAT _ NAT.LAST, set: CharSet _ 0] ~ { p: PROC[c: CHAR] RETURNS[BOOL _ FALSE] ~ { action[ORD[c]] }; [] _ RefText.Map[s: text, start: start, len: len, action: p]; }; <> <> <> <> <> <> <> <fontBox.leftExtent THEN fontBox.leftExtent _ charBox.leftExtent;>> <fontBox.rightExtent THEN fontBox.rightExtent _ charBox.rightExtent;>> <fontBox.descent THEN fontBox.descent _ charBox.descent;>> <fontBox.ascent THEN fontBox.ascent _ charBox.ascent;>> <<};>> <> <> <<};>> <<>> END.