ImagerIKTypefaceImpl.mesa
Copyright © 1987 by Xerox Corporation. All rights reserved.
Plass, January 19, 1987 2:16:22 pm PST
Adams, January 19, 1987 4:23:51 pm PST
Rick Beach, February 4, 1987 12:07:05 pm PST
Subhana Menis, February 10, 1987 5:39:12 pm PST
DIRECTORY CardTable, Imager, ImagerBox, ImagerPath, ImagerFont, IKOps, Rope, ImagerTypeface, RuntimeError, FS;
ImagerIKTypefaceImpl: CEDAR PROGRAM
IMPORTS CardTable, Imager, ImagerBox, IKOps, ImagerTypeface, RuntimeError
~ BEGIN
XChar: TYPE ~ ImagerFont.XChar;
nullXChar: XChar ~ ImagerFont.nullXChar;
VEC: TYPE ~ Imager.VEC;
ROPE: TYPE ~ Rope.ROPE;
IKFontData: TYPE ~ IKOps.IKFontData;
Typeface: TYPE ~ ImagerTypeface.Typeface;
CharCodeMapper: TYPE ~ CardTable.Ref;
Data: TYPE ~ REF DataRep;
DataRep: TYPE ~ RECORD [
ikFontData: IKOps.IKFontData,
charCodeMapper: CharCodeMapper,
unitsPerEm: REAL
];
Ord: PROC [x: XChar] RETURNS [CARDINAL] ~ INLINE {RETURN [x.set*256+x.code]};
IKContains: PROC [self: Typeface, char: XChar] RETURNS [BOOL] ~ {
data: Data ~ NARROW[self.data];
mapped: REF CARDINAL ~ NARROW[CardTable.Fetch[data.charCodeMapper, Ord[char]].val];
RETURN [char = [0, 40B] OR mapped # NIL AND IKOps.Contains[data.ikFontData, mapped^]]
};
IKNextChar: PROC [self: Typeface, char: XChar] RETURNS [XChar] ~ {
Val: PROC [c: CARDINAL] RETURNS [XChar] ~ INLINE {RETURN [[set: c/256, code: c MOD 256]]};
next: XChar ← IF char = nullXChar THEN [0, 0] ELSE Val[Ord[char]+1];
UNTIL next = nullXChar OR IKContains[self, next] DO
next ← Val[Ord[next]+1]
ENDLOOP;
RETURN [next];
};
defaultWidth: VEC ~ [0.5, 0.0];
wordSpaceWidth: VEC ~ [0.3333, 0.0];
IKWidth: PROC [self: Typeface, char: XChar] RETURNS [VEC] ~ {
data: Data ~ NARROW[self.data];
mapped: REF CARDINAL ~ NARROW[CardTable.Fetch[data.charCodeMapper, Ord[char]].val];
IF char = [0, 40B] THEN {
RETURN [wordSpaceWidth]
};
IF mapped # NIL AND IKOps.Contains[data.ikFontData, mapped^] THEN {
charInfo: IKOps.CharacterInfo ~ IKOps.GetCharacterInfo[data.ikFontData, mapped^];
RETURN [[x: charInfo.totalSetWidth/data.unitsPerEm, y: 0.0]]
};
RETURN [defaultWidth];
};
IKAmplified: PROC [self: Typeface, char: XChar] RETURNS [BOOL] ~ {
IF char = [0, 40B] THEN RETURN [TRUE];
RETURN [FALSE]
};
IKCorrection: PROC [self: Typeface, char: XChar] RETURNS [ImagerFont.CorrectionType] ~ {
IF char = [0, 40B] THEN RETURN [space];
RETURN [mask]
};
IKBoundingBox: PROC [self: Typeface, char: XChar] RETURNS [ImagerFont.Extents] ~ {
data: Data ~ NARROW[self.data];
mapped: REF CARDINAL ~ NARROW[CardTable.Fetch[data.charCodeMapper, Ord[char]].val];
IF mapped # NIL AND IKOps.Contains[data.ikFontData, mapped^] THEN {
charInfo: IKOps.CharacterInfo ~ IKOps.GetCharacterInfo[data.ikFontData, mapped^];
xMin: REAL ~ (charInfo.xMin+charInfo.leftSideBearing)/data.unitsPerEm;
xMax: REAL ~ (charInfo.xMax+charInfo.leftSideBearing)/data.unitsPerEm;
yMin: REAL ~ (charInfo.yMin)/data.unitsPerEm;
yMax: REAL ~ (charInfo.yMax)/data.unitsPerEm;
RETURN [ImagerBox.ExtentsFromBox[[xmin: xMin, ymin: yMin, xmax: xMax, ymax: yMax]]]
};
RETURN [[leftExtent: -0.05, rightExtent: 0.45, descent: 0, ascent: 0.6]];
};
IKFontBoundingBox: PROC [self: Typeface] RETURNS [ImagerFont.Extents] ~ {
data: Data ~ NARROW[self.data];
bb: ImagerBox.Box ← [xmin: 0.05, ymin: 0, xmax: 0.45, ymax: 0.6];
Action: PROC [characterCode: CARDINAL, byteOffsetOfCharacterData: INT] ~ {
charInfo: IKOps.CharacterInfo ~ IKOps.GetCharacterInfo[data.ikFontData, characterCode];
xMin: REAL ~ (charInfo.xMin+charInfo.leftSideBearing)/data.unitsPerEm;
xMax: REAL ~ (charInfo.xMax+charInfo.leftSideBearing)/data.unitsPerEm;
yMin: REAL ~ (charInfo.yMin)/data.unitsPerEm;
yMax: REAL ~ (charInfo.yMax)/data.unitsPerEm;
bb ← ImagerBox.BoundingBox[bb, [xmin: xMin, ymin: yMin, xmax: xMax, ymax: yMax]];
};
IKOps.EnumerateCharacters[data.ikFontData, Action];
RETURN [ImagerBox.ExtentsFromBox[bb]];
};
IKLigature: PROC [self: Typeface, char, successor: XChar] RETURNS [XChar] ~ {
RETURN[nullXChar];
};
IKNextLigature: PROC [self: Typeface, char, successor: XChar] RETURNS [XChar] ~ {
RETURN[nullXChar];
};
IKKern: PROC [self: Typeface, char, successor: XChar] RETURNS [VEC] ~ {
RETURN[[0, 0]];
};
IKNextKern: PROC [self: Typeface, char, successor: XChar] RETURNS [XChar] ~ {
RETURN[nullXChar];
};
IKMask: PROC [self: Typeface, char: XChar, context: Imager.Context] ~ {
data: Data ~ NARROW[self.data];
mapped: REF CARDINAL ~ NARROW[CardTable.Fetch[data.charCodeMapper, Ord[char]].val];
IF mapped # NIL AND IKOps.Contains[data.ikFontData, mapped^] THEN {
path: ImagerPath.PathProc ~ {
IKOps.GetPath[data.ikFontData, mapped^, moveTo, lineTo, curveTo];
};
charInfo: IKOps.CharacterInfo ~ IKOps.GetCharacterInfo[data.ikFontData, mapped^];
Imager.ScaleT[context, 1.0/data.unitsPerEm];
Imager.TranslateT[context, [x: charInfo.xMin+charInfo.leftSideBearing, y: charInfo.yMin]];
Imager.MaskFill[context: context, path: path, parity: TRUE];
RETURN;
};
IF char # [0, 40B] THEN Imager.MaskBox[context, [xmin: 0.05, ymin: 0.0, xmax: 0.45, ymax: 0.6]];
};
ikClass: ImagerTypeface.TypefaceClass ~ NEW[ImagerTypeface.TypefaceClassRep ← [
type: $IkarusFont,
Contains: IKContains,
NextChar: IKNextChar,
Width: IKWidth,
Amplified: IKAmplified,
Correction: IKCorrection,
BoundingBox: IKBoundingBox,
FontBoundingBox: IKFontBoundingBox,
Ligature: IKLigature,
NextLigature: IKNextLigature,
Kern: IKKern,
NextKern: IKNextKern,
Mask: IKMask
]];
FindCharCodeMapper: PROC [ikFontData: IKFontData] RETURNS [CharCodeMapper] ~ {
RETURN [bigelowAndHolmesCharCodeMapper] -- for now
};
FindUnitsPerEm: PROC [ikFontData: IKFontData] RETURNS [REAL] ~ {
IF ikFontData.bodySize # 0.0 THEN RETURN [ikFontData.bodySize];
RETURN [16800.0] -- for now
};
bigelowAndHolmesCharCodeMapper: CharCodeMapper ~ MakeBigelowAndHolmesCharCodeMapper[];
MakeBigelowAndHolmesCharCodeMapper: PROC RETURNS [CharCodeMapper] ~ {
c: CardTable.Ref ~ CardTable.Create[199];
C: PROC [xSet: [0B..377B), xChar: [0B..377B), bChar: CARDINAL] ~ {
[] ← CardTable.Store[c, xSet*256+xChar, NEW[CARDINAL ← bChar]];
};
C[xSet: 0B, xChar: 101B, bChar: 101];
C[xSet: 0B, xChar: 102B, bChar: 102];
C[xSet: 0B, xChar: 103B, bChar: 103];
C[xSet: 0B, xChar: 104B, bChar: 104];
C[xSet: 0B, xChar: 105B, bChar: 105];
C[xSet: 0B, xChar: 106B, bChar: 106];
C[xSet: 0B, xChar: 107B, bChar: 107];
C[xSet: 0B, xChar: 110B, bChar: 108];
C[xSet: 0B, xChar: 111B, bChar: 109];
C[xSet: 0B, xChar: 112B, bChar: 110];
C[xSet: 0B, xChar: 113B, bChar: 111];
C[xSet: 0B, xChar: 114B, bChar: 112];
C[xSet: 0B, xChar: 115B, bChar: 113];
C[xSet: 0B, xChar: 116B, bChar: 114];
C[xSet: 0B, xChar: 117B, bChar: 115];
C[xSet: 0B, xChar: 120B, bChar: 116];
C[xSet: 0B, xChar: 121B, bChar: 117];
C[xSet: 0B, xChar: 122B, bChar: 118];
C[xSet: 0B, xChar: 123B, bChar: 119];
C[xSet: 0B, xChar: 124B, bChar: 120];
C[xSet: 0B, xChar: 125B, bChar: 121];
C[xSet: 0B, xChar: 126B, bChar: 122];
C[xSet: 0B, xChar: 127B, bChar: 123];
C[xSet: 0B, xChar: 130B, bChar: 124];
C[xSet: 0B, xChar: 131B, bChar: 125];
C[xSet: 0B, xChar: 132B, bChar: 126];
C[xSet: 0B, xChar: 341B, bChar: 127];
C[xSet: 0B, xChar: 352B, bChar: 128];
C[xSet: 0B, xChar: 351B, bChar: 129];
C[xSet: 0B, xChar: 350B, bChar: 130];
C[xSet: 46B, xChar: 131B, bChar: 139];
C[xSet: 46B, xChar: 104B, bChar: 140];
C[xSet: 46B, xChar: 105B, bChar: 141];
C[xSet: 46B, xChar: 113B, bChar: 142];
C[xSet: 46B, xChar: 116B, bChar: 143];
C[xSet: 46B, xChar: 121B, bChar: 144];
C[xSet: 46B, xChar: 123B, bChar: 145];
C[xSet: 46B, xChar: 126B, bChar: 146];
C[xSet: 46B, xChar: 132B, bChar: 147];
C[xSet: 46B, xChar: 134B, bChar: 148];
C[xSet: 46B, xChar: 135B, bChar: 149];
C[xSet: 0B, xChar: 140B, bChar: 150];
C[xSet: 0B, xChar: 301B, bChar: 150];
C[xSet: 0B, xChar: 5B, bChar: 150]; --temporary substitution for Subhana
C[xSet: 0B, xChar: 302B, bChar: 151];
C[xSet: 0B, xChar: 13B, bChar: 151]; --temporary substitution for Subhana
C[xSet: 0B, xChar: 136B, bChar: 152];
C[xSet: 0B, xChar: 303B, bChar: 152];
C[xSet: 0B, xChar: 317B, bChar: 153];
C[xSet: 0B, xChar: 312B, bChar: 154];
C[xSet: 0B, xChar: 307B, bChar: 155];
C[xSet: 0B, xChar: 310B, bChar: 156];
C[xSet: 0B, xChar: 176B, bChar: 157];
C[xSet: 0B, xChar: 305B, bChar: 157];
C[xSet: 0B, xChar: 304B, bChar: 158];
C[xSet: 0B, xChar: 306B, bChar: 159];
C[xSet: 0B, xChar: 315B, bChar: 160];
C[xSet: 0B, xChar: 316B, bChar: 161];
C[xSet: 0B, xChar: 313B, bChar: 170];
C[xSet: 361B, xChar: 55B, bChar: 270];
C[xSet: 0B, xChar: 141B, bChar: 301];
C[xSet: 0B, xChar: 142B, bChar: 302];
C[xSet: 0B, xChar: 143B, bChar: 303];
C[xSet: 0B, xChar: 144B, bChar: 304];
C[xSet: 0B, xChar: 145B, bChar: 305];
C[xSet: 0B, xChar: 146B, bChar: 306];
C[xSet: 0B, xChar: 147B, bChar: 307];
C[xSet: 0B, xChar: 150B, bChar: 308];
C[xSet: 0B, xChar: 151B, bChar: 309];
C[xSet: 0B, xChar: 152B, bChar: 310];
C[xSet: 0B, xChar: 153B, bChar: 311];
C[xSet: 0B, xChar: 154B, bChar: 312];
C[xSet: 0B, xChar: 155B, bChar: 313];
C[xSet: 0B, xChar: 156B, bChar: 314];
C[xSet: 0B, xChar: 157B, bChar: 315];
C[xSet: 0B, xChar: 160B, bChar: 316];
C[xSet: 0B, xChar: 161B, bChar: 317];
C[xSet: 0B, xChar: 162B, bChar: 318];
C[xSet: 0B, xChar: 163B, bChar: 319];
C[xSet: 0B, xChar: 164B, bChar: 320];
C[xSet: 0B, xChar: 165B, bChar: 321];
C[xSet: 0B, xChar: 166B, bChar: 322];
C[xSet: 0B, xChar: 167B, bChar: 323];
C[xSet: 0B, xChar: 170B, bChar: 324];
C[xSet: 0B, xChar: 171B, bChar: 325];
C[xSet: 0B, xChar: 172B, bChar: 326];
C[xSet: 0B, xChar: 361B, bChar: 327];
C[xSet: 0B, xChar: 372B, bChar: 328];
C[xSet: 0B, xChar: 371B, bChar: 329];
C[xSet: 0B, xChar: 373B, bChar: 330];
C[xSet: 360B, xChar: 41B, bChar: 331];
C[xSet: 360B, xChar: 44B, bChar: 332];
C[xSet: 360B, xChar: 45B, bChar: 333];
C[xSet: 360B, xChar: 42B, bChar: 334];
C[xSet: 360B, xChar: 43B, bChar: 335];
C[xSet: 0B, xChar: 365B, bChar: 336];
C[xSet: 0B, xChar: 370B, bChar: 337];
C[xSet: 0B, xChar: 345B, bChar: 338];
C[xSet: ???B, xChar: ???B, bChar: 350 ??? lower case accents??];
C[xSet: ???B, xChar: ???B, bChar: 351 ???];
C[xSet: ???B, xChar: ???B, bChar: 352 ???];
C[xSet: ???B, xChar: ???B, bChar: 353 ???];
C[xSet: ???B, xChar: ???B, bChar: 354 ???];
C[xSet: ???B, xChar: ???B, bChar: 355 ???];
C[xSet: ???B, xChar: ???B, bChar: 356 ???];
C[xSet: ???B, xChar: ???B, bChar: 357 ???];
C[xSet: ???B, xChar: ???B, bChar: 358 ???];
C[xSet: ???B, xChar: ???B, bChar: 359 ???];
C[xSet: ???B, xChar: ???B, bChar: 360 ???];
C[xSet: ???B, xChar: ???B, bChar: 361 ???];
C[xSet: ???B, xChar: ???B, bChar: 370 ???];
C[xSet: 361B, xChar: 255B, bChar: 470];
C[xSet: 0B, xChar: 60B, bChar: 500];
C[xSet: 0B, xChar: 61B, bChar: 501];
C[xSet: 0B, xChar: 62B, bChar: 502];
C[xSet: 0B, xChar: 63B, bChar: 503];
C[xSet: 0B, xChar: 64B, bChar: 504];
C[xSet: 0B, xChar: 65B, bChar: 505];
C[xSet: 0B, xChar: 66B, bChar: 506];
C[xSet: 0B, xChar: 67B, bChar: 507];
C[xSet: 0B, xChar: 70B, bChar: 508];
C[xSet: 0B, xChar: 71B, bChar: 509];
C[xSet: 357B, xChar: 260B, bChar: 520];
C[xSet: 357B, xChar: 261B, bChar: 521];
C[xSet: 0B, xChar: 321B, bChar: 521];
C[xSet: 357B, xChar: 262B, bChar: 522];
C[xSet: 0B, xChar: 262B, bChar: 522];
C[xSet: 357B, xChar: 263B, bChar: 523];
C[xSet: 0B, xChar: 263B, bChar: 523];
C[xSet: 357B, xChar: 264B, bChar: 524];
C[xSet: 357B, xChar: 265B, bChar: 525];
C[xSet: 357B, xChar: 266B, bChar: 526];
C[xSet: 357B, xChar: 267B, bChar: 527];
C[xSet: 357B, xChar: 270B, bChar: 528];
C[xSet: 357B, xChar: 271B, bChar: 529];
C[xSet: 0B, xChar: 275B, bChar: 540];
C[xSet: 0B, xChar: 274B, bChar: 542];
C[xSet: 357B, xChar: 257B, bChar: 545];
C[xSet: 357B, xChar: 241B, bChar: 570];
C[xSet: 357B, xChar: 245B, bChar: 576];
C[xSet: 0B, xChar: 56B, bChar: 600];
C[xSet: 0B, xChar: 72B, bChar: 601];
C[xSet: 0B, xChar: 54B, bChar: 602];
C[xSet: 0B, xChar: 73B, bChar: 603];
C[xSet: 0B, xChar: 251B, bChar: 604];
C[xSet: 0B, xChar: 140B, bChar: 604]; --temporary substitution for Subhana
C[xSet: 0B, xChar: 47B, bChar: 605];
C[xSet: 0B, xChar: 271B, bChar: 605];
C[xSet: 0B, xChar: 252B, bChar: 606];
C[xSet: 0B, xChar: 42B, bChar: 607];
C[xSet: 0B, xChar: 272B, bChar: 607];
C[xSet: 357B, xChar: 50B, bChar: 608];
C[xSet: 0B, xChar: 41B, bChar: 609];
C[xSet: 0B, xChar: 241B, bChar: 610];
C[xSet: 0B, xChar: 77B, bChar: 611];
C[xSet: 0B, xChar: 277B, bChar: 612];
C[xSet: 43B, xChar: 262B, bChar: 613];
C[xSet: 0B, xChar: 134B, bChar: 620];
C[xSet: 0B, xChar: 57B, bChar: 621];
C[xSet: 0B, xChar: 50B, bChar: 622];
C[xSet: 0B, xChar: 51B, bChar: 623];
C[xSet: 0B, xChar: 133B, bChar: 624];
C[xSet: 0B, xChar: 135B, bChar: 625];
C[xSet: 0B, xChar: 173B, bChar: 626];
C[xSet: 0B, xChar: 175B, bChar: 627];
C[xSet: 357B, xChar: 52B, bChar: 628];
C[xSet: 357B, xChar: 53B, bChar: 629];
C[xSet: 0B, xChar: 253B, bChar: 630];
C[xSet: 0B, xChar: 273B, bChar: 631];
C[xSet: 357B, xChar: 60B, bChar: 650];
C[xSet: 357B, xChar: 61B, bChar: 651];
C[xSet: 0B, xChar: 247B, bChar: 652];
C[xSet: 0B, xChar: 266B, bChar: 653];
C[xSet: 41B, xChar: 76B, bChar: 670];
C[xSet: 357B, xChar: 44B, bChar: 671];
C[xSet: 0B, xChar: 55B, bChar: 671]; -- neutral
C[xSet: 0B, xChar: 30B, bChar: 671]; --temporary substitution for Subhana
C[xSet: 0B, xChar: 55B, bChar: 670]; --temporary substitution for Subhana
C[xSet: 357B, xChar: 45B, bChar: 672];
C[xSet: 0B, xChar: 137B, bChar: 673];
C[xSet: 0B, xChar: 137B, bChar: 672]; -- questionable duplication
C[xSet: 0B, xChar: 52B, bChar: 674];
C[xSet: 0B, xChar: 174B, bChar: 675];
C[xSet: 0B, xChar: 244B, bChar: 700];
C[xSet: 0B, xChar: 242B, bChar: 701];
C[xSet: 0B, xChar: 243B, bChar: 702];
C[xSet: 0B, xChar: 245B, bChar: 703];
C[xSet: 357B, xChar: 242B, bChar: 704];
C[xSet: 0B, xChar: 44B, bChar: 705];
C[xSet: 0B, xChar: 44B, bChar: 700]; --(questionable duplication)
C[xSet: 0B, xChar: 43B, bChar: 710];
C[xSet: 0B, xChar: 45B, bChar: 711];
C[xSet: 0B, xChar: 260B, bChar: 712];
C[xSet: 0B, xChar: 323B, bChar: 713];
C[xSet: 0B, xChar: 100B, bChar: 714];
C[xSet: 0B, xChar: 46B, bChar: 715];
C[xSet: 0B, xChar: 265B, bChar: 716];
C[xSet: 0B, xChar: 322B, bChar: 717];
C[xSet: 0B, xChar: 324B, bChar: 718];
C[xSet: ???B, xChar: ???B, bChar: 719 ???];
C[xSet: ???B, xChar: ???B, bChar: 720 ???];
C[xSet: 357B, xChar: 0B, bChar: 721];
C[xSet: 357B, xChar: 146B, bChar: 722];
C[xSet: ???B, xChar: ???B, bChar: 724 ??? three dots in a row??];
C[xSet: 0B, xChar: 53B, bChar: 750];
C[xSet: 365B, xChar: 55B, bChar: 751]; -- (minus sign code)
C[xSet: 0B, xChar: 75B, bChar: 752];
C[xSet: 0B, xChar: 261B, bChar: 753];
C[xSet: 0B, xChar: 74B, bChar: 754];
C[xSet: 0B, xChar: 76B, bChar: 755];
C[xSet: 356B, xChar: 176B, bChar: 756];
C[xSet: 357B, xChar: 266B, bChar: 757];
C[xSet: 0B, xChar: 267B, bChar: 758];
C[xSet: ???B, xChar: ???B, bChar: 759 ??? prime?? another name for this??];
C[xSet: 0B, xChar: 264B, bChar: 760];
C[xSet: 0B, xChar: 270B, bChar: 761];
C[xSet: 41B, xChar: 142B, bChar: 762];
RETURN [c]
};
IKCreator: ImagerTypeface.CreateProc ~ {
PROC [file: FS.OpenFile] RETURNS [Typeface]
ikFontData: IKOps.IKFontData ← NIL;
ikFontData ← IKOps.OpenFromOpenFile[file ! RuntimeError.UNCAUGHT => CONTINUE];
IF ikFontData = NIL THEN ERROR Imager.Error[[$formatError, "Format error in IK font file"]];
RETURN [NEW[ImagerTypeface.TypefaceRep ← [
class: ikClass,
data: NEW [DataRep ← [ikFontData, FindCharCodeMapper[ikFontData], FindUnitsPerEm[ikFontData]]]
]]];
};
ImagerTypeface.Register[extension: "ik", create: IKCreator];
END.