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: 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];
};
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];
};
END.