ImagerFontImpl.mesa
Copyright © 1984, Xerox Corporation. All rights reserved.
Doug Wyatt, November 14, 1984 6:47:13 pm PST
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;
name: ROPE,
transformation: Transformation,
class: Class,
data: REF,
props: REF
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: BOOLFALSE, -- 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: INTINT.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: NATNAT.LAST, set: CharSet ← 0] ~ {
p: PROC[c: CHAR] RETURNS[BOOLFALSE] ~ { action[ORD[c]] };
[] ← RefText.Map[s: text, start: start, len: len, action: p];
};
FontBoundingBox: PUBLIC PROC[font: Font] RETURNS[Extents] ~ {
first: BOOLTRUE;
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];
};
END.