DIRECTORY Checksum USING [ComputeChecksum], II USING [ConcatT, Context, DoSaveAll, Rectangle], IIFont USING [BYTE, CorrectionType, Extents, Font, FontRep, XChar, XCharProc, XStringProc], IITransformation USING [Concat, Copy, Equal, PostScale, Scale, Transformation, TransformationRep, TransformRectangle, TransformVec], IITypeface USING [FindTypeface, TypefaceRep], PrincOps USING [zXOR], Rope USING [ActionType, Map, ROPE], Vector2 USING [Add, VEC]; IIFontImpl: CEDAR MONITOR IMPORTS Checksum, II, IITransformation, IITypeface, Rope, Vector2 EXPORTS IIFont, IITypeface ~ BEGIN BYTE: TYPE ~ IIFont.BYTE; CorrectionType: TYPE ~ IIFont.CorrectionType; Extents: TYPE ~ IIFont.Extents; Font: TYPE ~ IIFont.Font; FontRep: TYPE ~ IIFont.FontRep; XChar: TYPE ~ IIFont.XChar; XCharProc: TYPE ~ IIFont.XCharProc; XStringProc: TYPE ~ IIFont.XStringProc; Typeface: TYPE ~ REF TypefaceRep; TypefaceRep: PUBLIC TYPE ~ IITypeface.TypefaceRep; -- export to IITypeface Rectangle: TYPE ~ II.Rectangle; ROPE: TYPE ~ Rope.ROPE; MapRope: PUBLIC PROC [rope: ROPE, start: INT _ 0, len: INT _ INT.LAST, charAction: XCharProc] ~ { state: {run, escape, escape2, extended, extended2} _ run; set: BYTE _ 0; byteAction: PROC [c: CHAR] RETURNS [BOOL _ FALSE] ~ { b: BYTE ~ ORD[c]; SELECT state FROM run => IF b=255 THEN state _ escape ELSE { charAction[[set: set, code: b]] }; escape => IF b=255 THEN state _ escape2 ELSE { set _ b; state _ run }; escape2 => IF b=0 THEN state _ extended ELSE ERROR; extended => IF b=255 THEN state _ escape ELSE { set _ b; state _ extended2 }; extended2 => { charAction[[set: set, code: b]]; state _ extended }; ENDCASE; }; [] _ Rope.Map[base: rope, start: start, len: len, action: byteAction]; }; MapText: PUBLIC PROC [text: REF READONLY TEXT, start: NAT _ 0, len: NAT _ NAT.LAST, charAction: XCharProc] ~ { rem: NAT ~ text.length-start; -- bounds check state: {run, escape, escape2, extended, extended2} _ run; set: BYTE _ 0; FOR i: NAT IN[0..MIN[len, rem]) DO b: BYTE ~ ORD[text[start+i]]; SELECT state FROM run => IF b=255 THEN state _ escape ELSE { charAction[[set: set, code: b]] }; escape => IF b=255 THEN state _ escape2 ELSE { set _ b; state _ run }; escape2 => IF b=0 THEN state _ extended ELSE ERROR; extended => IF b=255 THEN state _ escape ELSE { set _ b; state _ extended2 }; extended2 => { charAction[[set: set, code: b]]; state _ extended }; ENDCASE; ENDLOOP; }; VEC: TYPE ~ Vector2.VEC; Transformation: TYPE ~ IITransformation.Transformation; TransformationRep: TYPE ~ IITransformation.TransformationRep; identityTransformation: Transformation ~ IITransformation.Scale[1]; hashTableSize: NAT ~ 53; HashIndex: TYPE ~ [0..hashTableSize); HashTable: TYPE ~ REF HashTableRep; HashTableRep: TYPE ~ ARRAY HashIndex OF NodeList; NodeList: TYPE ~ LIST OF Node; Node: TYPE ~ RECORD [hash: CARDINAL, font: Font]; hashTable: HashTable ~ NEW[HashTableRep _ ALL[NIL]]; entries: INT _ 0; collisions: INT _ 0; misses: INT _ 0; Munch: PROC [LONG CARDINAL] RETURNS [CARDINAL] ~ TRUSTED MACHINE CODE { PrincOps.zXOR }; Hash: PROC [typeface: Typeface, m: Transformation] RETURNS [CARDINAL] ~ TRUSTED INLINE { RETURN[Checksum.ComputeChecksum[cs: Munch[LOOPHOLE[typeface]], nWords: SIZE[TransformationRep], p: LOOPHOLE[m]]]; }; MakeFont: PUBLIC ENTRY PROC [typeface: Typeface, m: Transformation] RETURNS [Font] ~ { ENABLE UNWIND => NULL; hash: CARDINAL ~ Hash[typeface, m]; hashIndex: HashIndex ~ hash MOD hashTableSize; head: NodeList ~ hashTable[hashIndex]; FOR each: NodeList _ head, each.rest UNTIL each=NIL DO node: Node ~ each.first; IF node.hash = hash AND node.font.typeface = typeface AND IITransformation.Equal[node.font.charToClient, m] THEN RETURN[node.font] ELSE misses _ misses+1; ENDLOOP; { -- not found, so make a new Font font: Font ~ NEW[FontRep _ [charToClient: IITransformation.Copy[m], typeface: typeface]]; hashTable[hashIndex] _ CONS[[hash: hash, font: font], head]; entries _ entries+1; IF head#NIL THEN collisions _ collisions+1; RETURN[font]; }; }; RectangleFromExtents: PROC [e: Extents] RETURNS [Rectangle] ~ INLINE { RETURN[[x: -e.leftExtent, y: -e.descent, w: e.leftExtent+e.rightExtent, h: e.descent+e.ascent]]; }; ExtentsFromRectangle: PROC [r: Rectangle] RETURNS [Extents] ~ INLINE { RETURN[[leftExtent: -r.x, rightExtent: r.x+r.w, descent: -r.y, ascent: r.y+r.h]]; }; TransformExtents: PROC [m: Transformation, e: Extents] RETURNS [Extents] ~ { RETURN[ExtentsFromRectangle[m.TransformRectangle[RectangleFromExtents[e]]]] }; Find: PUBLIC PROC [name: ROPE] RETURNS [Font] ~ { typeface: Typeface ~ IITypeface.FindTypeface[name]; -- may raise II.Error RETURN[MakeFont[typeface, identityTransformation]]; }; Modify: PUBLIC PROC [font: Font, m: Transformation] RETURNS [Font] ~ { RETURN[MakeFont[font.typeface, font.charToClient.Concat[m]]]; }; Scale: PUBLIC PROC [font: Font, s: REAL] RETURNS [Font] ~ { RETURN[MakeFont[font.typeface, font.charToClient.PostScale[s]]]; }; FindScaled: PUBLIC PROC [name: ROPE, s: REAL] RETURNS [Font] ~ { RETURN[Scale[Find[name], s]]; }; Contains: PUBLIC PROC [font: Font, char: XChar] RETURNS [BOOL] ~ { typeface: Typeface ~ font.typeface; IF char.set=0 AND typeface.info#NIL THEN RETURN[typeface.info[char.code].exists] ELSE RETURN[typeface.class.Contains[typeface, char]]; }; NextChar: PUBLIC PROC [font: Font, char: XChar] RETURNS [next: XChar] ~ { typeface: Typeface ~ font.typeface; RETURN[typeface.class.NextChar[typeface, char]]; }; Escapement: PUBLIC PROC [font: Font, char: XChar] RETURNS [VEC] ~ { typeface: Typeface ~ font.typeface; escapement: VEC ~ typeface.class.Escapement[typeface, char]; RETURN[font.charToClient.TransformVec[escapement]]; }; Amplified: PUBLIC PROC [font: Font, char: XChar] RETURNS [BOOL] ~ { typeface: Typeface ~ font.typeface; IF char.set=0 AND typeface.info#NIL THEN RETURN[typeface.info[char.code].amplified] ELSE RETURN[typeface.class.Amplified[typeface, char]]; }; Correction: PUBLIC PROC [font: Font, char: XChar] RETURNS [CorrectionType] ~ { typeface: Typeface ~ font.typeface; IF char.set=0 AND typeface.info#NIL THEN RETURN[typeface.info[char.code].correction] ELSE RETURN[typeface.class.Correction[typeface, char]]; }; BoundingBox: PUBLIC PROC [font: Font, char: XChar] RETURNS [Extents] ~ { typeface: Typeface ~ font.typeface; charExtents: Extents ~ typeface.class.BoundingBox[typeface, char]; RETURN[TransformExtents[font.charToClient, charExtents]]; }; FontBoundingBox: PUBLIC PROC [font: Font] RETURNS [Extents] ~ { typeface: Typeface ~ font.typeface; fontExtents: Extents ~ typeface.class.FontBoundingBox[typeface]; RETURN[TransformExtents[font.charToClient, fontExtents]]; }; Name: PUBLIC PROC [font: Font] RETURNS [ROPE] ~ { typeface: Typeface ~ font.typeface; RETURN [typeface.name]; }; Kern: PUBLIC PROC [font: Font, char, successor: XChar] RETURNS [VEC] ~ { typeface: Typeface ~ font.typeface; RETURN[typeface.class.Kern[typeface, char, successor]]; }; NextKern: PUBLIC PROC [font: Font, char, successor: XChar] RETURNS [XChar] ~ { typeface: Typeface ~ font.typeface; RETURN[typeface.class.NextKern[typeface, char, successor]]; }; Ligature: PUBLIC PROC [font: Font, char, successor: XChar] RETURNS [XChar] ~ { typeface: Typeface ~ font.typeface; RETURN[typeface.class.Ligature[typeface, char, successor]]; }; NextLigature: PUBLIC PROC [font: Font, char, successor: XChar] RETURNS [XChar] ~ { typeface: Typeface ~ font.typeface; RETURN[typeface.class.NextLigature[typeface, char, successor]]; }; MaskChar: PUBLIC PROC [font: Font, char: XChar, context: II.Context] ~ { typeface: Typeface ~ font.typeface; action: PROC ~ { II.ConcatT[context, font.charToClient]; typeface.class.Mask[typeface, char, context]; }; II.DoSaveAll[context, action]; }; StringEscapement: PUBLIC PROC [font: Font, string: XStringProc] RETURNS [VEC] ~ { sum: VEC _ [0, 0]; -- accumulated in character coordinates typeface: Typeface ~ font.typeface; charAction: XCharProc ~ { escapement: VEC ~ typeface.class.Escapement[typeface, char]; sum _ Vector2.Add[sum, escapement]; }; string[charAction]; RETURN[font.charToClient.TransformVec[sum]]; }; RopeEscapement: PUBLIC PROC [font: Font, rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] RETURNS [VEC] ~ { string: XStringProc ~ { MapRope[rope, start, len, charAction] }; RETURN[StringEscapement[font, string]]; }; TextEscapement: PUBLIC PROC [font: Font, text: REF READONLY TEXT, start: NAT _ 0, len: NAT _ NAT.LAST] RETURNS [VEC] ~ { string: XStringProc ~ { MapText[text, start, len, charAction] }; RETURN[StringEscapement[font, string]]; }; StringBoundingBox: PUBLIC PROC [font: Font, string: XStringProc] RETURNS [Extents] ~ { typeface: Typeface ~ font.typeface; sxmin, symin, sxmax, symax: REAL _ 0; position: VEC _ [0, 0]; count: INT _ 0; charAction: XCharProc ~ { charExtents: Extents ~ typeface.class.BoundingBox[typeface, char]; charEscapement: VEC ~ typeface.class.Escapement[typeface, char]; cxmin: REAL ~ position.x-charExtents.leftExtent; cxmax: REAL ~ position.x+charExtents.rightExtent; cymin: REAL ~ position.y-charExtents.descent; cymax: REAL ~ position.y+charExtents.ascent; IF count=0 THEN { sxmin _ cxmin; sxmax _ cxmax; symin _ cymin; symax _ cymax } ELSE { IF cxmin < sxmin THEN sxmin _ cxmin; IF cxmax > sxmax THEN sxmax _ cxmax; IF cymin < symin THEN symin _ cymin; IF cymax > symax THEN symax _ cymax; }; position _ Vector2.Add[position, charEscapement]; count _ count+1; }; string[charAction]; RETURN[TransformExtents[font.charToClient, [leftExtent: -sxmin, rightExtent: sxmax, descent: -symin, ascent: symax]]]; }; RopeBoundingBox: PUBLIC PROC [font: Font, rope: ROPE, start: INT _ 0, len: INT _ INT.LAST] RETURNS [Extents] ~ { string: XStringProc ~ { MapRope[rope, start, len, charAction] }; RETURN[StringBoundingBox[font, string]]; }; TextBoundingBox: PUBLIC PROC [font: Font, text: REF READONLY TEXT, start: NAT _ 0, len: NAT _ NAT.LAST] RETURNS [Extents] ~ { string: XStringProc ~ { MapText[text, start, len, charAction] }; RETURN[StringBoundingBox[font, string]]; }; END. ςImagerFontImpl.mesa Copyright Σ 1984, 1985 by Xerox Corporation. All rights reserved. Doug Wyatt, May 27, 1985 1:49:59 pm PDT Michael Plass, November 21, 1986 12:34:05 pm PST N.B. Exported to IITypeface N.B. Exported to IITypeface Κ Ξ˜codešœ™KšœB™BK™'K™0—K™šΟk ˜ Kšœ œ˜!Kšœœ*˜2KšœœœI˜[Kšœœn˜„Kšœ œ˜-Kšœ œ˜Kšœœœ˜#Kšœœœ˜—K˜KšΠbl œœ˜Kšœ:˜AKšœ˜šœ˜K˜Kšœœ œ˜Kšœœ˜-Kšœ œ˜Kšœœ˜Kšœ œ˜Kšœœ˜Kšœ œ˜#Kšœ œ˜'Kšœ œœ ˜!šœ œœΟc˜JK˜—Kšœ œ˜Kšœœœ˜K˜šΟnœœœœ œ œœœ˜bJšœ9˜9Kšœœ˜š œ œœœœœ˜5Kšœœœ˜šœ˜Kšœœœœ%˜MKšœ œœœ˜FKš œ œœœœ˜3Kšœ œœœ ˜MKšœC˜CKšœ˜—Kšœ˜—KšœF˜FK˜K˜—š œœœœœœ œ œœœ˜oKšœœŸ˜-Jšœ9˜9Kšœœ˜š œœœœ ˜"Kšœœœ˜šœ˜Kšœœœœ%˜MKšœ œœœ˜FKš œ œœœœ˜3Kšœ œœœ ˜MKšœC˜CKšœ˜—Kšœ˜—K˜K˜—K˜Kšœœ œ˜Kšœœ#˜7Kšœœ&˜=KšœC˜CK˜Kšœœ˜Kšœ œ˜%Kšœ œœ˜#Kšœœœ œ ˜1Kšœ œœœ˜šœœœœ˜1K˜—Kšœœœœ˜4Kšœ œ˜Kšœ œ˜Kšœœ˜K˜š  œœœœœœ˜.Kšœœœœ˜)K˜—š  œœ)œœœœ˜XKšœ$œœœ˜rK˜K˜—š œ œœ)œ ˜VKšΟb™Kšœœœ˜Kšœœ˜#Kšœœ˜.Kšœ&˜&šœ"œœ˜6K˜Kš œœœ3œœ œ˜šKšœ˜—šœŸ ˜"Kšœ œI˜YKšœœ!˜