IPTypefaceImpl.mesa
Copyright © 1984, 1985, 1986 by Xerox Corporation. All rights reserved.
Doug Wyatt, May 30, 1986 5:31:31 pm PDT
DIRECTORY
Imager USING [ConcatT, Context, DoSave],
ImagerFont USING [CorrectionType, Extents, Font, FontRep, nullXChar, XChar],
ImagerFontPrivate USING [FontImpl, FontImplRep],
ImagerTransformation USING [Scale, Transformation, TransformVec],
ImagerTypeface USING [Typeface, TypefaceClass, TypefaceClassRep, TypefaceRep],
IPImager,
IPInterpreter,
Vector2 USING [VEC];
IPTypefaceImpl: CEDAR PROGRAM
IMPORTS Imager, ImagerTransformation, IPImager, IPInterpreter
EXPORTS ImagerFont, IPImager
~ BEGIN OPEN IPInterpreter, ImagerTypeface, ImagerFont;
VEC: TYPE ~ Vector2.VEC;
Transformation: TYPE ~ ImagerTransformation.Transformation;
Data: TYPE ~ REF DataRep;
DataRep: TYPE ~ RECORD[
fontDescription: Vector,
characterMasks: Vector,
characterMetrics: Vector,
transformation: Transformation,
interpreter: Ref
];
Font: TYPE ~ ImagerFont.Font;
FontRep: TYPE ~ ImagerFont.FontRep;
FontImpl: TYPE ~ ImagerFontPrivate.FontImpl;
FontImplRep: PUBLIC TYPE ~ ImagerFontPrivate.FontImplRep; -- export to ImagerFont
identity: Transformation ~ ImagerTransformation.Scale[1];
MakeFont: PUBLIC PROC [self: Ref, v: Vector] RETURNS [Font] ~ {
typeface: Typeface ~ IPCreate[self, v];
impl: FontImpl ~ NEW[FontImplRep ← [typeface: typeface]];
font: Font ~ NEW[FontRep ← [name: typeface.name, charToClient: identity, impl: impl]];
RETURN[font];
};
IPCreate: PROC [self: Ref, fd: Vector] RETURNS [Typeface] ~ {
data: Data ~ NEW[DataRep ← []];
data.fontDescription ← fd;
data.characterMasks ← VectorFromAny[GetPR[fd, "characterMasks"]];
data.characterMetrics ← VectorFromAny[GetPR[fd, "characterMetrics"]];
WITH GetPR[fd, "transformation"] SELECT FROM
m: Transformation => data.transformation ← m;
ENDCASE => ERROR;
data.interpreter ← self;
RETURN[NEW[TypefaceRep ← [class: ipClass, data: data]]];
};
IPContains: PROC [self: Typeface, char: XChar] RETURNS [BOOL] ~ {
data: Data ~ NARROW[self.data];
i: Cardinal ~ LOOPHOLE[char, CARDINAL];
RETURN[GetPropC[data.characterMetrics, i].found];
};
IPNextChar: PROC [self: Typeface, char: XChar] RETURNS [next: XChar] ~ {
ichar: CARDINAL ~ LOOPHOLE[char];
start: CARDINAL ← 0;
IF char=nullXChar THEN start ← 0
ELSE IF ichar<LAST[CARDINAL] THEN start ← ichar+1
ELSE RETURN[nullXChar];
FOR code: CARDINAL IN[start..LAST[CARDINAL]] DO
xchar: XChar ~ LOOPHOLE[code];
IF IPContains[self, xchar] THEN RETURN[xchar];
ENDLOOP;
RETURN[nullXChar];
};
IPWidth: PROC [self: Typeface, char: XChar] RETURNS [VEC] ~ {
data: Data ~ NARROW[self.data];
found: BOOL; value: Any;
[found, value] ← GetPropC[data.characterMetrics, LOOPHOLE[char, CARDINAL]];
IF found THEN {
metrics: Vector ~ VectorFromAny[value];
ex, ey: REAL ← 0;
[found, value] ← GetPropR[metrics, "escapementX"];
IF found THEN ex ← RealFromAny[value];
[found, value] ← GetPropR[metrics, "escapementY"];
IF found THEN ey ← RealFromAny[value];
RETURN[data.transformation.TransformVec[[ex, ey]]];
};
RETURN[[0, 0]];
};
IPAmplified: PROC [self: Typeface, char: XChar] RETURNS [BOOL] ~ {
data: Data ~ NARROW[self.data];
found: BOOL; value: Any;
[found, value] ← GetPropC[data.characterMetrics, LOOPHOLE[char, CARDINAL]];
IF found THEN {
metrics: Vector ~ VectorFromAny[value];
[found, value] ← GetPropR[metrics, "amplified"];
IF found THEN RETURN[CardinalFromAny[value]#0];
};
RETURN[FALSE];
};
IPCorrection: PROC [self: Typeface, char: XChar] RETURNS [CorrectionType] ~ {
data: Data ~ NARROW[self.data];
found: BOOL; value: Any;
[found, value] ← GetPropC[data.characterMetrics, LOOPHOLE[char, CARDINAL]];
IF found THEN {
metrics: Vector ~ VectorFromAny[value];
[found, value] ← GetPropR[metrics, "correction"];
IF found THEN SELECT CardinalFromAny[value] FROM
0 => RETURN[mask];
1 => RETURN[space];
ENDCASE;
};
RETURN[none];
};
IPBoundingBox: PROC [self: Typeface, char: XChar] RETURNS [Extents] ~ {
data: Data ~ NARROW[self.data];
found: BOOL; value: Any;
[found, value] ← GetPropC[data.characterMetrics, LOOPHOLE[char, CARDINAL]];
IF found THEN {
metrics: Vector ~ VectorFromAny[value];
extents: Extents ← [0, 0, 0, 0];
[found, value] ← GetPropR[metrics, "leftExtent"];
IF found THEN extents.leftExtent ← RealFromAny[value];
[found, value] ← GetPropR[metrics, "rightExtent"];
IF found THEN extents.rightExtent ← RealFromAny[value];
[found, value] ← GetPropR[metrics, "ascent"];
IF found THEN extents.ascent ← RealFromAny[value];
[found, value] ← GetPropR[metrics, "descent"];
IF found THEN extents.descent ← RealFromAny[value];
RETURN[extents];
};
RETURN[[0, 0, 0, 0]];
};
IPFontBoundingBox: PROC [self: Typeface] RETURNS [Extents] ~ {
RETURN[[0, 0, 0, 0]];
};
IPKern: PROC [self: Typeface, char, successor: XChar] RETURNS [VEC] ~ {
RETURN[[0, 0]];
};
IPNextKern: PROC [self: Typeface, char, successor: XChar] RETURNS [XChar] ~ {
RETURN[nullXChar];
};
IPLigature: PROC [self: Typeface, char, successor: XChar] RETURNS [XChar] ~ {
RETURN[nullXChar];
};
IPNextLigature: PROC [self: Typeface, char, successor: XChar] RETURNS [XChar] ~ {
RETURN[nullXChar];
};
IPMask: PROC [self: Typeface, char: XChar, context: Imager.Context] ~ {
data: Data ~ NARROW[self.data];
interpreter: IPInterpreter.Ref ~ data.interpreter;
savedImager: Imager.Context ~ interpreter.imager;
maskAction: PROC ~ {
Imager.ConcatT[context, data.transformation];
IPImager.MaskChar[interpreter, data.fontDescription, LOOPHOLE[char, CARDINAL]];
};
interpreter.imager ← context;
Imager.DoSave[context, maskAction ! UNWIND => interpreter.imager ← savedImager];
interpreter.imager ← savedImager;
};
ipClass: TypefaceClass ~ NEW[TypefaceClassRep ← [
type: $IP,
Contains: IPContains,
NextChar: IPNextChar,
Width: IPWidth,
Amplified: IPAmplified,
Correction: IPCorrection,
BoundingBox: IPBoundingBox,
FontBoundingBox: IPFontBoundingBox,
Ligature: IPLigature,
NextLigature: IPNextLigature,
Kern: IPKern,
NextKern: IPNextKern,
Mask: IPMask
]];
END.