<> <> <> <<>> DIRECTORY Font USING [Char, Class, CorrectionType, Extents, FONT, FontRep, nullChar, OptionalReal], ImagerTransformation USING [Scale, Transformation], Prop USING [Get, Put], Rope USING [ROPE], Vector2 USING [VEC]; FontImpl: CEDAR PROGRAM IMPORTS ImagerTransformation, Prop EXPORTS Font ~ BEGIN ROPE: TYPE ~ Rope.ROPE; VEC: TYPE ~ Vector2.VEC; Transformation: TYPE ~ ImagerTransformation.Transformation; FONT: TYPE ~ Font.FONT; FontRep: TYPE ~ Font.FontRep; <> <> <> <> <> Class: TYPE ~ Font.Class; Char: TYPE ~ Font.Char; -- CARDINAL nullChar: Char ~ Font.nullChar; CorrectionType: TYPE ~ Font.CorrectionType; -- {none, space, mask}; Extents: TYPE ~ Font.Extents; -- RECORD[leftExtent, rightExtent, descent, ascent: REAL]; OptionalReal: TYPE ~ Font.OptionalReal; -- RECORD[exists: BOOLEAN, value: REAL]; identityTransformation: Transformation ~ ImagerTransformation.Scale[1]; Find: PUBLIC PROC[name: ROPE] RETURNS[FONT] ~ { <> <> <> 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]]; }; FontBoundingBox: PUBLIC PROC[font: FONT] RETURNS[Extents] ~ { first: BOOL _ TRUE; fontBox: Extents _ [0, 0, 0, 0]; FOR char: Char _ NextChar[font, nullChar], NextChar[font, char] UNTIL char=nullChar DO charBox: Extents ~ BoundingBox[font, char]; IF first THEN { fontBox _ charBox; first _ FALSE } ELSE { IF charBox.leftExtent>fontBox.leftExtent THEN fontBox.leftExtent _ charBox.leftExtent; IF charBox.rightExtent>fontBox.rightExtent THEN fontBox.rightExtent _ charBox.rightExtent; IF charBox.descent>fontBox.descent THEN fontBox.descent _ charBox.descent; IF charBox.ascent>fontBox.ascent THEN fontBox.ascent _ charBox.ascent; }; ENDLOOP; RETURN[fontBox]; }; Register: PUBLIC PROC[prefix: ROPE, find: PROC[ROPE] RETURNS[FONT]] ~ { }; END.