IPFontImpl.mesa
Copyright © 1984 Xerox Corporation. All rights reserved.
Doug Wyatt, August 20, 1984 2:31:21 pm PDT
DIRECTORY
Font USING [FindFont, FONT, ModifyFont],
Imager USING [ConcatT],
IPFont USING [],
IP,
Rope USING [Concat, ROPE];
IPFontImpl: CEDAR PROGRAM
IMPORTS Font, Imager, IP, Rope
EXPORTS IPFont
= BEGIN OPEN IP;
ROPE: TYPE ~ Rope.ROPE;
FONT: TYPE ~ Font.FONT;
$Font Vectors
fontClass: VectorClass ~ NEW[VectorClassRep ← [type: $Font,
shape: FontShape, get: FontGet]];
FontShape: PROC[v: Vector] RETURNS[VectorShape] ~ {
RETURN[[l: 0, n: CARDINAL.LAST]];
};
FontGet: PROC[v: Vector, j: Integer] RETURNS[Any] ~ {
font: FONT ~ v.font;
IF j IN[0..CARDINAL.LAST] THEN RETURN[OperatorFromChar[font: font, code: j]]
ELSE {
MasterError[$boundsFault, "Font vector index out of bounds."];
ERROR Error;
};
};
VectorFromFont: PUBLIC PROC[font: FONT] RETURNS[Vector] ~ {
RETURN[NEW[VectorRep ← [class: fontClass, data: NIL, font: font]]];
};
$Char Operators (the result of Get[font, j])
CharData: TYPE ~ REF CharDataRep;
CharDataRep: TYPE ~ RECORD[font: FONT, code: CARDINAL];
charClass: OperatorClass ~ NEW[OperatorClassRep ← [type: $Char, apply: CharApply]];
CharApply: PROC[op: Operator, state: State] ~ {
data: CharData ~ NARROW[op.data];
font: FONT ~ data.font;
font.class.DrawChar[font, data.code, state.imager];
};
OperatorFromChar: PROC[font: FONT, code: CARDINAL] RETURNS[Operator] ~ {
data: CharData ~ NEW[CharDataRep ← [font: font, code: code]];
RETURN[NEW[OperatorRep ← [class: charClass, data: data]]];
};
$Modified Vectors (the result of ModifyFont[v, ...] where v is not a $Font Vector)
ModifiedData: TYPE ~ REF ModifiedDataRep;
ModifiedDataRep: TYPE ~ RECORD[v: Vector, m: Transformation];
modifiedClass: VectorClass ~ NEW[VectorClassRep ← [type: $Modified,
shape: ModifiedShape, get: ModifiedGet]];
ModifiedShape: PROC[v: Vector] RETURNS[VectorShape] ~ {
data: ModifiedData ~ NARROW[v.data];
RETURN[Shape[data.v]];
};
ModifiedGet: PROC[v: Vector, j: Integer] RETURNS[Any] ~ {
data: ModifiedData ~ NARROW[v.data];
val: Any ~ Get[data.v, j];
WITH val SELECT FROM
op: Operator => RETURN[OperatorFromModifiedChar[e: op, m: data.m]];
ENDCASE => {
MasterError[$wrongType, "Element of font vector is not an Operator."];
ERROR Error;
};
};
$ModifiedChar Operators (the result of Get[v, j], where v is a $Modified Vector)
ModifiedCharData: TYPE ~ REF ModifiedCharDataRep;
ModifiedCharDataRep: TYPE ~ RECORD[e: Operator, m: Transformation];
modifiedCharClass: OperatorClass ~ NEW[OperatorClassRep ← [type: $ModifiedChar,
apply: ModifiedCharApply]];
ModifiedCharApply: PROC[op: Operator, state: State] ~ {
data: ModifiedCharData ~ NARROW[op.data];
state.imager.ConcatT[data.m]; Do[state, data.e];
};
OperatorFromModifiedChar: PROC[e: Operator, m: Transformation] RETURNS[Operator] ~ {
data: ModifiedCharData ~ NEW[ModifiedCharDataRep ← [e: e, m: m]];
RETURN[NEW[OperatorRep ← [class: modifiedCharClass, data: data]]];
};
Public procedures
RopeFromName: PROC[name: Name] RETURNS[rope: ROPENIL] ~ {
FOR list: Name ← name, list.rest UNTIL list=NIL DO
IF rope#NIL THEN rope ← rope.Concat["/"];
rope ← rope.Concat[list.first.rope];
ENDLOOP;
};
FindFont: PUBLIC PROC[self: State, v: Vector] RETURNS[Vector] ~ {
name: Name ~ NameFromVector[v];
rope: ROPE ~ RopeFromName[name];
font: FONT ~ Font.FindFont[rope];
RETURN[VectorFromFont[font]];
};
FindFontVec: PUBLIC PROC[self: State, v: Vector] RETURNS[Vector] ~ {
MasterError[$unimplemented, "FINDFONTVEC is not implemented."];
ERROR Error;
};
ModifyFont: PUBLIC PROC[v: Vector, m: Transformation] RETURNS[Vector] ~ {
IF v.font#NIL THEN RETURN[VectorFromFont[Font.ModifyFont[v.font, m]]]
ELSE {
data: ModifiedData ~ NEW[ModifiedDataRep ← [v: v, m: m]];
RETURN[NEW[VectorRep ← [class: modifiedClass, data: data]]];
};
};
END.