DIRECTORY Imager USING [ClassRep, Context, ContextRep, GetProp, SetFont, Show, Warning], ImagerFont USING [Find, Font, MapText, Modify, XChar, XStringProc, Name], ImagerFontFilter USING [CharacterCodeMap, FontMap, OutputMap], ImagerPrivate USING [Class, ClassRep], Prop USING [Put, PropList], IO, RefTab USING [Create, Fetch, Ref, Store], Rope; ImagerFontFilterImpl: CEDAR PROGRAM IMPORTS Imager, ImagerFont, Prop, IO, RefTab, Rope EXPORTS ImagerFontFilter, Imager ~ BEGIN OPEN ImagerFontFilter; ROPE: TYPE ~ Rope.ROPE; Font: TYPE ~ ImagerFont.Font; XChar: TYPE ~ ImagerFont.XChar; XStringProc: TYPE ~ ImagerFont.XStringProc; Context: TYPE ~ Imager.Context; Class: TYPE ~ ImagerPrivate.Class; ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; -- export to Imager BoundOutputMap: TYPE ~ LIST OF BoundOutputMapEntry; BoundOutputMapEntry: TYPE ~ RECORD [newFont: ImagerFont.Font, charMap: CharacterCodeMap]; Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD[ c: Imager.Context, curFont: Font ¬ NIL, curBoundOutputMap: BoundOutputMap ¬ NIL, curMappedFont: Font ¬ NIL, fontMap: FontMap, fontTable: RefTab.Ref, saveStack: LIST OF SaveEntry, msg: IO.STREAM, verbose: BOOL ]; SaveEntry: TYPE ~ RECORD [ curFont: Font, curBoundOutputMap: BoundOutputMap, curMappedFont: Font, ref: REF ]; FilterFonts: PUBLIC PROC [c: Imager.Context, fontMap: FontMap, msg: IO.STREAM, verbose: BOOL] RETURNS [context: Imager.Context] ~ { oldClass: Class ~ c.class; data: Data ~ NEW[DataRep ¬ [c: c, fontMap: fontMap, fontTable: RefTab.Create[], msg: msg, verbose: verbose]]; props: Prop.PropList ~ Prop.Put[c.propList, $FontFilter, data]; class: Class ~ NEW[ClassRep ¬ oldClass­]; class.type ¬ $FontFilter; class.Save ¬ MySave; class.Restore ¬ MyRestore; class.SetFont ¬ MySetFont; class.GetFont ¬ MyGetFont; class.Show ¬ MyShow; class.ShowText ¬ MyShowText; context ¬ NEW[Imager.ContextRep ¬ [class: class, state: c.state, data: c.data, propList: props]]; }; MySetFont: PROC[context: Context, font: Font] ~ { data: Data ~ NARROW[Imager.GetProp[context, $FontFilter]]; subst: BoundOutputMap ¬ NARROW[data.fontTable.Fetch[font].val]; IF subst = NIL THEN { oldName: ROPE ~ ImagerFont.Name[font]; outputMap: OutputMap ¬ NIL; h: BoundOutputMap ~ LIST[[NIL,NIL]]; t: BoundOutputMap ¬ h; canPrint: BOOL ~ data.msg#NIL; printing: BOOL ¬ canPrint AND data.verbose; warn: BOOL ¬ FALSE; FOR p: FontMap ¬ data.fontMap, p.rest UNTIL p=NIL DO IF Rope.Equal[oldName, p.first.inputName, FALSE] THEN { outputMap ¬ p.first.output; warn ¬ p.first.warn; EXIT; }; ENDLOOP; IF outputMap = NIL THEN { charMap: CharacterCodeMap ~ LIST[[bc: 0, ec: WORD.LAST, newbc: 0]]; outputMap ¬ LIST[[newName: oldName, charMap: charMap]]; }; IF warn AND canPrint THEN printing ¬ TRUE; IF warn AND printing THEN data.msg.PutRope[" WARNING:"]; IF printing THEN data.msg.PutF1[" (%g =>", IO.rope[oldName]]; FOR o: OutputMap ¬ outputMap, o.rest UNTIL o=NIL DO newFont: Font; note: ROPE ¬ NIL; IF printing THEN data.msg.PutF1[" %g", IO.rope[o.first.newName]]; newFont ¬ ImagerFont.Find[o.first.newName ! Imager.Warning => {IF printing THEN data.msg.PutF1[" {%g}", IO.rope[error.explanation]]; RESUME}]; newFont ¬ ImagerFont.Modify[newFont, font.charToClient]; t.rest ¬ LIST[[newFont: newFont, charMap: o.first.charMap]]; t ¬ t.rest; ENDLOOP; IF printing THEN data.msg.PutRope[")"]; subst ¬ h.rest; [] ¬ data.fontTable.Store[font, subst]; }; data.curFont ¬ font; IF subst = NIL THEN ERROR; data.curBoundOutputMap ¬ subst; data.curMappedFont ¬ NIL; }; MapChar: PROC [data: Data, charCode: WORD] RETURNS [f: Font, tchar: WORD] ~ { boundMap: BoundOutputMap ~ data.curBoundOutputMap; FOR b: BoundOutputMap ¬ boundMap, b.rest UNTIL b = NIL DO FOR c: CharacterCodeMap ¬ b.first.charMap, c.rest UNTIL c = NIL DO IF charCode IN [c.first.bc..c.first.ec] THEN { f ¬ b.first.newFont; tchar ¬ c.first.newbc+(charCode-c.first.bc); RETURN; }; ENDLOOP; ENDLOOP; f ¬ boundMap.first.newFont; tchar ¬ charCode; IF data.msg#NIL THEN data.msg.PutF[" WARNING: (%03BB|%03BB) not in %g", IO.int[charCode/256], IO.int[charCode MOD 256], IO.rope[ImagerFont.Name[data.curFont]]]; }; MyShow: PROC[context: Context, string: XStringProc, xrel: BOOL] ~ { data: Data ~ NARROW[Imager.GetProp[context, $FontFilter]]; short: NAT ~ 100; long: NAT ~ NAT15.LAST; buf: ARRAY [0..short) OF WORD; xbuf: REF ARRAY [short..long) OF WORD ¬ NIL; nChars: NAT ¬ 0; i: NAT ¬ 0; myCharAction: PROC [char: XChar] ~ { IF nChars = short THEN xbuf ¬ NEW[ARRAY [short..long) OF WORD]; IF nChars < short THEN buf[nChars] ¬ LOOPHOLE[char] ELSE { IF xbuf = NIL THEN xbuf ¬ NEW[ARRAY [short..long) OF WORD]; xbuf[nChars] ¬ LOOPHOLE[char]; }; nChars ¬ nChars + 1; }; C: PROC [index: NAT] RETURNS [WORD] ~ INLINE {RETURN [IF index < short THEN buf[index] ELSE xbuf[index]]}; deltaChars: NAT ¬ 0; f: Font ¬ NIL; myString: XStringProc ~ { c: WORD; [f, c] ¬ MapChar[data, C[i]]; deltaChars ¬ 0; DO ff: Font; charAction[LOOPHOLE[c]]; deltaChars ¬ deltaChars + 1; IF i+deltaChars = nChars THEN EXIT; [ff, c] ¬ MapChar[data, C[i+deltaChars]]; IF ff # f THEN EXIT; ENDLOOP; }; string[myCharAction]; UNTIL i = nChars DO [f, ----] ¬ MapChar[data, C[i]]; IF f # data.curMappedFont THEN { Imager.SetFont[data.c, f]; data.curMappedFont ¬ f; }; Imager.Show[data.c, myString, xrel]; i ¬ i + deltaChars; ENDLOOP; }; MyShowText: PROC [context: Context, text: REF READONLY TEXT, start, len: NAT, xrel: BOOL] ~ { string: XStringProc ~ { ImagerFont.MapText[text, start, len, charAction] }; Imager.Show[context, string, xrel]; }; MySave: PROC[context: Context, all: BOOL] RETURNS [REF] ~ { data: Data ~ NARROW[Imager.GetProp[context, $FontFilter]]; cClass: Class ~ data.c.class; data.saveStack ¬ CONS[[ curFont: data.curFont, curBoundOutputMap: data.curBoundOutputMap, curMappedFont: data.curMappedFont, ref: cClass.Save[context, all] ], data.saveStack]; RETURN [data.saveStack] }; MyRestore: PROC[context: Context, ref: REF] ~ { data: Data ~ NARROW[Imager.GetProp[context, $FontFilter]]; cClass: Class ~ data.c.class; IF NOT (ref=NIL OR ref = data.saveStack) THEN ERROR; cClass.Restore[context, data.saveStack.first.ref]; data.curMappedFont ¬ data.saveStack.first.curMappedFont; data.curBoundOutputMap ¬ data.saveStack.first.curBoundOutputMap; data.curFont ¬ data.saveStack.first.curFont; data.saveStack ¬ data.saveStack.rest; }; MyGetFont: PROC[context: Context] RETURNS[Font] ~ { data: Data ~ NARROW[Imager.GetProp[context, $FontFilter]]; RETURN [data.curFont] }; END. ,ImagerFontFilterImpl.mesa Copyright Σ 1985, 1989, 1992 by Xerox Corporation. All rights reserved. Michael Plass, September 15, 1989 1:14:45 pm PDT Last changed by Pavel on January 18, 1988 2:52:37 pm PST Jean-Marc Frailong January 20, 1988 11:56:16 am PST Willie-s, April 2, 1992 7:30 pm PST Κ–(cedarcode) style•NewlineDelimiter ˜™Icodešœ Οeœ=™HK™0K™8K™3K™#K™—šΟk ˜ KšœžœB˜NKšœ žœ9˜IKšœžœ(˜>Kšœžœ˜&Kšœžœ˜Kšžœ˜Kšœžœ˜)Kšœ˜—K˜KšΠlnœž ˜#Kšžœžœ˜2Kšžœ˜ šœžœžœ˜Kšžœžœžœ˜Kšœžœ˜Kšœžœ˜Kšœ žœ˜+Kšœ žœ˜Kšœžœ˜"Kšœ žœžœΟc˜CK˜Kšœžœžœžœ˜3šœžœžœ7˜YK˜—Kšœžœžœ ˜šœ žœžœ˜Kšœ˜Kšœžœ˜Kšœ$žœ˜(Kšœžœ˜Kšœ˜Kšœ˜Kšœ žœžœ ˜Kšœžœžœ˜Kšœ ž˜ Kšœ˜K˜—šœ žœžœ˜Kšœ˜Kšœ"˜"Kšœ˜Kšœž˜Kšœ˜K˜—šΟn œžœžœ,žœžœ žœžœ˜ƒKšœ˜Kšœ žœ]˜mKšœ?˜?Kšœžœ˜)K˜K˜K˜K˜K˜K˜K˜Kšœ žœT˜aKšœ˜K˜—š‘ œžœ"˜1Kšœ žœ'˜:Kšœžœ!˜?šžœ žœžœ˜Kšœ žœ˜&Kšœžœ˜Kšœžœžœžœ˜$K˜Kšœ žœ žœ˜Kšœ žœ žœ˜+Kšœžœžœ˜šžœ#žœžœž˜4šžœ(žœžœ˜7K˜K˜Kšžœ˜Kšœ˜—Kšžœ˜—šžœ žœžœ˜Kšœžœ žœžœ ˜CKšœ žœ'˜7Kšœ˜—Kšžœžœ žœ žœ˜*Kšžœžœ žœ˜8Kšžœ žœžœ˜=šžœ"žœžœž˜3Kšœ˜Kšœžœžœ˜Kšžœ žœžœ˜A˜=Kš œžœ žœžœžœ˜P—K˜8Kšœ žœ/˜