DIRECTORY Ascii USING [Lower], Atom USING [GetPName, MakeAtom], Checksum USING [ComputeChecksum], Convert USING [RopeFromInt], NodeProps USING [Is], NodeStyle USING [DataEntry, DataList, GetStyleName, IntegerValue, MaxNestingLevel, RealCode, Style, SetReal, StyleBody], NodeStyleOps USING [ExtObjPair, LocalStyle, LocalStyleRec, OfStyle], NodeStyleWorks USING [BadStyleFile, ExecuteLooksInStyle, ExecuteNameInStyle, ExecuteObjectInStyle, FreeFrame, GetFrame, GetStyleDict, RunStyle, StyleParamKey], Rope USING [Cat, Concat, ROPE, Translate], Tioga, TiogaPrivate USING [AddEditNotifyProc, Change, ChangeSet], TJaM USING [Frame, NumberRep, Object, TryToLoad]; NodeStyleOpsImpl: CEDAR MONITOR LOCKS env USING env: Env IMPORTS Ascii, Atom, Checksum, Convert, NodeProps, NodeStyle, NodeStyleWorks, Rope, Tioga, TiogaPrivate, TJaM EXPORTS NodeStyleOps ~ BEGIN OPEN NodeStyle, NodeStyleOps; ROPE: TYPE ~ Rope.ROPE; Frame: TYPE ~ TJaM.Frame; Object: TYPE ~ TJaM.Object; lastIntAsReal: REAL _ LAST[INT]; firstIntAsReal: REAL _ FIRST[INT]; IntegerValue: PUBLIC PROC [value: REAL _ 0.0] RETURNS [INT] ~ { RETURN [SELECT value FROM > lastIntAsReal => LAST[INT], < firstIntAsReal => FIRST[INT], ENDCASE => Real.Round[value]]; }; realArray: REF ARRAY RealCode OF REAL ~ NEW[ARRAY RealCode OF REAL _ ALL[0.0]]; nextFreeRealCode: RealCode _ 1; overflowCount: INT _ 0; EnterReal: ENTRY PROC [value: REAL _ 0.0] RETURNS [code: RealCode] ~ { ENABLE UNWIND => NULL; FOR code _ RealCode.FIRST, code+1 UNTIL code=nextFreeRealCode DO IF realArray[code]=value THEN RETURN; -- value already in realArray ENDLOOP; IF code=overflow THEN overflowCount _ overflowCount+1 -- realArray is full ELSE { realArray[code] _ value; nextFreeRealCode _ code+1 }; -- enter in realArray }; SetReal: PUBLIC PROC [s: Style, param: RealParam, value: REAL _ 0.0] ~ { code: RealCode ~ EnterReal[value]; IF code=overflow THEN s.dataList _ NEW[DataEntry _ [s.dataList, real[param, value]]]; s.real[param] _ code; }; GetReal: PUBLIC PROC [s: Style, param: RealParam] RETURNS [value: REAL _ 0.0] ~ { code: RealCode ~ s.real[param]; IF code#overflow THEN RETURN[realArray[code]] ELSE { FOR entry: REF DataEntry _ s.dataList, entry.next UNTIL entry=NIL DO WITH entry SELECT FROM e: REF DataEntry.real => IF e.param=param THEN RETURN[e.value]; ENDCASE; ENDLOOP; ERROR; -- failed to find it on the data list -- }; }; GetTabLoc: PUBLIC PROC [stop: TabStop, s:Style] RETURNS [REAL _ 0.0] ~ { code: RealCode; IF (code _ stop.loc) # overflow THEN RETURN [realArray[code]]; RETURN [GetTabOverflow[s,stop,loc]]; }; GetTabLeaderSpacing: PUBLIC PROC [stop: LeaderTabStop, s:Style] RETURNS [REAL _ 0.0] ~ { code: RealCode; IF (code _ stop.spacing) # overflow THEN RETURN [realArray[code]]; RETURN [GetTabOverflow[s,stop,spacing]]; }; GetTabRuleWeight: PUBLIC PROC [stop: RuleTabStop, s:Style] RETURNS [REAL _ 0.0] ~ { code: RealCode; IF (code _ stop.weight) # overflow THEN RETURN [realArray[code]]; RETURN [GetTabOverflow[s,stop,weight]]; }; GetTabRuleVShift: PUBLIC PROC [stop: RuleTabStop, s:Style] RETURNS [REAL _ 0.0] ~ { code: RealCode; IF (code _ stop.vshift) # overflow THEN RETURN [realArray[code]]; RETURN [GetTabOverflow[s,stop,vshift]]; }; GetTabRealCode: PUBLIC PROC [s: Style, stop: TabStop, which: TabRealParam, value: REAL _ 0.0] RETURNS [code: RealCode] ~ { code _ EnterReal[value]; IF code=overflow THEN s.dataList _ NEW[DataEntry _ [s.dataList, tab[stop, which, value]]]; }; GetRulesTabCount: PUBLIC PROC [stop: RulesTabStop] RETURNS [count: INT] ~ { RETURN [stop.rules.length]; }; GetRulesTabInfo: PUBLIC PROC [stop: RulesTabStop, num: INT] RETURNS [weight, vshift: REAL] ~ { weight _ stop.rules.array[num].weight; vshift _ stop.rules.array[num].vshift; }; GetTabOverflow: PROC [s: Style, stop: TabStop, which: TabRealParam] RETURNS [value: REAL _ 0.0] ~ { FOR x: DataList _ s.dataList, x.next UNTIL x=NIL DO WITH x SELECT FROM xx: REF DataEntry.tab => IF xx.tabStop=stop AND xx.which=which THEN RETURN [xx.value]; ENDCASE; ENDLOOP; ERROR -- failed to find it on the data list -- }; pointsPerPica: PUBLIC REAL _ 12.0; pointsPerInch: PUBLIC REAL _ 1.0/0.0138370; -- 72.27 pointsPerCentimeter: PUBLIC REAL _ pointsPerInch/2.540; pointsPerMillimeter: PUBLIC REAL _ pointsPerCentimeter/10; pointsPerDidot: PUBLIC REAL _ pointsPerCentimeter/26.60; pointsPerFil: PUBLIC REAL _ 10000.0; pointsPerFill: PUBLIC REAL _ pointsPerFil*pointsPerFil; pointsPerFilll: PUBLIC REAL _ pointsPerFill*pointsPerFil; LowerCaseRope: PROC [rope: ROPE] RETURNS [ROPE] ~ { lower: Rope.TranslatorType ~ { new _ Ascii.Lower[old] }; RETURN [Rope.Translate[base: rope, translator: lower]]; }; LowerCaseAtom: PROC [atom: ATOM] RETURNS [ATOM] ~ { RETURN [Atom.MakeAtom[LowerCaseRope[Atom.GetPName[atom]]]]; }; Create: PUBLIC PROC RETURNS [Style] ~ { RETURN [NEW[StyleBody]]; }; Copy: PUBLIC PROC [dest, source: Style] ~ { dest^ _ source^; }; Alloc: PUBLIC ENTRY PROC [env: Env] RETURNS [s: Style] ~ { OPEN env; ENABLE UNWIND => NULL; IF s3 # NIL THEN { s _ s3; s3 _ NIL } ELSE IF s2 # NIL THEN { s _ s2; s2 _ NIL } ELSE IF s1 # NIL THEN { s _ s1; s1 _ NIL } ELSE s _ Create[]; }; Free: PUBLIC ENTRY PROC [env: Env, s: Style] ~ { OPEN env; ENABLE UNWIND => NULL; IF s3 = NIL THEN s3 _ s ELSE IF s2 = NIL THEN s2 _ s ELSE IF s1 = NIL THEN s1 _ s; }; WithFrame: PROC [style: Style, styleName: ATOM, kind: StyleKind, action: PROC [Frame]] ~ { frame: Frame ~ NodeStyleWorks.GetFrame[style, styleName, kind]; action[frame]; NodeStyleWorks.FreeFrame[frame, styleName, kind]; }; LoadStyle: PUBLIC PROC [name: ATOM] RETURNS [ok: BOOL] ~ { LoadStyleAction: PROC [frame: Frame] ~ { [] _ NodeStyleWorks.GetStyleDict[frame, name, screen]; }; WithFrame[NIL, NIL, screen, LoadStyleAction]; RETURN [TRUE]; }; DefineStyle: PUBLIC PROC [name: ATOM, def: ROPE] RETURNS [ok: BOOL] ~ { DefineStyleAction: PROC [frame: Frame] ~ { IF def = NIL THEN NodeStyleWorks.BadStyleFile[frame, name] ELSE [] _ NodeStyleWorks.GetStyleDict[frame, name, screen, def]; }; WithFrame[NIL, NIL, screen, DefineStyleAction]; RETURN [TRUE]; }; ReloadStyle: PUBLIC PROC [name: ATOM] RETURNS [ok: BOOL] ~ { name _ ForceLowerName[name]; FOR kind: NodeStyleOps.OfStyle IN NodeStyleOps.OfStyle DO frame: Frame _ NodeStyleWorks.GetFrame[NIL, NIL, kind]; ok _ NodeStyleWorks.RunStyle[frame, name]; IF ~ok THEN NodeStyleWorks.BadStyleFile[frame, name]; NodeStyleWorks.FreeFrame[frame, NIL, kind]; ENDLOOP; }; SetDefaultStyle: PUBLIC PROC [name: ROPE] ~ { defaultStyleName _ Atom.MakeAtom[ForceRopeLower[name]]; defaultStyle.name[style] _ defaultStyleName; FlushCaches[]; }; SetExtensionStyles: PUBLIC PROC [value: LIST OF ROPE] ~ { defaultStylesForExtensions _ NIL; UNTIL value=NIL OR value.rest=NIL DO ext: ATOM _ Atom.MakeAtom[ForceRopeLower[value.first]]; -- the extension styleObject: Object _ Rope.Cat["\"", ForceRopeLower[value.rest.first], "\" style"]; defaultStylesForExtensions _ CONS[[ext, styleObject], defaultStylesForExtensions]; value _ value.rest.rest; ENDLOOP; FlushCaches[]; }; ReadStyleDef: PROC [name: ATOM, specs: ROPE] RETURNS [value: REF] ~ { GenLocalName: ENTRY PROC RETURNS [gen: ROPE] ~ { localStyleNumber _ localStyleNumber + 1; gen _ Rope.Concat["LocalStyle-", Convert.RopeFromInt[localStyleNumber]]; }; localStyle: LocalStyle _ NEW[LocalStyleRec]; localStyleName: ROPE ~ GenLocalName[]; localStyle.name _ Atom.MakeAtom[localStyleName]; localStyle.def _ specs; [] _ DefineStyle[localStyle.name, specs]; RETURN [localStyle]; }; WriteStyleDef: PROC [name: ATOM, value: REF] RETURNS [specs: ROPE] ~ { localStyle: LocalStyle _ NARROW[value]; RETURN [IF localStyle=NIL THEN NIL ELSE localStyle.def]; }; CopyStyleDef: PROC [name: ATOM, value: REF] RETURNS [new: REF] ~ { RETURN [value]; }; ApplyAll: PUBLIC PROC [ref: Style, node: Tioga.Node, kind: OfStyle _ screen] ~ { [] _ DoApplyAll[ref, node, kind]; }; DoApplyAll: PROC [ref: Style, node: Tioga.Node, kind: OfStyle] RETURNS [depth: CARDINAL] ~ { found: BOOL; parent: Tioga.Node; alt: ATOM; IF node = NIL THEN { ref^ _ defaultStyle^; RETURN [0] }; [found, depth] _ FindInApplyAllCache[ref, node, kind]; IF found THEN RETURN [depth+1]; parent _ Tioga.Parent[node]; alt _ IF parent=NIL THEN rootFormatName ELSE defaultFormatName; depth _ DoApplyAll[ref, parent, kind]; ApplyForNode[ref, node, alt, kind]; EnterInApplyAllCache[ref, node, depth]; RETURN [depth+1]; }; ApplyForNode: PUBLIC PROC [ref: Style, node: Tioga.Node, alt: ATOM, kind: OfStyle] ~ { ext: ATOM; ref.isComment _ IF node # NIL THEN node.comment ELSE FALSE; ref.print _ (kind = print); ref.nestingLevel _ MIN[Tioga.Level[node], MaxNestingLevel]; IF node.hasstyledef THEN { localStyle: LocalStyle _ NARROW[Tioga.GetProp[node, $StyleDef]]; IF localStyle # NIL THEN ref.name[style] _ localStyle.name; }; IF node.hasprefix THEN ApplyObject[ref, Tioga.GetProp[node, $Prefix], kind] ELSE IF ref.nestingLevel=0 -- root node -- AND -- check for file extension default (ext _ NARROW[Tioga.GetProp[node, $FileExtension]]) # NIL THEN FOR list: LIST OF ExtObjPair _ defaultStylesForExtensions, list.rest UNTIL list = NIL DO IF list.first.fileExtension # ext THEN LOOP; ApplyObject[ref, list.first.styleObject, kind]; EXIT; ENDLOOP; ApplyFormat[ref, node.formatName, alt, kind]; IF node.haspostfix THEN ApplyObject[ref, Tioga.GetProp[node, $Postfix], kind]; }; ApplyCacheRep: TYPE ~ RECORD [ depth: CARDINAL _ 0, -- next free entry results: REF ApplyCacheResults, nodes: REF ApplyCacheNodes, probes, hits, saves: INT _ 0 ]; applyCacheSize: CARDINAL ~ 8; -- number of levels deep in tree ApplyCacheNodes: TYPE ~ ARRAY [0..applyCacheSize) OF Tioga.Node; ApplyCacheResults: TYPE ~ ARRAY [0..applyCacheSize) OF StyleBody; InitApplyCacheRecord: PROC ~ { applyCache.results _ NEW[ApplyCacheResults]; applyCache.nodes _ NEW[ApplyCacheNodes]; }; RemoveAllFromApplyAllCache: PUBLIC PROC ~ { FlushApplyAllCache[] }; FlushApplyAllCache: PUBLIC ENTRY PROC [init: BOOL _ FALSE] ~ { ENABLE UNWIND => NULL; ClearApplyAllCache[init]; }; ClearApplyAllCache: INTERNAL PROC [init: BOOL] ~ { FOR i: CARDINAL IN [0..applyCacheSize) DO applyCache.nodes[i] _ NIL; ENDLOOP; applyCache.depth _ 0; }; RemoveNodeFromApplyAllCache: PUBLIC ENTRY PROC [node: Tioga.Node] ~ { ENABLE UNWIND => NULL; nodes: REF ApplyCacheNodes _ applyCache.nodes; FOR i: CARDINAL IN [0..applyCache.depth) DO IF nodes[i]=node THEN { -- clear from here on FOR j: CARDINAL IN [i..applyCacheSize) DO nodes[j] _ NIL; ENDLOOP; applyCache.depth _ i; EXIT; }; ENDLOOP; }; FindInApplyAllCache: ENTRY PROC [ref: Style, node: Tioga.Node, kind: OfStyle] RETURNS [found: BOOL, depth: CARDINAL] ~ { ENABLE UNWIND => NULL; nodes: REF ApplyCacheNodes _ applyCache.nodes; print: BOOL ~ (kind=print); -- if true, then find result with print true also applyCache.probes _ applyCache.probes+1; FOR i: CARDINAL DECREASING IN [0..applyCache.depth) DO IF nodes[i]=node AND print=applyCache.results[i].print THEN { -- found it applyCache.hits _ applyCache.hits+1; applyCache.saves _ applyCache.saves+i+1; ref^ _ applyCache.results[i]; RETURN [TRUE, i] }; ENDLOOP; RETURN [FALSE, 0]; }; EnterInApplyAllCache: ENTRY PROC [ref: Style, node: Tioga.Node, depth: CARDINAL] ~ { ENABLE UNWIND => NULL; nodes: REF ApplyCacheNodes _ applyCache.nodes; IF depth >= applyCacheSize THEN RETURN; nodes[depth] _ node; applyCache.results[depth] _ ref^; FOR i: CARDINAL IN [depth+1..applyCacheSize) DO nodes[i] _ NIL; ENDLOOP; applyCache.depth _ depth+1; }; Change: TYPE ~ TiogaPrivate.Change; Notify: PROC [change: REF READONLY Change] ~ { DoNode: PROC [node: Tioga.Node] ~ { IF Tioga.FirstChild[node] # NIL THEN FlushApplyAllCache[] ELSE RemoveNodeFromApplyAllCache[node] }; WITH change SELECT FROM x: REF READONLY Change.InsertingNode => IF Tioga.FirstChild[x.new] # NIL THEN FlushApplyAllCache[]; x: REF READONLY Change.MovingNodes => FlushApplyAllCache[]; x: REF READONLY Change.NodeNesting => IF x.first = x.last -- only changing one node AND Tioga.FirstChild[x.first] = NIL -- node has no children THEN SELECT x.change FROM +1 => -- increasing nesting in tree IF Tioga.Next[x.first] = NIL THEN RemoveNodeFromApplyAllCache[x.first] ELSE FlushApplyAllCache[]; -1 => -- decreasing nesting in tree RemoveNodeFromApplyAllCache[x.first]; ENDCASE => FlushApplyAllCache[] ELSE FlushApplyAllCache[]; x: REF READONLY Change.ChangingFormat => DoNode[x.node]; x: REF READONLY Change.ChangingProp => { IF NodeProps.Is[x.propAtom, $Visible] THEN DoNode[x.node]; }; ENDCASE => ERROR; -- not expecting notify for any other kinds of changes }; HashStyle: PROC [ref: Style, looks: Tioga.Looks _ Tioga.noLooks, anotherRef: REF _ NIL] RETURNS [CARDINAL] ~ TRUSTED { Bits: TYPE ~ MACHINE DEPENDENT RECORD [ REF, REF, REF, REF, RealCode, RealCode, RealCode, RealCode, Tioga.Looks]; bits: Bits _ [ref.name[style], ref.name[fontPrefix], ref.name[fontFamily], anotherRef, ref.real[fontSize], ref.real[leftIndent], ref.real[leading], 0, looks]; RETURN [Checksum.ComputeChecksum[3145, SIZE[Bits], @bits]]; }; ruleCacheSize: CARDINAL ~ 64; -- should be a power of 2 ruleCacheMax: CARDINAL ~ (ruleCacheSize*4)/5; -- don't fill too full RuleCacheLoc: TYPE ~ CARDINAL[0..ruleCacheSize); RuleCacheNames: TYPE ~ ARRAY RuleCacheLoc OF ATOM; RuleCacheBodies: TYPE ~ ARRAY RuleCacheLoc OF StyleBody; RuleCache: TYPE ~ REF RuleCacheRep; RuleCacheRep: TYPE ~ RECORD [ count: CARDINAL _ 0, -- number of entries currently in use names: REF RuleCacheNames, inputs: REF RuleCacheBodies, results: REF RuleCacheBodies, probes, hits: INT _ 0 ]; InitRuleCacheInfo: PROC ~ { ruleCache.names _ NEW[RuleCacheNames]; ruleCache.inputs _ NEW[RuleCacheBodies]; ruleCache.results _ NEW[RuleCacheBodies]; }; FlushRuleCache: ENTRY PROC [init: BOOL _ FALSE] ~ { ENABLE UNWIND => NULL; ClearRuleCache[]; }; ClearRuleCache: INTERNAL PROC [init: BOOL _ FALSE] ~ { IF init OR ruleCache.count#0 THEN { ruleCache.count _ 0; FOR i: RuleCacheLoc IN RuleCacheLoc DO ruleCache.names[i] _ NIL; ENDLOOP; }; }; ApplyFormat: PUBLIC PROC [ref: Style, name, alt: ATOM, kind: OfStyle] ~ { input: StyleBody; initloc: RuleCacheLoc; FindInRuleCache: ENTRY PROC RETURNS [BOOL] ~ { ENABLE UNWIND => NULL; loc: RuleCacheLoc _ initloc; ruleCache.probes _ ruleCache.probes+1; DO -- search ruleCache SELECT ruleCache.names[loc] FROM name => IF ruleCache.inputs[loc] = ref^ THEN { ref^ _ ruleCache.results[loc]; ruleCache.hits _ ruleCache.hits+1; RETURN [TRUE]; }; NIL => RETURN [FALSE]; -- this is an unused entry ENDCASE; loc _ (loc+1) MOD ruleCacheSize; IF loc=initloc THEN RETURN [FALSE]; ENDLOOP; }; PutInRuleCache: ENTRY PROC ~ { ENABLE UNWIND => NULL; loc: RuleCacheLoc _ initloc; IF ruleCache.count = ruleCacheMax THEN ClearRuleCache[]; DO -- search ruleCache for place to put the entry SELECT ruleCache.names[loc] FROM name => IF ruleCache.inputs[loc] = input THEN RETURN; -- already in cache NIL => EXIT; -- this is an unused entry ENDCASE; loc _ (loc+1) MOD ruleCacheSize; IF loc=initloc THEN ERROR; -- cache full ENDLOOP; ruleCache.names[loc] _ name; ruleCache.inputs[loc] _ input; ruleCache.results[loc] _ ref^; ruleCache.count _ ruleCache.count+1; }; IF name=NIL AND (name _ alt)=NIL THEN RETURN; initloc _ HashStyle[ref, , name] MOD ruleCacheSize; IF FindInRuleCache[] THEN RETURN; input _ ref^; -- save the input value of the record IF NodeStyleWorks.ExecuteNameInStyle[ref, kind, name] THEN PutInRuleCache[] ELSE IF name#alt THEN ApplyFormat[ref, alt, NIL, kind]; }; looksCacheSize: CARDINAL ~ 16; -- should be a power of 2 looksCacheMax: CARDINAL ~ (looksCacheSize*4)/5; -- don't fill too full LooksCacheLoc: TYPE ~ CARDINAL[0..looksCacheSize); LooksCacheLooks: TYPE ~ ARRAY LooksCacheLoc OF Tioga.Looks; LooksCacheBodies: TYPE ~ ARRAY LooksCacheLoc OF StyleBody; LooksCache: TYPE ~ REF LooksCacheRep; LooksCacheRep: TYPE ~ RECORD [ count: CARDINAL _ 0, looks: REF LooksCacheLooks, inputs: REF LooksCacheBodies, results: REF LooksCacheBodies, probes, hits: INT _ 0 ]; InitLooksCacheInfo: PROC ~ { looksCache.looks _ NEW[LooksCacheLooks]; looksCache.inputs _ NEW[LooksCacheBodies]; looksCache.results _ NEW[LooksCacheBodies]; }; FlushLooksCache: ENTRY PROC [init: BOOL _ FALSE] ~ { ENABLE UNWIND => NULL; ClearLooksCache[]; }; ClearLooksCache: PROC [init: BOOL _ FALSE] ~ { IF ~init AND looksCache.count = 0 THEN RETURN; looksCache.count _ 0; FOR i: LooksCacheLoc IN LooksCacheLoc DO looksCache.looks[i] _ Tioga.noLooks; ENDLOOP; }; ApplyLooks: PUBLIC PROC [ref: Style, looks: Tioga.Looks, kind: OfStyle] ~ { initloc: LooksCacheLoc; input: StyleBody; FindInLooksCache: ENTRY PROC RETURNS [BOOL] ~ { ENABLE UNWIND => NULL; loc: LooksCacheLoc _ initloc; looksCache.probes _ looksCache.probes+1; DO -- search looksCache SELECT looksCache.looks[loc] FROM looks => IF looksCache.inputs[loc] = ref^ THEN { ref^ _ looksCache.results[loc]; looksCache.hits _ looksCache.hits+1; RETURN [TRUE]; }; Tioga.noLooks => EXIT; -- this is an unused entry ENDCASE; loc _ (loc+1) MOD looksCacheSize; IF loc=initloc THEN EXIT; ENDLOOP; RETURN [FALSE]; }; PutInLooksCache: ENTRY PROC ~ { ENABLE UNWIND => NULL; loc: LooksCacheLoc _ initloc; IF looksCache.count = looksCacheMax THEN ClearLooksCache[]; DO -- search looksCache for place to put the entry SELECT looksCache.looks[loc] FROM looks => IF looksCache.inputs[loc] = input THEN RETURN; -- already in cache Tioga.noLooks => EXIT; -- this is an unused entry ENDCASE; loc _ (loc+1) MOD looksCacheSize; IF loc=initloc THEN ERROR; -- cache full ENDLOOP; looksCache.looks[loc] _ looks; looksCache.inputs[loc] _ input; looksCache.results[loc] _ ref^; looksCache.count _ looksCache.count+1; }; IF looks = Tioga.noLooks THEN RETURN; initloc _ HashStyle[ref, looks] MOD looksCacheSize; IF FindInLooksCache[] THEN RETURN; input _ ref^; -- save the input value of the record IF NodeStyleWorks.ExecuteLooksInStyle[ref, kind, looks] THEN PutInLooksCache[]; }; objectCacheSize: CARDINAL ~ 16; -- should be a power of 2 objectCacheMax: CARDINAL ~ (objectCacheSize*4)/5; -- don't fill too full ObjectCacheLoc: TYPE ~ CARDINAL[0..objectCacheSize); ObjectCacheObjects: TYPE ~ ARRAY [0..objectCacheSize) OF Object; ObjectCacheBodies: TYPE ~ ARRAY [0..objectCacheSize) OF StyleBody; ObjectCacheRep: TYPE ~ RECORD [ count: CARDINAL[0..objectCacheMax], objects: REF ObjectCacheObjects, inputs: REF ObjectCacheBodies, results: REF ObjectCacheBodies, probes, hits: INT _ 0 ]; InitObjectCacheInfo: PROC ~ { objectCache.objects _ NEW[ObjectCacheObjects]; objectCache.inputs _ NEW[ObjectCacheBodies]; objectCache.results _ NEW[ObjectCacheBodies]; }; FlushObjectCache: ENTRY PROC [init: BOOL _ FALSE] ~ { ENABLE UNWIND => NULL; ClearObjectCache[]; }; ClearObjectCache: PROC [init: BOOL _ FALSE] ~ { IF ~init AND objectCache.count = 0 THEN RETURN; objectCache.count _ 0; FOR i: ObjectCacheLoc IN ObjectCacheLoc DO objectCache.objects[i] _ NIL; ENDLOOP; }; ApplyObject: PUBLIC PROC [ref: Style, object: Object, kind: OfStyle _ screen] ~ { input: StyleBody; initloc: ObjectCacheLoc; FindInObjectCache: ENTRY PROC RETURNS [BOOL] ~ { ENABLE UNWIND => NULL; loc: ObjectCacheLoc _ initloc; objectCache.probes _ objectCache.probes+1; DO -- search objectCache SELECT objectCache.objects[loc] FROM object => IF objectCache.inputs[loc] = ref^ THEN { ref^ _ objectCache.results[loc]; objectCache.hits _ objectCache.hits+1; RETURN [TRUE]; }; NIL => EXIT; -- this is an unused entry ENDCASE; loc _ (loc+1) MOD objectCacheSize; IF loc=initloc THEN EXIT; ENDLOOP; RETURN [FALSE]; }; PutInObjectCache: ENTRY PROC ~ { ENABLE UNWIND => NULL; loc: ObjectCacheLoc _ initloc; IF objectCache.count = objectCacheMax THEN ClearObjectCache[]; DO -- search objectCache for place to put the entry SELECT objectCache.objects[loc] FROM object => IF objectCache.inputs[loc] = input THEN RETURN; -- already in cache NIL => EXIT; -- this is an unused entry ENDCASE; loc _ (loc+1) MOD objectCacheSize; IF loc=initloc THEN ERROR; -- cache full ENDLOOP; objectCache.objects[loc] _ object; objectCache.inputs[loc] _ input; objectCache.results[loc] _ ref^; objectCache.count _ objectCache.count+1; }; IF object = nullObject THEN RETURN; initloc _ HashStyle[ref, , object] MOD objectCacheSize; IF FindInObjectCache[] THEN RETURN; input _ ref^; -- save the input value of the record IF NodeStyleWorks.ExecuteObjectInStyle[ref, kind, object] THEN PutInObjectCache[]; }; FlushCaches: PUBLIC ENTRY PROC ~ { ENABLE UNWIND => NULL; ClearCaches[FALSE]; }; ClearCaches: PROC [init: BOOL] ~ { ClearApplyAllCache[init]; ClearRuleCache[init]; ClearLooksCache[init]; ClearObjectCache[init]; }; nonNumeric: PUBLIC ERROR ~ CODE; GetStyleParam: PUBLIC PROC [s: Style, name: ATOM, styleName: ATOM, kind: OfStyle] RETURNS [r: REAL] ~ { obj: Object _ GetStyleParamObj[s, name, styleName, kind]; WITH obj SELECT FROM x: REF TJaM.NumberRep.int => r _ x.int; x: REF TJaM.NumberRep.real => r _ x.real; ENDCASE => ERROR nonNumeric; RETURN [r]; }; GetStyleParamI: PUBLIC PROC [s: Style, name: ATOM, styleName: ATOM, kind: OfStyle] RETURNS [i: INTEGER] ~ { obj: Object _ GetStyleParamObj[s, name, styleName, kind]; WITH obj SELECT FROM x: REF TJaM.NumberRep.int => i _ x.int; x: REF TJaM.NumberRep.real => i _ NodeStyle.IntegerValue[x.real]; ENDCASE => ERROR nonNumeric; RETURN [i]; }; GetStyleParamObj: PUBLIC PROC [s: Style, name: ATOM, styleName: ATOM, kind: OfStyle] RETURNS [obj: Object] ~ { frame: Frame; key: ATOM _ NodeStyleWorks.StyleParamKey[name]; FOR x: DataList _ s.dataList, x.next UNTIL x=NIL DO WITH x SELECT FROM xx: REF NodeStyle.DataEntry.object => IF xx.name = key THEN RETURN[xx.object]; ENDCASE; ENDLOOP; frame _ NodeStyleWorks.GetFrame[s, styleName, kind]; obj _ TJaM.TryToLoad[frame, key].val; NodeStyleWorks.FreeFrame[frame, styleName, kind]; RETURN [obj]; }; StyleNameForNode: PUBLIC PROC [node: Tioga.Node] RETURNS [name: ATOM] ~ { s: Style _ Alloc[]; ApplyAll[s, node]; name _ GetStyleName[s]; Free[s]; }; InitializeDefaultStyle: PUBLIC PROC [world: Tioga.World, suggestedStyle: ROPE] ~ { changeSet: TiogaPrivate.ChangeSet; PointsPerInch: REAL ~ 1.0/0.0138370; changeSet[ChangingProp] _ TRUE; changeSet[ChangingFormat] _ TRUE; changeSet[MovingNodes] _ TRUE; changeSet[NodeNesting] _ TRUE; changeSet[InsertingNode] _ TRUE; TiogaPrivate.AddEditNotifyProc[world, Notify, after, high, changeSet]; InitApplyCacheRecord[]; InitRuleCacheInfo[]; InitLooksCacheInfo[]; InitObjectCacheInfo[]; ClearCaches[TRUE]; defaultStyle _ Create[]; defaultFormatName _ $default; rootFormatName _ $root; defaultStyle.name[fontFamily] _ $Helvetica; SetReal[defaultStyle, fontSize, 10]; SetReal[defaultStyle, leading, 12]; SetReal[defaultStyle, tabStops, 4]; SetReal[defaultStyle, pageWidth, 8.5*PointsPerInch]; SetReal[defaultStyle, pageLength, 11*PointsPerInch]; SetReal[defaultStyle, leftMargin, 1*PointsPerInch]; SetReal[defaultStyle, rightMargin, 1*PointsPerInch]; SetReal[defaultStyle, topMargin, 1*PointsPerInch]; SetReal[defaultStyle, bottomMargin, 1*PointsPerInch]; SetReal[defaultStyle, lineLength, 6.5*PointsPerInch]; SetReal[defaultStyle, underlineThickness, 1]; SetReal[defaultStyle, underlineDescent, 1]; SetReal[defaultStyle, strikeoutThickness, 1]; SetReal[defaultStyle, strikeoutAscent, 4]; Tioga.RegisterProp[name: $StyleDef, reader: ReadStyleDef, writer: WriteStyleDef, copier: CopyStyleDef]; SetDefaultStyle[suggestedStyle]; }; ROPE: TYPE ~ Rope.ROPE; Frame: TYPE ~ TJaM.Frame; OfStyle: TYPE ~ NodeStyleOps.OfStyle; Object: TYPE ~ TJaM.Object; FrameInfo: TYPE ~ REF FrameInfoBody; FrameInfoBody: TYPE ~ RECORD [ frame: Frame, style: Style, rest: FrameInfo ]; GetFrame: PUBLIC PROC [style: Style, styleName: ATOM, kind: OfStyle] RETURNS [frame: Frame] ~ { found: BOOL; AllocFrame: ENTRY PROC [name: ATOM, kind: OfStyle] ~ { ENABLE UNWIND => NULL; allocFrameCalls _ allocFrameCalls+1; IF name # NIL THEN { IF name = styleName1 AND kind = styleKind1 AND freeFrame1 # NIL THEN { frame _ freeFrame1; freeFrame1 _ NIL; RETURN }; IF name = styleName2 AND kind = styleKind2 AND freeFrame2 # NIL THEN { frame _ freeFrame2; freeFrame2 _ NIL; RETURN }; IF name = styleName3 AND kind = styleKind3 AND freeFrame3 # NIL THEN { frame _ freeFrame3; freeFrame3 _ NIL; RETURN }; IF name = styleName4 AND kind = styleKind4 AND freeFrame4 # NIL THEN { frame _ freeFrame4; freeFrame4 _ NIL; RETURN }}; IF freeFrame1 # NIL THEN { frame _ freeFrame1; freeFrame1 _ NIL } ELSE IF freeFrame2 # NIL THEN { frame _ freeFrame2; freeFrame2 _ NIL } ELSE IF freeFrame3 # NIL THEN { frame _ freeFrame3; freeFrame3 _ NIL } ELSE IF freeFrame4 # NIL THEN { frame _ freeFrame4; freeFrame4 _ NIL } ELSE { frame _ TJaM.NewFrame[]; frameAlloc _ frameAlloc+1; TJaM.Begin[frame, styledict]; }; }; SaveStyleInfo: ENTRY PROC ~ { ENABLE UNWIND => NULL; IF frame1 = NIL THEN { frame1 _ frame; style1 _ style } ELSE IF frame2 = NIL THEN { frame2 _ frame; style2 _ style } ELSE IF frame3 = NIL THEN { frame3 _ frame; style3 _ style } ELSE IF frame4 = NIL THEN { frame4 _ frame; style4 _ style } ELSE FOR lst: FrameInfo _ frameList, lst.rest UNTIL lst=NIL DO IF lst.frame = NIL THEN { lst.frame _ frame; lst.style _ style; EXIT }; REPEAT FINISHED => frameList _ NEW[FrameInfoBody _ [frame, style, frameList]]; ENDLOOP; }; AllocFrame[styleName, kind]; -- use styleName and kind as hint about which to allocate IF styleName # NIL THEN { styleNameObj: Object; done: BOOL _ FALSE; [found, styleNameObj] _ TJaM.TryToLoad[frame, styleDictName]; IF found THEN { -- some style dictionary on stack already IF TypeCheckName[styleNameObj] = styleName THEN { -- still must check kind of style kindNameObj: Object; [found, kindNameObj] _ TJaM.TryToLoad[frame, styleKindName]; IF found AND TypeCheckName[kindNameObj] = kindNames[kind] THEN done _ TRUE; }; -- already there IF NOT done THEN -- get rid of top dictionary WHILE TJaM.DictTop[frame] # styledict DO TJaM.End[frame]; ENDLOOP; }; IF NOT done THEN TJaM.Begin[frame, GetStyleDict[frame, styleName, kind]] } ELSE WHILE TJaM.DictTop[frame] # styledict DO TJaM.End[frame] ENDLOOP; SaveStyleInfo[]; }; FreeFrame: PUBLIC ENTRY PROC [frame: Frame, styleName: ATOM, kind: OfStyle] ~ { ENABLE UNWIND => NULL; freeFrameCalls _ freeFrameCalls+1; IF freeFrame1 = NIL THEN { freeFrame1 _ frame; styleName1 _ styleName; styleKind1 _ kind } ELSE IF freeFrame2 = NIL THEN { freeFrame2 _ frame; styleName2 _ styleName; styleKind2 _ kind } ELSE IF freeFrame3 = NIL THEN { freeFrame3 _ frame; styleName3 _ styleName; styleKind3 _ kind } ELSE IF freeFrame4 = NIL THEN { freeFrame4 _ frame; styleName4 _ styleName; styleKind4 _ kind } ELSE { frameFree _ frameFree+1; }; -- let garbage collector find it SELECT frame FROM frame1 => { frame1 _ NIL; style1 _ NIL }; frame2 => { frame2 _ NIL; style2 _ NIL }; frame3 => { frame3 _ NIL; style3 _ NIL }; frame4 => { frame4 _ NIL; style4 _ NIL }; ENDCASE => FOR lst: FrameInfo _ frameList, lst.rest UNTIL lst=NIL DO IF lst.frame = frame THEN { lst.frame _ NIL; lst.style _ NIL; EXIT }; ENDLOOP; }; StyleForFrame: PUBLIC PROC [frame: Frame] RETURNS [style: Style] ~ { GetIt: ENTRY PROC RETURNS [s: Style] ~ { ENABLE UNWIND => NULL; SELECT frame FROM frame1 => RETURN [style1]; frame2 => RETURN [style2]; frame3 => RETURN [style3]; frame4 => RETURN [style4]; ENDCASE => FOR lst: FrameInfo _ frameList, lst.rest UNTIL lst=NIL DO IF lst.frame=frame THEN RETURN [lst.style]; ENDLOOP }; IF (style _ GetIt[]) = NIL THEN { -- failed to find the frame IF debugFlag THEN { IF debugStyle = NIL THEN debugStyle _ NodeStyleOps.Create[]; RETURN [debugStyle]; }; ERROR; }; RETURN [style]; }; GetStyleDict: PUBLIC PROC [frame: Frame, styleName: ATOM, kind: OfStyle, def: ROPE _ NIL] RETURNS [d: TJaM.Dict] ~ { found, ok: BOOL; styleName _ ForceLowerName[styleName]; [d, found] _ CheckStyleDict[styleName, kind]; IF found THEN RETURN; ok _ IF def # NIL THEN RunStyleString[frame, styleName, def] ELSE RunStyle[frame, styleName]; IF ok THEN [d, found] _ CheckStyleDict[styleName, kind]; IF NOT found THEN { BadStyleFile[frame, styleName]; [d, found] _ CheckStyleDict[styleName, kind]; }; }; BadStyleFile: PUBLIC PROC [frame: Frame, styleName: ATOM] ~ { { ENABLE { WhatStyle => RESUME[styleName]; StartOfStyle => RESUME; EndOfStyle => RESUME; }; BeginStyleOp[frame]; IF styleName # NodeStyleOps.defaultStyleName THEN { TJaM.Push[frame, NodeStyleOps.defaultStyleName]; AttachStyleOp[frame]; }; EndStyleOp[frame]; }; [] _ RefTab.Store[fileForStyle, styleName, NEW [FileIDRep _ []]]; MessageWindow.Append[TJaM.RopeFromAtom[styleName], TRUE]; MessageWindow.Append[".style could not be loaded."]; MessageWindow.Blink[]; TJaM.Push[frame, styleName]; TJaM.PushRope[frame, "style was bad."]; StyleError[frame, 2]; }; CheckStyleDict: PROC [styleName: ATOM, kind: OfStyle] RETURNS [d: TJaM.Dict, found: BOOL] ~ { obj: Object; [found, obj] _ TJaM.TryToGet[stylesDicts[kind], styleName]; IF found THEN d _ TypeCheckDict[obj]; }; CreateStyleDict: PROC RETURNS [d: TJaM.Dict] ~ { -- creates dict for style RETURN [TJaM.NewDict[50]]; }; EnterStyleDict: PROC [styleName: ATOM, d: Object, kind: OfStyle] ~ { TJaM.Put[stylesDicts[kind], styleName, d]; }; defaultSearch: LIST OF ROPE _ LIST["[]<>Commands>", "[]<>"]; FileID: TYPE ~ REF FileIDRep; FileIDRep: TYPE ~ RECORD [name: ROPE _ NIL, time: BasicTime.GMT _ BasicTime.nullGMT]; Same: PROC [a, b: FileID] RETURNS [BOOL] ~ { RETURN [a.time = b.time AND Rope.Equal[a.name, b.name, FALSE]] }; GetFileID: PROC [shortName: ATOM, extension: ROPE] RETURNS [FileID] ~ { dirs: LIST OF ROPE _ UserProfile.ListOfTokens["Tioga.StyleSearchRules", defaultSearch]; name: ROPE ~ Rope.Concat[TJaM.RopeFromAtom[shortName], extension]; fileName: ROPE _ NIL; created: BasicTime.GMT _ BasicTime.nullGMT; WHILE fileName = NIL AND dirs # NIL DO [fullFName: fileName, created: created] _ FS.FileInfo[name: name, wDir: dirs.first ! FS.Error => CONTINUE]; dirs _ dirs.rest; ENDLOOP; IF fileName = NIL THEN RETURN [NIL]; RETURN [NEW[FileIDRep _ [fileName, created]]]; }; DoLocked: PUBLIC PROC [action: PROC] ~ { me: UNSAFE PROCESS ~ Process.GetCurrent[]; Lock: ENTRY PROC ~ { UNTIL styleLockProcess = me OR styleLockCount = 0 DO WAIT styleLockFree ENDLOOP; styleLockProcess _ me; styleLockCount _ styleLockCount + 1; }; Unlock: ENTRY PROC ~ { styleLockCount _ styleLockCount - 1; IF styleLockCount = 0 THEN {styleLockProcess _ NIL; NOTIFY styleLockFree}; }; Lock[]; action[ ! UNWIND => Unlock[]]; Unlock[]; }; ValidateStyles: PUBLIC PROC RETURNS [changed: BOOL _ FALSE] ~ { Locked: PROC ~ { Action: PROC [key: REF, val: REF] RETURNS [quit: BOOLEAN] ~ { IF ValidateStyle[NARROW[key]] THEN changed _ TRUE; RETURN [FALSE] }; [] _ RefTab.Pairs[fileForStyle, Action]; }; DoLocked[Locked]; }; ValidateStyle: PUBLIC PROC [styleName: ATOM] RETURNS [changed: BOOL _ FALSE] ~ { Locked: PROC ~ { fileID: FileID ~ GetFileID[styleName, ".style"]; oldFileID: FileID ~ NARROW[RefTab.Fetch[fileForStyle, styleName].val]; IF oldFileID = NIL OR fileID = NIL OR Same[fileID, oldFileID] THEN changed _ FALSE ELSE { frame: Frame _ GetFrame[NIL, NIL, screen]; IF NOT RunStyle[frame, styleName] THEN BadStyleFile[frame, styleName]; FreeFrame[frame, NIL, screen]; changed _ TRUE; }; }; DoLocked[Locked]; }; RunStyle: PUBLIC PROC [frame: Frame, styleName: ATOM] RETURNS [ok: BOOL _ FALSE] ~ { Inner: PROC ~ { started, finished: BOOL _ FALSE; fileID: FileID ~ GetFileID[styleName, ".style"]; TJaM.Put[attachmentsDict, styleName, TJaM.NewArray[0]]; IF fileID = NIL THEN {ok _ FALSE; RETURN}; MessageWindow.Append["Using ", runNesting=0]; MessageWindow.Append[fileID.name, FALSE]; MessageWindow.Append[" . . . ", FALSE]; runNesting _ runNesting + 1; TJaM.PushRope[frame, fileID.name]; TJaM.Execute[frame, run ! WhatStyle => RESUME[styleName]; StartOfStyle => { started _ TRUE; RESUME }; EndOfStyle => { finished _ TRUE; RESUME }; TJaM.Stop => { finished _ FALSE; CONTINUE }; ]; runNesting _ runNesting - 1; ok _ started AND finished; IF ok THEN MessageWindow.Append["ok ", FALSE]; IF ok THEN [] _ RefTab.Store[fileForStyle, styleName, fileID]; IF ok AND runNesting=0 THEN MessageWindow.Clear[]; }; DoLocked[Inner]; }; RunStyleString: PUBLIC PROC [frame: Frame, styleName: ATOM, def: ROPE] RETURNS [ok: BOOL] ~ { started, finished: BOOL _ FALSE; TJaM.Put[attachmentsDict, styleName, TJaM.NewArray[0]]; TJaM.Execute[frame, TJaM.CvX[def] ! WhatStyle => { RESUME[styleName] }; StartOfStyle => { started _ TRUE; RESUME }; EndOfStyle => { finished _ TRUE; RESUME }; TJaM.Stop => { finished _ FALSE; CONTINUE }; ]; RETURN [started AND finished]; }; styleDictName: ATOM ~ TJaM.AtomFromRope["##styleDictName"]; styleKindName: ATOM ~ TJaM.AtomFromRope["##styleKindName"]; InitDict: PUBLIC PROC [name: ATOM, size: CARDINAL _ 100] RETURNS [dictionary: TJaM.Dict] ~ { found: BOOL; d: Object; [found, d] _ TJaM.TryToGet[sysdict, name]; IF found THEN dictionary _ TypeCheckDict[d] ELSE { dictionary _ TJaM.NewDict[size]; TJaM.Put[sysdict, name, dictionary]; } }; kindNames: REF ARRAY OfStyle OF ATOM _ NEW[ARRAY OfStyle OF ATOM _ [ $screen, $print, $base]]; styleRuleDictNames: REF ARRAY OfStyle OF ATOM ~ NEW[ARRAY OfStyle OF ATOM _ [ TJaM.AtomFromRope["##BaseStyleRuleDictName"], TJaM.AtomFromRope["##ScreenStyleRuleDictName"], TJaM.AtomFromRope["##PrintStyleRuleDictName"] ]]; styleDictNames: REF ARRAY OfStyle OF ATOM ~ NEW[ARRAY OfStyle OF ATOM _[ TJaM.AtomFromRope["##BaseStyleDictName"], TJaM.AtomFromRope["##ScreenStyleDictName"], TJaM.AtomFromRope["##PrintStyleDictName"] ]]; StartOfStyle: SIGNAL ~ CODE; -- raised to indicate start of loading style EndOfStyle: SIGNAL ~ CODE; -- raised to indicate successful loading WhatStyle: SIGNAL RETURNS [ATOM] ~ CODE; -- raised to find name of style being loaded BeginStyleOp: TJaM.CommandProc ~ { name: ATOM _ ForceLowerName[SIGNAL WhatStyle]; -- get style name from RunStyle screenDict, printDict, baseDict: TJaM.Dict; ResetDict: PROC [dict: TJaM.Dict] ~ { TJaM.ClrDict[dict]; TJaM.DetachAll[dict]; }; MakeDict: PROC [kind: OfStyle] RETURNS [dict: TJaM.Dict] ~ { dict _ CreateStyleDict[]; EnterStyleDict[name, dict, kind]; }; SetupDict: PROC [dict: TJaM.Dict, kind: OfStyle] ~ { TJaM.Put[baseDict, styleRuleDictNames[kind], TJaM.NewDict[50]]; TJaM.Put[dict, styleKindName, kindNames[kind]]; }; found: BOOL; [baseDict, found] _ CheckStyleDict[name, base]; -- check if reloading IF found THEN { ResetDict[baseDict]; [printDict, ] _ CheckStyleDict[name, print]; ResetDict[printDict]; [screenDict, ] _ CheckStyleDict[name, screen]; ResetDict[screenDict]; NodeStyleOps.FlushCaches[] } ELSE { baseDict _ MakeDict[base]; screenDict _ MakeDict[screen]; printDict _ MakeDict[print] }; SetupDict[baseDict, base]; SetupDict[screenDict, screen]; SetupDict[printDict, print]; TJaM.AttachDict[screenDict, baseDict]; TJaM.AttachDict[printDict, baseDict]; TJaM.Put[baseDict, styleDictNames[screen], screenDict]; TJaM.Put[baseDict, styleDictNames[print], printDict]; TJaM.Put[baseDict, styleDictNames[base], baseDict]; TJaM.Put[baseDict, styleDictName, name]; TJaM.Begin[frame, baseDict]; TJaM.Push[frame, baseDict]; -- leave this around for EndStyleOp SIGNAL StartOfStyle; -- caught by RunStyle }; EndStyleOp: TJaM.CommandProc ~ { d1, d2: TJaM.Dict; d1 _ TJaM.DictTop[frame]; -- the current dictionary d2 _ TJaM.PopDict[frame]; -- pushed by StyleOp IF d1 # d2 THEN { TJaM.PushRope[frame, "mismatched Style and EndStyle commands"]; StyleError[frame, 1]; } ELSE { -- change attachments so look in own basicDict before any attached dicts name: ATOM _ SIGNAL WhatStyle; screenDict: TJaM.Dict ~ CheckStyleDict[name, screen].d; printDict: TJaM.Dict ~ CheckStyleDict[name, print].d; TJaM.DetachDict[screenDict, d1]; TJaM.DetachDict[printDict, d1]; TJaM.AttachDict[screenDict, d1]; TJaM.AttachDict[printDict, d1]; TJaM.End[frame]; }; SIGNAL EndOfStyle; -- caught by RunStyle }; StyleNameOp: TJaM.CommandProc ~ { -- expects style dictionary on op stack TJaM.Push[frame, TJaM.Load[frame, styleDictName]] }; StyleRuleOp: TJaM.CommandProc ~ { DefineStyleRule[frame, base] }; PrintRuleOp: TJaM.CommandProc ~ { DefineStyleRule[frame, print] }; ScreenRuleOp: TJaM.CommandProc ~ { DefineStyleRule[frame, screen] }; DefineStyleRule: PROC [frame: Frame, kind: OfStyle] ~ { definition: Object _ TJaM.Pop[frame]; comment: Object _ TJaM.Pop[frame]; styleRule: ATOM _ PopName[frame]; name: ATOM _ ForceLowerName[styleRule]; dict: TJaM.Dict _ LoadStyleDict[frame, kind]; WITH definition SELECT FROM x: TJaM.Array => TJaM.ABind[x, bindingDict]; ENDCASE; -- def may be a string definition _ TJaM.CvX[definition]; TJaM.Put[dict, name, definition]; -- save the definition IF name # styleRule THEN TJaM.Put[dict, styleRule, definition]; TJaM.Put[LoadStyleRuleDict[frame, kind], name, comment]; -- save the comment in the rule name dict }; LoadStyleDict: PROC [frame: Frame, kind: OfStyle] RETURNS [TJaM.Dict] ~ { RETURN [TypeCheckDict[TJaM.Load[frame, styleDictNames[kind]]]]; }; LoadStyleRuleDict: PROC [frame: Frame, kind: OfStyle] RETURNS [TJaM.Dict] ~ { RETURN [TypeCheckDict[TJaM.Load[frame, styleRuleDictNames[kind]]]]; }; OpenPrintStyleOp: TJaM.CommandProc ~ { -- expects style name on op stack OpenStyle[frame, print]; }; OpenScreenStyleOp: TJaM.CommandProc ~ { -- expects style name on op stack OpenStyle[frame, screen]; }; OpenStyle: PROC [frame: Frame, kind: OfStyle] ~ { name: ATOM _ PopName[frame]; IF NOT NodeStyleOps.LoadStyle[name] THEN RETURN; WHILE TJaM.DictTop[frame] # sysdict DO TJaM.End[frame]; ENDLOOP; TJaM.Begin[frame, styledict]; TJaM.Begin[frame, GetStyleDict[frame, name, kind]]; }; ResetTestStyleOp: TJaM.CommandProc ~ { IF debugStyle=NIL THEN debugStyle _ NodeStyleOps.Create[]; debugStyle^ _ NodeStyleOps.defaultStyle^; }; StyleRuleDictOp: TJaM.CommandProc ~ { GetRuleDict[frame, base] }; PrintRuleDictOp: TJaM.CommandProc ~ { GetRuleDict[frame, print] }; ScreenRuleDictOp: TJaM.CommandProc ~ { GetRuleDict[frame, screen] }; GetRuleDict: PROC [frame: Frame, kind: OfStyle] ~ { TJaM.Push[frame, styleRuleDictNames[kind]]; TJaM.Execute[frame, get]; }; AttachStyleOp: TJaM.CommandProc ~ { -- expects opstk to contain style name as a rope name: ATOM _ ForceLowerName[PopName[frame]]; found: BOOL; printDict, screenDict: TJaM.Dict; array: TJaM.Array; styleName: ATOM _ SIGNAL WhatStyle; val: Object; [printDict, found] _ CheckStyleDict[name, print]; IF NOT found THEN { IF RunStyle[frame, name] THEN [printDict, found] _ CheckStyleDict[name, print]; IF NOT found THEN { BadStyleFile[frame, name]; RETURN; }; }; [screenDict, found] _ CheckStyleDict[name, screen]; IF ~found THEN ERROR; TJaM.AttachDict[LoadStyleDict[frame, screen], screenDict]; TJaM.AttachDict[LoadStyleDict[frame, print], printDict]; [found, val] _ TJaM.TryToGet[attachmentsDict, styleName]; IF NOT found THEN array _ TJaM.NewArray[1] -- this is the first attachment ELSE { -- add new item to the array WITH val SELECT FROM x: TJaM.Array => array _ x; ENDCASE => ERROR; array _ TJaM.ACopy[array, 1]; }; TJaM.APut[array, array.len-1, name]; TJaM.Put[attachmentsDict, styleName, array]; }; ForEachAttachedStyle: PUBLIC PROC [dictName: ATOM, proc: PROC [attached: ATOM] RETURNS [stop: BOOL]] ~ { val: Object; array: TJaM.Array; found: BOOL; dictName _ ForceLowerName[dictName]; [found, val] _ TJaM.TryToGet[attachmentsDict, dictName]; IF NOT found THEN RETURN; WITH val SELECT FROM x: TJaM.Array => array _ x; ENDCASE => ERROR; FOR i: CARDINAL IN [0..array.len) DO IF proc[TypeCheckName[TJaM.AGet[array, i]]] THEN RETURN; ENDLOOP; }; ExecuteObject: PROC [frame: Frame, object: Object] RETURNS [ok: BOOL _ TRUE] ~ { initDepth, finalDepth: INT; initDepth _ TJaM.CountStack[frame]; TJaM.Execute[frame, object]; finalDepth _ TJaM.CountStack[frame]; IF finalDepth # initDepth THEN { TJaM.PushRope[frame, "Failed to leave stack at same depth after execution.\n"]; TJaM.Push[frame, object]; StyleError[frame, 2]; ok _ FALSE; }; }; ExecuteName: PUBLIC PROC [frame: Frame, name: ATOM] RETURNS [ok: BOOL] ~ { oldName: ATOM _ executingName; [ok, ] _ TJaM.TryToLoad[frame, name]; executingName _ name; IF ok THEN ok _ ExecuteObject[frame, name ! TJaM.Stop => {ok _ FALSE; CONTINUE}]; executingName _ oldName; }; ExecuteNameInStyle: PUBLIC PROC [ref: Style, kind: OfStyle, styleRule: ATOM] RETURNS [ok: BOOL] ~ { styleName: ATOM _ ref.name[style]; frame: Frame _ GetFrame[ref, styleName, kind]; ok _ ExecuteName[frame, styleRule]; FreeFrame[frame, styleName, kind]; frame _ NIL; ref.font _ NIL; }; ExecuteObjectInStyle: PUBLIC PROC [ref: Style, kind: OfStyle, object: Object] RETURNS [ok: BOOL _ TRUE] ~ { styleName: ATOM _ ref.name[style]; frame: Frame _ GetFrame[ref, styleName, kind]; { ENABLE TJaM.Stop => GO TO stop; ok _ ExecuteObject[frame, TJaM.CvX[object]]; EXITS stop => ok _ FALSE; }; FreeFrame[frame, styleName, kind]; frame _ NIL; ref.font _ NIL; }; ExecuteLooksInStyle: PUBLIC PROC [ref: Style, kind: OfStyle, looks: TextLooks.Looks] RETURNS [ok: BOOL _ TRUE] ~ { styleName: ATOM _ ref.name[style]; frame: Frame _ GetFrame[ref, styleName, kind]; FOR c: CHAR IN TextLooks.Look DO IF looks[c] THEN ok _ ExecuteName[frame, lookNames[c]] ENDLOOP; FreeFrame[frame, styleName, kind]; frame _ NIL; ref.font _ NIL; IF nodeStyleFonts THEN { ref.font _ NodeStyleFont.FontFromStyleParams[prefix: ref.name[fontPrefix], family: ref.name[fontFamily], face: ref.fontFace, size: GetReal[ref, fontSize], alphabets: ref.fontAlphabets]; }; }; lookNames: REF LookNames _ NEW[LookNames]; LookNames: TYPE ~ ARRAY TextLooks.Look OF ATOM; InitLookNames: PROC ~ { FOR c: CHAR IN TextLooks.Look DO lookNames[c] _ TJaM.AtomFromRope[Rope.Concat["look.", Rope.FromChar[c]]]; ENDLOOP; }; StyleError: PUBLIC PROC [frame: Frame, num: INTEGER] ~ { TJaM.PushInt[frame, num]; TJaM.Execute[frame, $StyleError ! TJaM.Stop => CONTINUE]; }; DoStyleOp: PUBLIC PROC [frame: Frame, p: Param] ~ { aName: BOOL; name: ATOM; style: Style _ StyleForFrame[frame]; Error: PROC ~ { TJaM.Push[frame, p.opName]; TJaM.PushRope[frame, "illegal as qualifer for"]; TJaM.Push[frame, name]; StyleError[frame, 3]; }; [name, aName] _ TryToPopName[frame]; IF NOT aName THEN p.ops.Store[frame, p, style] -- e.g., "10 pt leading" ELSE SELECT name FROM $the => p.ops.Load[frame, p, style]; -- e.g., "the leading" $bigger => { [name, aName] _ TryToPopName[frame]; IF NOT aName THEN p.ops.AddReal[frame, TJaM.PopReal[frame], p, style] ELSE IF name = $percent THEN p.ops.Percent[frame, 100+TJaM.PopReal[frame], p, style] ELSE { Error[]; RETURN }; }; $smaller => { [name, aName] _ TryToPopName[frame]; IF NOT aName THEN p.ops.AddReal[frame, -TJaM.PopReal[frame], p, style] ELSE IF name = $percent THEN p.ops.Percent[frame, 100-TJaM.PopReal[frame], p, style] ELSE { Error[]; RETURN }; }; $percent => p.ops.Percent[frame, TJaM.PopReal[frame], p, style]; ENDCASE => p.ops.SetName[frame, name, p, style]; -- e.g., "TimesRoman family" }; StoreError: PUBLIC StoreProc ~ { ob: Object _ TJaM.Pop[frame]; TJaM.Push[frame, p.opName]; TJaM.PushRope[frame, "is not legal as value for"]; TJaM.Push[frame, ob]; StyleError[frame, 3]; }; AddRealError: PUBLIC AddRealProc ~ { TJaM.Push[frame, p.opName]; TJaM.PushRope[frame, "Numbers are illegal as values for"]; StyleError[frame, 2]; }; PercentError: PUBLIC PercentProc ~ { TJaM.Push[frame, p.opName]; TJaM.PushRope[frame, "Numbers are illegal as values for"]; StyleError[frame, 2]; }; SetNameError: PUBLIC SetNameProc ~ { TJaM.Push[frame, p.opName]; TJaM.PushRope[frame, "Only numbers are legal as values for"]; StyleError[frame, 2]; }; nameOps: PUBLIC Ops _ NEW [OpsRec _ [LoadNameParam, StoreError, AddRealError, PercentError, SetNameParam]]; LoadNameParam: PUBLIC LoadProc ~ { x: REF ParamRec.name ~ NARROW[p]; TJaM.Push[frame, style.name[x.param]]; }; SetNameParam: PUBLIC SetNameProc ~ { x: REF ParamRec.name ~ NARROW[p]; style.name[x.param] _ name; }; NameError: PUBLIC PROC [frame: Frame, name: ATOM, p: Param] ~ { TJaM.Push[frame, p.opName]; TJaM.PushRope[frame, "illegal as value for"]; TJaM.Push[frame, name]; StyleError[frame, 3]; }; realOps: PUBLIC Ops _ NEW [OpsRec _ [RealOpLoad, RealOpSetReal, RealOpAddReal, RealOpPercent, SetNameError]]; RealOpLoad: PUBLIC LoadProc ~ { x: REF ParamRec.real ~ NARROW[p]; TJaM.PushReal[frame, GetReal[style, x.param]]; }; RealOpSetReal: PUBLIC StoreProc ~ { x: REF ParamRec.real ~ NARROW[p]; SetReal[style, x.param, TJaM.PopReal[frame]]; }; RealOpAddReal: PUBLIC AddRealProc ~ { x: REF ParamRec.real ~ NARROW[p]; SetReal[style, x.param, GetReal[style, x.param]+inc]; }; RealOpPercent: PUBLIC PercentProc ~ { x: REF ParamRec.real ~ NARROW[p]; SetReal[style, x.param, GetReal[style, x.param]*(percent/100)]; }; glueOps: PUBLIC Ops _ NEW [OpsRec _ [GlueOpLoad, GlueOpSetReal, GlueOpAddReal, GlueOpPercent, SetNameError]]; GlueOpLoad: PUBLIC LoadProc ~ { Push: PROC [r: RealParam] ~ { TJaM.PushReal[frame, GetReal[style, r]] }; x: REF ParamRec.glue ~ NARROW[p]; Push[x.size]; Push[x.stretch]; Push[x.shrink]; }; GlueOpSetReal: PUBLIC StoreProc ~ { Pop: PROC [r: RealParam] ~ { SetReal[style, r, TJaM.PopReal[frame]] }; x: REF ParamRec.glue ~ NARROW[p]; Pop[x.shrink]; Pop[x.stretch]; Pop[x.size]; }; GlueOpAddReal: PUBLIC AddRealProc ~ { Add: PROC [r: RealParam] ~ { SetReal[style, r, GetReal[style, r]+inc] }; x: REF ParamRec.glue ~ NARROW[p]; Add[x.size]; Add[x.stretch]; Add[x.shrink]; }; GlueOpPercent: PUBLIC PercentProc ~ { Pct: PROC [r: RealParam] ~ { SetReal[style, r, GetReal[style, r]*(percent/100)] }; x: REF ParamRec.glue ~ NARROW[p]; Pct[x.size]; Pct[x.stretch]; Pct[x.shrink]; }; colorOps: PUBLIC Ops _ NEW [OpsRec _ [ColorOpLoad, ColorOpSetReal, ColorOpAddReal, ColorOpPercent, SetNameError]]; ColorOpLoad: PUBLIC LoadProc ~ { Push: PROC [r: RealParam] ~ { TJaM.PushReal[frame, GetReal[style, r]] }; x: REF ParamRec.color ~ NARROW[p]; Push[x.hue]; Push[x.saturation]; Push[x.brightness]; }; ColorOpSetReal: PUBLIC StoreProc ~ { Pop: PROC [r: RealParam] ~ { SetReal[style, r, TJaM.PopReal[frame]] }; x: REF ParamRec.color ~ NARROW[p]; Pop[x.brightness]; Pop[x.saturation]; Pop[x.hue]; }; ColorOpAddReal: PUBLIC AddRealProc ~ { Add: PROC [r: RealParam] ~ { SetReal[style, r, GetReal[style, r]+inc] }; x: REF ParamRec.color ~ NARROW[p]; Add[x.hue]; Add[x.saturation]; Add[x.brightness]; }; ColorOpPercent: PUBLIC PercentProc ~ { Pct: PROC [r: RealParam] ~ { SetReal[style, r, GetReal[style, r]*(percent/100)] }; x: REF ParamRec.color ~ NARROW[p]; Pct[x.hue]; Pct[x.saturation]; Pct[x.brightness]; }; RegisterWorks1: PUBLIC PROC [frame: Frame] ~ { InitLookNames[]; RegisterStyleCommand[frame, $BeginStyle, BeginStyleOp]; RegisterStyleCommand[frame, $EndStyle, EndStyleOp]; RegisterStyleCommand[frame, $StyleRule, StyleRuleOp]; RegisterStyleCommand[frame, $PrintRule, PrintRuleOp]; RegisterStyleCommand[frame, $ScreenRule, ScreenRuleOp]; RegisterStyleCommand[frame, $AttachStyle, AttachStyleOp]; TJaM.Register[frame, $StyleName, StyleNameOp]; TJaM.Register[frame, $OpenPrintStyle, OpenPrintStyleOp]; TJaM.Register[frame, $OpenScreenStyle, OpenScreenStyleOp]; TJaM.Register[frame, $ResetTestStyle, ResetTestStyleOp]; TJaM.Register[frame, $StyleRuleDict, StyleRuleDictOp]; TJaM.Register[frame, $PrintRuleDict, PrintRuleDictOp]; TJaM.Register[frame, $ScreenRuleDict, ScreenRuleDictOp]; }; GetCommand: PUBLIC PROC [frame: Frame, name: ATOM] RETURNS [TJaM.Cmd] ~ { known: BOOL; obj: Object; [known, obj] _ TJaM.TryToLoad[frame, name]; IF NOT known THEN ERROR; RETURN [TypeCheckCommand[obj]]; }; ForceLowerName: PUBLIC PROC [n: ATOM] RETURNS [ATOM] ~ { IF n#NIL THEN { rope: ROPE ~ Atom.GetPName[n]; CheckLower: Rope.ActionType ~ {quit _ c IN ['A..'Z]}; IF Rope.Map[base: rope, action: CheckLower] THEN { len: NAT ~ Rope.Length[rope]; text: REF TEXT ~ RefText.ObtainScratch[len]; FOR i: NAT IN[0..len) DO text[i] _ Ascii.Lower[Rope.Fetch[rope, i]] ENDLOOP; text.length _ len; n _ Atom.MakeAtomFromRefText[text]; RefText.ReleaseScratch[text]; }; }; RETURN [n]; }; ForceLowerRope: PUBLIC PROC [r: ROPE] RETURNS [ROPE] ~ { ForceCharLower: PROC [old: CHAR] RETURNS [new: CHAR] ~ { RETURN [Ascii.Lower[old]] }; RETURN [Rope.Translate[base: r, translator: ForceCharLower]]; }; PopName: PUBLIC PROC [frame: Frame] RETURNS [name: ATOM] ~ { ok: BOOL _ TRUE; obj: Object _ NIL; IF TJaM.StackIsEmpty[frame] THEN ok _ FALSE; IF ok THEN SELECT TJaM.TopType[frame] FROM atom => RETURN [TJaM.PopAtom[frame]]; rope => RETURN [TJaM.AtomFromRope[TJaM.PopRope[frame]]] ENDCASE => { ok _ FALSE; obj _ TJaM.Pop[frame]; }; IF NOT ok THEN { TJaM.PushRope[frame, " -- found where a name was expected."]; TJaM.Push[frame, obj]; StyleError[frame, 2]; }; }; TryToPopName: PUBLIC PROC [frame: Frame] RETURNS [name: ATOM, ok: BOOL] ~ { IF NOT TJaM.StackIsEmpty[frame] THEN SELECT TJaM.TopType[frame] FROM atom => RETURN [name: TJaM.PopAtom[frame], ok: TRUE]; rope => RETURN [name: TJaM.AtomFromRope[TJaM.PopRope[frame]], ok: TRUE]; ENDCASE; RETURN[name: NIL, ok: FALSE]; }; TryToPopReal: PUBLIC PROC [frame: Frame] RETURNS [value: REAL, ok: BOOL] ~ { IF NOT TJaM.StackIsEmpty[frame] THEN SELECT TJaM.TopType[frame] FROM number => RETURN [value: TJaM.PopReal[frame], ok: TRUE]; ENDCASE; RETURN[value: 0, ok: FALSE]; }; TryToPopRope: PUBLIC PROC [frame: Frame] RETURNS [rope: ROPE, ok: BOOL] ~ { IF NOT TJaM.StackIsEmpty[frame] THEN SELECT TJaM.TopType[frame] FROM atom => RETURN [rope: TJaM.RopeFromAtom[TJaM.PopAtom[frame]], ok: TRUE]; rope => RETURN [rope: TJaM.PopRope[frame], ok: TRUE]; ENDCASE; RETURN[rope: NIL, ok: FALSE]; }; TypeCheckName: PUBLIC PROC [obj: Object] RETURNS [ATOM] ~ { WITH obj SELECT FROM x: ATOM => RETURN [x]; x: ROPE => RETURN [TJaM.AtomFromRope[x]]; ENDCASE; ERROR; }; TypeCheckDict: PUBLIC PROC [obj: Object] RETURNS [TJaM.Dict] ~ { WITH obj SELECT FROM x: TJaM.Dict => RETURN [x]; ENDCASE; ERROR; }; TypeCheckCommand: PUBLIC PROC [obj: Object] RETURNS [TJaM.Cmd] ~ { WITH obj SELECT FROM x: TJaM.Cmd => RETURN [x]; ENDCASE; ERROR; }; IsCommentOp: TJaM.CommandProc ~ { style: Style _ StyleForFrame[frame]; TJaM.PushBool[frame, style.isComment]; }; IsPrintOp: TJaM.CommandProc ~ { style: Style _ StyleForFrame[frame]; TJaM.PushBool[frame, style.print]; }; NestingLevelOp: TJaM.CommandProc ~ { style: Style _ StyleForFrame[frame]; TJaM.PushInt[frame, style.nestingLevel]; }; StyleParamOp: TJaM.CommandProc ~ { initialValue: Object _ TJaM.Pop[frame]; -- the initial value name: ATOM _ PopName[frame]; -- the parameter name key: ATOM; array: TJaM.Array; [key, array] _ SpecialOpArray[name, $SpecialOp]; TJaM.Def[frame, name, TJaM.CvX[array]]; -- store the definition TJaM.Def[frame, key, initialValue]; -- store the initial value }; SpecialOpArray: PUBLIC PROC [name: ATOM, op: Object] RETURNS [key: ATOM, array: TJaM.Array] ~ { key _ StyleParamKey[name]; array _ TJaM.NewArray[2]; TJaM.APut[array, 0, TJaM.CvLit[key]]; TJaM.APut[array, 1, op]; }; StyleParamKey: PUBLIC PROC [name: ATOM] RETURNS [key: ATOM] ~ { scratch: REF TEXT ~ RefText.ObtainScratch[50]; text: REF TEXT _ scratch; text _ RefText.AppendRope[text, "!!"]; text _ RefText.AppendRope[text, Atom.GetPName[name]]; key _ Atom.MakeAtomFromRefText[text]; RefText.ReleaseScratch[scratch]; }; SpecialOp: TJaM.CommandProc ~ { aName: BOOL; name: ATOM; var: ATOM; style: Style _ StyleForFrame[frame]; Error: PROC ~ { TJaM.Push[frame, name]; TJaM.PushRope[frame, "has illegal qualifier:"]; TJaM.Push[frame, var]; StyleError[frame, 3]; }; FindObject: PROC RETURNS [Object] ~ { FOR x: DataList _ style.dataList, x.next UNTIL x=NIL DO xx: REF DataEntry.object ~ NARROW[x]; IF xx.name = var THEN RETURN [xx.object]; ENDLOOP; TJaM.Push[frame, var]; TJaM.Execute[frame, load]; -- get the initial value RETURN [TJaM.Pop[frame]]; }; Store: PROC [ob: Object] ~ { style.dataList _ NEW[DataEntry _ [style.dataList, object[var, ob]]]; }; Load: PROC ~ { TJaM.Push[frame, FindObject[]] }; AddReal: PROC [inc: REAL] ~ { value: REAL; Load[]; value _ TJaM.PopReal[frame]; SetReal[value+inc]; }; SetReal: PROC [x: REAL] ~ { TJaM.PushReal[frame, x]; Store[TJaM.Pop[frame]]; }; SetName: PROC [n: ATOM] ~ { TJaM.Push[frame, n]; Store[TJaM.Pop[frame]]; }; Percent: PROC [percent: REAL] ~ { value: REAL; Load[]; value _ TJaM.PopReal[frame]; SetReal[(percent/100)*value]; }; var _ PopName[frame]; -- the name of the special parameter [name, aName] _ TryToPopName[frame]; IF NOT aName THEN Store[TJaM.Pop[frame]] ELSE SELECT name FROM $the => Load[]; $bigger => BEGIN [name, aName] _ TryToPopName[frame]; IF NOT aName THEN AddReal[TJaM.PopReal[frame]] ELSE IF name = $percent THEN Percent[100+TJaM.PopReal[frame]] ELSE { Error; RETURN }; END; $smaller => BEGIN [name, aName] _ TryToPopName[frame]; IF NOT aName THEN AddReal[-TJaM.PopReal[frame]] ELSE IF name = $percent THEN Percent[100-TJaM.PopReal[frame]] ELSE { Error; RETURN }; END; $percent => Percent[TJaM.PopReal[frame]]; ENDCASE => SetName[name]; }; RegisterStyleCommand: PUBLIC PROC [frame: Frame, name: ATOM, proc: TJaM.CommandProc] ~ { TJaM.Register[frame, name, proc]; TJaM.Put[bindingDict, name, TJaM.Load[frame, name]]; }; RegisterStyleLiteral: PUBLIC PROC [frame: Frame, name: ATOM] ~ { TJaM.Put[bindingDict, name, name]; TJaM.Def[frame, name, TJaM.CvLit[name]]; }; ReportStyleErrorOp: TJaM.CommandProc ~ { num: INT _ TJaM.PopInt[frame]; msg: ROPE; ok: BOOL; MessageWindow.Clear[]; IF executingName # NIL THEN { TJaM.PushRope[frame, "style rule. "]; TJaM.Push[frame, executingName]; TJaM.PushRope[frame, "Error in"]; num _ num+3; }; UNTIL num=0 DO [msg, ok] _ TryToPopRope[frame]; IF NOT ok THEN EXIT; MessageWindow.Append[msg]; num _ num-1; IF num # 0 THEN MessageWindow.Append[" "]; ENDLOOP; }; RegisterWorks2: PUBLIC PROC [frame: Frame] ~ { TJaM.Register[frame, $isComment, IsCommentOp]; TJaM.Register[frame, $isPrint, IsPrintOp]; TJaM.Register[frame, $nestingLevel, NestingLevelOp]; TJaM.Register[frame, $StyleParam, StyleParamOp]; TJaM.Register[frame, $SpecialOp, SpecialOp]; TJaM.Register[frame, $ReportStyleError, ReportStyleErrorOp]; }; OpsListItem: TYPE ~ RECORD [name: ATOM, op: TJaM.CommandProc]; OpsList: TYPE ~ LIST OF OpsListItem; opsList: OpsList _ NIL; Preregister: PROC [param: Param, op: TJaM.CommandProc] RETURNS [Param] ~ { opsList _ CONS[[param.opName, op], opsList]; RETURN [param]; }; RegisterWorks3: PUBLIC PROC [frame: Frame] ~ { FOR list: OpsList _ opsList, list.rest UNTIL list=NIL DO RegisterStyleCommand[frame, list.first.name, list.first.op]; ENDLOOP; RegisterStyleCommand[frame, $clearTabStops, ClearTabStopsOp]; RegisterStyleCommand[frame, $tabStop, TabStopOp]; RegisterStyleCommand[frame, $defaultTabStops, DefaultTabStopsOp]; RegisterStyleCommand[frame, $tabStopLocations, RelativeTabStopsOp]; RegisterStyleCommand[frame, $pt, PointsOp]; RegisterStyleCommand[frame, $pc, PicasOp]; RegisterStyleCommand[frame, $in, InchesOp]; RegisterStyleCommand[frame, $cm, CentimetersOp]; RegisterStyleCommand[frame, $mm, MillimetersOp]; RegisterStyleCommand[frame, $dd, DidotPointsOp]; RegisterStyleCommand[frame, $em, EmsOp]; RegisterStyleCommand[frame, $en, EnsOp]; RegisterStyleCommand[frame, $screensp, ScreenSpacesOp]; RegisterStyleCommand[frame, $printsp, PrintSpacesOp]; RegisterStyleCommand[frame, $fil, FilOp]; RegisterStyleCommand[frame, $fill, FillOp]; RegisterStyleCommand[frame, $filll, FilllOp]; }; StyleNameOp: TJaM.CommandProc ~ { DoStyleOp[frame, styleNameParam] }; styleNameParam: Param _ Preregister[NEW [name ParamRec _ [nameOps, $style, name[style]]], StyleNameOp]; FontPrefixOp: TJaM.CommandProc ~ { DoStyleOp[frame, fontPrefixParam] }; fontPrefixParam: Param _ Preregister[NEW [name ParamRec _ [nameOps, $fontPrefix, name[fontPrefix]]], FontPrefixOp]; FontFamilyOp: TJaM.CommandProc ~ { DoStyleOp[frame, fontFamilyParam] }; fontFamilyParam: Param _ Preregister[NEW [name ParamRec _ [nameOps, $family, name[fontFamily]]], FontFamilyOp]; FontSizeOp: TJaM.CommandProc ~ { DoStyleOp[frame, fontSizeParam] }; fontSizeParam: Param _ Preregister[NEW [real ParamRec _ [realOps, $size, real[fontSize]]], FontSizeOp]; FontFaceOp: TJaM.CommandProc ~ { DoStyleOp[frame, fontFaceParam] }; fontFaceParam: Param _ Preregister[NEW[misc ParamRec _ [NEW [OpsRec _ [FontFaceLoad, StoreError, AddRealError, PercentError, FontFaceSetName]], $face, misc[]]], FontFaceOp]; FontFaceLoad: LoadProc ~ { TJaM.Push[frame, SELECT style.fontFace FROM Regular => $regular, Bold => $bold, Italic => $italic, BoldItalic => bolditalic, ENDCASE => ERROR] }; FontFaceSetName: SetNameProc ~ { Error: PROC RETURNS [FontFace] ~ { NameError[frame, name, p]; RETURN [Regular]; }; FontFaceArray: TYPE ~ ARRAY FontFace OF FontFace; minusBold: FontFaceArray ~ [Regular, Regular, Italic, Italic]; minusItalic: FontFaceArray ~ [Regular, Bold, Regular, Bold]; plusBold: FontFaceArray ~ [Bold, Bold, BoldItalic, BoldItalic]; plusItalic: FontFaceArray ~ [Italic, BoldItalic, Italic, BoldItalic]; style.fontFace _ SELECT name FROM $regular => Regular, $bold => Bold, $italic => Italic, bolditalic => BoldItalic, plusbold => plusBold[style.fontFace], plusitalic => plusItalic[style.fontFace], minusbold => minusBold[style.fontFace], minusitalic => minusItalic[style.fontFace], ENDCASE => Error[]; }; bolditalic: ATOM ~ TJaM.AtomFromRope["bold+italic"]; plusbold: ATOM ~ TJaM.AtomFromRope["+bold"]; plusitalic: ATOM ~ TJaM.AtomFromRope["+italic"]; minusbold: ATOM ~ TJaM.AtomFromRope["-bold"]; minusitalic: ATOM ~ TJaM.AtomFromRope["-italic"]; FontAlphabetsOp: TJaM.CommandProc ~ { DoStyleOp[frame, fontAlphabetsParam] }; fontAlphabetsParam: Param _ Preregister[NEW[misc ParamRec _ [NEW [OpsRec _ [FontAlphabetsLoad, StoreError, AddRealError, PercentError, FontAlphabetsSetName]], $alphabets, misc[]]], FontAlphabetsOp]; FontAlphabetsLoad: LoadProc ~ { TJaM.Push[frame, SELECT style.fontAlphabets FROM CapsAndLower => capsAndLower, CapsAndSmallCaps => capsAndSmallCaps, LowerOnly => $lowercase, CapsOnly => $caps, ENDCASE => ERROR] }; FontAlphabetsSetName: SetNameProc ~ { Error: PROC RETURNS [FontAlphabets] ~ { NameError[frame, name, p]; RETURN [CapsAndLower]; }; style.fontAlphabets _ SELECT name FROM capsAndLower => CapsAndLower, capsAndSmallCaps => CapsAndSmallCaps, $lowercase => LowerOnly, $caps => CapsOnly, ENDCASE => Error[]; }; capsAndLower: ATOM ~ TJaM.AtomFromRope["caps+lowercase"]; capsAndSmallCaps: ATOM ~ TJaM.AtomFromRope["caps+smallcaps"]; TextRotationOp: TJaM.CommandProc ~ { DoStyleOp[frame, textRotationParam] }; textRotationParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $textRotation, real[textRotation]]], TextRotationOp]; LeftIndentOp: TJaM.CommandProc ~ { DoStyleOp[frame, leftIndentParam] }; leftIndentParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $leftIndent, real[leftIndent]]], LeftIndentOp]; RightIndentOp: TJaM.CommandProc ~ { DoStyleOp[frame, rightIndentParam] }; rightIndentParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $rightIndent, real[rightIndent]]], RightIndentOp]; FirstIndentOp: TJaM.CommandProc ~ { DoStyleOp[frame, firstIndentParam] }; firstIndentParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $firstIndent, real[firstIndent]]], FirstIndentOp]; FirstIndentRightOp: TJaM.CommandProc ~ { DoStyleOp[frame, firstIndentRightParam] }; firstIndentRightParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $firstIndentRight, real[firstIndentRight]]], FirstIndentRightOp]; RestIndentOp: TJaM.CommandProc ~ { DoStyleOp[frame, restIndentParam] }; restIndentParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $restIndent, real[restIndent]]], RestIndentOp]; RunaroundLeftOp: TJaM.CommandProc ~ { DoStyleOp[frame, runaroundLeftParam] }; runaroundLeftParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $runaroundLeft, real[runaroundLeft]]], RunaroundLeftOp]; RunaroundRightOp: TJaM.CommandProc ~ { DoStyleOp[frame, runaroundRightParam] }; runaroundRightParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $runaroundRight, real[runaroundRight]]], RunaroundRightOp]; TopIndentOp: TJaM.CommandProc ~ { DoStyleOp[frame, topIndentParam] }; topIndentParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $topIndent, real[topIndent]]], TopIndentOp]; BottomIndentOp: TJaM.CommandProc ~ { DoStyleOp[frame, bottomIndentParam] }; bottomIndentParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $bottomIndent, real[bottomIndent]]], BottomIndentOp]; LineLeadingOp: TJaM.CommandProc ~ { DoStyleOp[frame, lineLeadingParam]; }; lineLeadingParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $leading, real[leading]]], LineLeadingOp]; LineLeadingStretchOp: TJaM.CommandProc ~ { DoStyleOp[frame, lineLeadingStretchParam] }; lineLeadingStretchParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $leadingStretch, real[leadingStretch]]], LineLeadingStretchOp]; LineLeadingShrinkOp: TJaM.CommandProc ~ { DoStyleOp[frame, lineLeadingShrinkParam] }; lineLeadingShrinkParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $leadingShrink, real[leadingShrink]]], LineLeadingShrinkOp]; LineLeadingGlueOp: TJaM.CommandProc ~ { DoStyleOp[frame, lineLeadingGlueParam] }; lineLeadingGlueParam: Param _ Preregister[NEW[glue ParamRec _ [glueOps, $leadingGlue, glue[leading, leadingStretch, leadingShrink]]], LineLeadingGlueOp]; TopLeadingOp: TJaM.CommandProc ~ { DoStyleOp[frame, topLeadingParam]; }; topLeadingParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $topLeading, real[topLeading]]], TopLeadingOp]; TopLeadingStretchOp: TJaM.CommandProc ~ { DoStyleOp[frame, topLeadingStretchParam] }; topLeadingStretchParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $topLeadingStretch, real[topLeadingStretch]]], TopLeadingStretchOp]; TopLeadingShrinkOp: TJaM.CommandProc ~ { DoStyleOp[frame, topLeadingShrinkParam] }; topLeadingShrinkParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $topLeadingShrink, real[topLeadingShrink]]], TopLeadingShrinkOp]; TopLeadingGlueOp: TJaM.CommandProc ~ { DoStyleOp[frame, topLeadingGlueParam] }; topLeadingGlueParam: Param _ Preregister[NEW[glue ParamRec _ [glueOps, $topLeadingGlue, glue[topLeading, topLeadingStretch, topLeadingShrink]]], TopLeadingGlueOp]; BottomLeadingOp: TJaM.CommandProc ~ { DoStyleOp[frame, bottomLeadingParam]; }; bottomLeadingParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $bottomLeading, real[bottomLeading]]], BottomLeadingOp]; BottomLeadingStretchOp: TJaM.CommandProc ~ { DoStyleOp[frame, bottomLeadingStretchParam] }; bottomLeadingStretchParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $bottomLeadingStretch, real[bottomLeadingStretch]]], BottomLeadingStretchOp]; BottomLeadingShrinkOp: TJaM.CommandProc ~ { DoStyleOp[frame, bottomLeadingShrinkParam] }; bottomLeadingShrinkParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $bottomLeadingShrink, real[bottomLeadingShrink]]], BottomLeadingShrinkOp]; BottomLeadingGlueOp: TJaM.CommandProc ~ { DoStyleOp[frame, bottomLeadingGlueParam] }; bottomLeadingGlueParam: Param _ Preregister[NEW[glue ParamRec _ [glueOps, $bottomLeadingGlue, glue[bottomLeading, bottomLeadingStretch, bottomLeadingShrink]]], BottomLeadingGlueOp]; LineFormattingOp: TJaM.CommandProc ~ { DoStyleOp[frame, lineFormattingParam]; }; lineFormattingParam: Param _ Preregister[NEW [misc ParamRec _ [NEW [OpsRec _ [LineFormattingLoad, StoreError, AddRealError, PercentError, LineFormattingSetName]], $lineFormatting, misc[]]], LineFormattingOp]; LineFormattingLoad: LoadProc ~ { TJaM.Push[frame, SELECT style.lineFormatting FROM Justified => $justified, FlushLeft => $flushLeft, FlushRight => $flushRight, Centered => $centered, ENDCASE => ERROR] }; LineFormattingSetName: SetNameProc ~ { Error: PROC RETURNS [LineFormatting] ~ { NameError[frame, name, p]; RETURN [FlushLeft] }; style.lineFormatting _ SELECT name FROM $justified => Justified, $flushLeft => FlushLeft, $flushRight => FlushRight, $centered => Centered, ENDCASE => Error[]; }; LastLineFormattingOp: TJaM.CommandProc ~ { DoStyleOp[frame, lastLineFormattingParam]; }; lastLineFormattingParam: Param _ Preregister[NEW [misc ParamRec _ [NEW [OpsRec _ [LastLineFormattingLoad, StoreError, AddRealError, PercentError, LastLineFormattingSetName]], $lastLineFormatting, misc[]]], LastLineFormattingOp]; LastLineFormattingLoad: LoadProc ~ { TJaM.Push[frame, SELECT style.lastLineFormatting FROM Justified => $justified, FlushLeft => $flushLeft, FlushRight => $flushRight, Centered => $centered, ENDCASE => ERROR] }; LastLineFormattingSetName: SetNameProc ~ { Error: PROC RETURNS [LineFormatting] ~ { NameError[frame, name, p]; RETURN [FlushLeft] }; style.lastLineFormatting _ SELECT name FROM $justified => Justified, $flushLeft => FlushLeft, $flushRight => FlushRight, $centered => Centered, ENDCASE => Error[]; }; UnderliningOp: TJaM.CommandProc ~ { DoStyleOp[frame, underliningParam] }; underliningParam: Param _ Preregister[NEW [misc ParamRec _ [NEW [OpsRec _ [UnderliningLoad, StoreError, AddRealError, PercentError, UnderliningSetName]], $underlining, misc[]]], UnderliningOp]; UnderliningLoad: LoadProc ~ { TJaM.Push[frame, SELECT style.underlining FROM None => $none, LettersAndDigits => lettersAndDigits, Visible => $visible, All => $all, ENDCASE => ERROR] }; lettersAndDigits: ATOM ~ TJaM.AtomFromRope["letters+digits"]; UnderliningSetName: SetNameProc ~ { Error: PROC RETURNS [FontUnderlining] ~ { NameError[frame, name, p]; RETURN [None] }; style.underlining _ SELECT name FROM $none => None, lettersAndDigits => LettersAndDigits, $visible => Visible, $all => All, ENDCASE => Error[]; }; StrikeoutOp: TJaM.CommandProc ~ { DoStyleOp[frame, strikeoutParam] }; strikeoutParam: Param _ Preregister[NEW [misc ParamRec _ [NEW [OpsRec _ [StrikeoutLoad, StoreError, AddRealError, PercentError, StrikeoutSetName]], $strikeout, misc[]]], StrikeoutOp]; StrikeoutLoad: LoadProc ~ { TJaM.Push[frame, SELECT style.strikeout FROM None => $none, LettersAndDigits => lettersAndDigits, Visible => $visible, All => $all, ENDCASE => ERROR] }; StrikeoutSetName: SetNameProc ~ { Error: PROC RETURNS [FontUnderlining] ~ { NameError[frame, name, p]; RETURN [None] }; style.strikeout _ SELECT name FROM $none => None, lettersAndDigits => LettersAndDigits, $visible => Visible, $all => All, ENDCASE => Error[]; }; HShiftOp: TJaM.CommandProc ~ { DoStyleOp[frame, hshiftParam] }; hshiftParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $hShift, real[hshift]]], HShiftOp]; VShiftOp: TJaM.CommandProc ~ { DoStyleOp[frame, vshiftParam] }; vshiftParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $vShift, real[vshift]]], VShiftOp]; MinLineGapOp: TJaM.CommandProc ~ { DoStyleOp[frame, minLineGapParam]; }; minLineGapParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $minLineGap, real[minLineGap]]], MinLineGapOp]; TabStopsOp: TJaM.CommandProc ~ { DoStyleOp[frame, tabStopsParam]; }; tabStopsParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $tabStops, real[tabStops]]], TabStopsOp]; LineWeightOp: TJaM.CommandProc ~ { DoStyleOp[frame, lineWeightParam] }; lineWeightParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $lineWeight, real[lineWeight]]], LineWeightOp]; PageWidthOp: TJaM.CommandProc ~ { DoStyleOp[frame, pageWidthParam] }; pageWidthParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $pageWidth, real[pageWidth]]], PageWidthOp]; PageLengthOp: TJaM.CommandProc ~ { DoStyleOp[frame, pageLengthParam] }; pageLengthParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $pageLength, real[pageLength]]], PageLengthOp]; LeftMarginOp: TJaM.CommandProc ~ { DoStyleOp[frame, leftMarginParam] }; leftMarginParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $leftMargin, real[leftMargin]]], LeftMarginOp]; RightMarginOp: TJaM.CommandProc ~ { DoStyleOp[frame, rightMarginParam] }; rightMarginParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $rightMargin, real[rightMargin]]], RightMarginOp]; TopMarginOp: TJaM.CommandProc ~ { DoStyleOp[frame, topMarginParam] }; topMarginParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $topMargin, real[topMargin]]], TopMarginOp]; BottomMarginOp: TJaM.CommandProc ~ { DoStyleOp[frame, bottomMarginParam] }; bottomMarginParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $bottomMargin, real[bottomMargin]]], BottomMarginOp]; HeaderMarginOp: TJaM.CommandProc ~ { DoStyleOp[frame, headerMarginParam] }; headerMarginParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $headerMargin, real[headerMargin]]], HeaderMarginOp]; FooterMarginOp: TJaM.CommandProc ~ { DoStyleOp[frame, footerMarginParam] }; footerMarginParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $footerMargin, real[footerMargin]]], FooterMarginOp]; BindingMarginOp: TJaM.CommandProc ~ { DoStyleOp[frame, bindingMarginParam] }; bindingMarginParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $bindingMargin, real[bindingMargin]]], BindingMarginOp]; LineLengthOp: TJaM.CommandProc ~ { DoStyleOp[frame, lineLengthParam] }; lineLengthParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $lineLength, real[lineLength]]], LineLengthOp]; ColumnOp: TJaM.CommandProc ~ { DoStyleOp[frame, columnParam] }; columnParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $column, real[columns]]], ColumnOp]; TextHueOp: TJaM.CommandProc ~ { DoStyleOp[frame, textHueParam] }; textHueParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $textHue, real[textHue]]], TextHueOp]; TextSaturationOp: TJaM.CommandProc ~ { DoStyleOp[frame, textSaturationParam] }; textSaturationParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $textSaturation, real[textSaturation]]], TextSaturationOp]; TextBrightnessOp: TJaM.CommandProc ~ { DoStyleOp[frame, textBrightnessParam] }; textBrightnessParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $textBrightness, real[textBrightness]]], TextBrightnessOp]; TextColorOp: TJaM.CommandProc ~ { DoStyleOp[frame, textColorParam] }; textColorParam: Param _ Preregister[NEW[color ParamRec _ [colorOps, $textColor, color[textHue, textSaturation, textBrightness]]], TextColorOp]; PageBreakPenaltyOp: TJaM.CommandProc ~ { DoStyleOp[frame, pageBreakPenaltyParam] }; pageBreakPenaltyParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $pageBreakPenalty, real[pageBreakPenalty]]], PageBreakPenaltyOp]; PageBreakPenalty2Op: TJaM.CommandProc ~ { DoStyleOp[frame, pageBreakPenalty2Param] }; pageBreakPenalty2Param: Param _ Preregister[NEW[real ParamRec _ [realOps, $pageBreakAfterFirstLinePenalty, real[pageBreakAfterFirstLinePenalty]]], PageBreakPenalty2Op]; PageBreakPenalty3Op: TJaM.CommandProc ~ { DoStyleOp[frame, pageBreakPenalty3Param] }; pageBreakPenalty3Param: Param _ Preregister[NEW[real ParamRec _ [realOps, $pageBreakAfterLastLinePenalty, real[pageBreakAfterLastLinePenalty]]], PageBreakPenalty3Op]; PageBreakPenalty4Op: TJaM.CommandProc ~ { DoStyleOp[frame, pageBreakPenalty4Param] }; pageBreakPenalty4Param: Param _ Preregister[NEW[real ParamRec _ [realOps, $pageBreakBeforeFirstLinePenalty, real[pageBreakBeforeFirstLinePenalty]]], PageBreakPenalty4Op]; PageBreakPenalty5Op: TJaM.CommandProc ~ { DoStyleOp[frame, pageBreakPenalty5Param] }; pageBreakPenalty5Param: Param _ Preregister[NEW[real ParamRec _ [realOps, $pageBreakBeforeLastLinePenalty, real[pageBreakBeforeLastLinePenalty]]], PageBreakPenalty5Op]; ClearTabStopsOp: TJaM.CommandProc ~ { ref: Style _ StyleForFrame[frame]; ref.tabStops _ NIL; ref.numTabStops _ 0; }; TabStopOp: TJaM.CommandProc ~ { ref: Style _ StyleForFrame[frame]; tabStop: TabStop _ TabSpec[ref, frame]; loc: REAL _ 0.0; tabStop.loc _ GetTabRealCode[ref, tabStop, loc, TJaM.PopReal[frame]]; loc _ GetTabLoc[tabStop, ref]; ref.numTabStops _ ref.numTabStops+1; IF ref.tabStops = NIL OR GetTabLoc[ref.tabStops.first, ref] <= loc THEN ref.tabStops _ CONS[tabStop, ref.tabStops] ELSE { -- copy list up to first with smaller loc old: LIST OF TabStop _ ref.tabStops; new: LIST OF TabStop _ CONS[old.first, NIL]; ref.tabStops _ new; FOR lst: LIST OF TabStop _ old.rest, lst.rest DO IF lst=NIL OR GetTabLoc[lst.first, ref] <= loc THEN { -- insert here new.rest _ CONS[tabStop, lst]; EXIT; }; new.rest _ CONS[lst.first, NIL]; new _ new.rest; ENDLOOP; }; }; RelativeTabStopsOp: TJaM.CommandProc ~ { ref: Style _ StyleForFrame[frame]; name: ATOM; ok: BOOL; [name, ok] _ TryToPopName[frame]; IF NOT ok THEN { -- restore name to stack and return default TJaM.PushRope[frame, "illegal value for tabStops: should be fixed or relative"]; StyleError[frame, 1]; }; SELECT name FROM $fixed => ref.fixedTabs _ TRUE; $relative => ref.fixedTabs _ FALSE; ENDCASE => { -- restore name to stack and return default TJaM.Push[frame, name]; TJaM.PushRope[frame, "illegal value for tabStops: should be fixed or relative"]; StyleError[frame, 2]; }; }; DefaultTabStopsOp: TJaM.CommandProc ~ { ref: Style _ StyleForFrame[frame]; tabStop: TabStop _ TabSpec[ref, frame]; tabStop.loc _ GetTabRealCode[ref, tabStop, loc, TJaM.PopReal[frame]]; ref.defaultTabStops _ tabStop; }; TabSpec: PROC [ref: Style, frame: Frame] RETURNS [tabStop: TabStop] ~ { -- parse tab specs looks: Tioga.Looks _ TabLooksSpec[frame]; breakIfPast: BOOL _ TabPastSpec[frame]; tabStop _ TabPattern[ref, frame]; tabStop.looks _ looks; tabStop.breakIfPast _ breakIfPast; TabAlign[tabStop, frame]; }; TabLooksSpec: PROC [frame: Frame] RETURNS [lks: Tioga.Looks] ~ { name: ATOM; ok: BOOL; SetLookBit: Rope.ActionType ~ { c _ Ascii.Lower[c]; IF c IN ['a..'z] THEN lks[c] _ TRUE; RETURN [FALSE]; }; lks _ Tioga.noLooks; [name, ok] _ TryToPopName[frame]; IF NOT ok THEN RETURN; IF name # $looks THEN { TJaM.Push[frame, name]; RETURN }; [] _ Rope.Map[base~TJaM.PopRope[frame], action~SetLookBit]; }; TabPastSpec: PROC [frame: Frame] RETURNS [break: BOOL] ~ { name: ATOM; ok: BOOL; [name, ok] _ TryToPopName[frame]; IF NOT ok THEN RETURN; SELECT name FROM $breakIfPast => break _ TRUE; $spaceIfPast => break _ FALSE; ENDCASE => { -- restore name to stack and return default TJaM.Push[frame, name]; break _ FALSE; }; }; TabPattern: PROC [ref: Style, frame: Frame] RETURNS [tabStop: TabStop] ~ { name: ATOM; ok: BOOL; [name, ok] _ TryToPopName[frame]; IF NOT ok THEN { tabStop _ NEW[blank TabStopRec]; RETURN }; SELECT name FROM $blank => tabStop _ NEW[blank TabStopRec]; $leaders => { leaderRope: ROPE; value: REAL _ 0.0; ldrStop: LeaderTabStop _ NEW[leaders TabStopRec]; tabStop _ ldrStop; [name, ok] _ TryToPopName[frame]; IF NOT ok THEN ldrStop.congruent _ TRUE ELSE SELECT name FROM $centered => ldrStop.congruent _ FALSE; $congruent => ldrStop.congruent _ TRUE; ENDCASE => { TJaM.Push[frame, name]; TJaM.PushRope[frame, "is not legal as value for tab leaders: congruent or centered"]; StyleError[frame, 2]; }; [value, ok] _ TryToPopReal[frame]; ldrStop.spacing _ GetTabRealCode[ref, tabStop, spacing, IF ok THEN value ELSE 0.0]; [leaderRope, ok] _ TryToPopRope[frame]; IF ok AND NOT leaderRope.IsEmpty THEN { IF leaderRope.Length > 1 THEN { TJaM.PushRope[frame, "Cannot specify more than one character for tab leaders"]; StyleError[frame, 1]; } ELSE ldrStop.char _ leaderRope.Fetch[0]; } ELSE { TJaM.PushRope[frame, "Must specify character for tab leaders"]; StyleError[frame, 1]; }; }; $rule => { ruleStop: RuleTabStop _ NEW[rule TabStopRec]; tabStop _ ruleStop; ruleStop.vshift _ GetTabRealCode[ref, tabStop, vshift, TJaM.PopReal[frame]]; ruleStop.weight _ GetTabRealCode[ref, tabStop, weight, TJaM.PopReal[frame]]; }; $rules => { array: TJaM.Array _ TJaM.PopArray[frame]; rulesStop: RulesTabStop _ NEW[rules TabStopRec]; tabStop _ rulesStop; rulesStop.rules _ NEW[TabArrayRec[array.len]]; FOR i: NAT IN [0..array.len/2) DO TJaM.Push[frame, TJaM.AGet[array, 2*i]]; rulesStop.rules.array[i].weight _ GetTabRealCode[ref, tabStop, weight, TJaM.PopReal[frame]]; TJaM.Push[frame, TJaM.AGet[array, 2*i+1]]; rulesStop.rules.array[i].vshift _ GetTabRealCode[ref, tabStop, vshift, TJaM.PopReal[frame]]; ENDLOOP; }; ENDCASE => { TJaM.Push[frame, name]; tabStop _ NEW[blank TabStopRec]; }; }; MissingChar: PROC [frame: Frame] ~ { TJaM.PushRope[frame, "Cannot specify more than one character for tab alignment"]; StyleError[frame, 1]; }; TabAlign: PROC [tabStop: TabStop, frame: Frame] ~ { name: ATOM; ok: BOOL; [name, ok] _ TryToPopName[frame]; IF NOT ok THEN { tabStop.alignment _ FlushLeft; RETURN }; SELECT name FROM $flushLeft => tabStop.alignment _ FlushLeft; $flushRight => tabStop.alignment _ FlushRight; $centered => tabStop.alignment _ Centered; $aligned => { alignRope: ROPE; tabStop.alignment _ Character; [alignRope, ok] _ TryToPopRope[frame]; IF ok AND NOT alignRope.IsEmpty THEN { IF alignRope.Length = 1 THEN tabStop.alignmentChar _ alignRope.Fetch[0] ELSE { TJaM.PushRope[frame, "Cannot specify more than one character for tab alignment"]; StyleError[frame, 1]; } } ELSE { TJaM.PushRope[frame, "Must specify character for tab alignment"]; StyleError[frame, 1]; }; }; ENDCASE => { TJaM.Push[frame, name]; tabStop.alignment _ FlushLeft; }; }; PointsOp: TJaM.CommandProc ~ { }; -- no change needed to convert to points pointsPerBigPoint: REAL _ 72.27/72; BigPointsOp: TJaM.CommandProc ~ {TJaM.PushReal[frame, TJaM.PopReal[frame]*pointsPerBigPoint]}; PicasOp: TJaM.CommandProc ~ { TJaM.PushReal[frame, TJaM.PopReal[frame]*PointsPerPica] }; InchesOp: TJaM.CommandProc ~ { TJaM.PushReal[frame, TJaM.PopReal[frame]*PointsPerInch] }; CentimetersOp: TJaM.CommandProc ~ { TJaM.PushReal[frame, TJaM.PopReal[frame]*PointsPerCentimeter] }; MillimetersOp: TJaM.CommandProc ~ { TJaM.PushReal[frame, TJaM.PopReal[frame]*PointsPerMillimeter] }; DidotPointsOp: TJaM.CommandProc ~ { TJaM.PushReal[frame, TJaM.PopReal[frame]*PointsPerDidot] }; EmsOp: TJaM.CommandProc ~ { oneEm: REAL ~ GetFontSize[StyleForFrame[frame]]; -- should really be width of "M" in current font TJaM.PushReal[frame, TJaM.PopReal[frame]*oneEm]; }; EnsOp: TJaM.CommandProc ~ { oneEn: REAL ~ GetFontSize[StyleForFrame[frame]]/2; -- should really be width of "N" in current font TJaM.PushReal[frame, TJaM.PopReal[frame]*oneEn]; }; ScreenSpacesOp: TJaM.CommandProc ~ { spaces: REAL ~ TJaM.PopReal[frame]; width: REAL ~ GetScreenSpaceWidth[StyleForFrame[frame]]; TJaM.PushReal[frame, spaces*width]; }; PrintSpacesOp: TJaM.CommandProc ~ { spaces: REAL ~ TJaM.PopReal[frame]; width: REAL ~ GetPrintSpaceWidth[StyleForFrame[frame]]; TJaM.PushReal[frame, spaces*width]; }; FilOp: TJaM.CommandProc ~ { TJaM.PushReal[frame, TJaM.PopReal[frame]*PointsPerFil] }; FillOp: TJaM.CommandProc ~ { TJaM.PushReal[frame, TJaM.PopReal[frame]*PointsPerFill] }; FilllOp: TJaM.CommandProc ~ { TJaM.PushReal[frame, TJaM.PopReal[frame]*PointsPerFilll] }; OpsListItem: TYPE ~ RECORD [name: ATOM, op: TJaM.CommandProc]; OpsList: TYPE ~ LIST OF OpsListItem; opsList: OpsList _ NIL; Preregister: PROC [param: Param, op: TJaM.CommandProc] RETURNS [Param] ~ { opsList _ CONS[[param.opName, op], opsList]; RETURN [param]; }; RegisterWorks4: PUBLIC PROC [frame: Frame] ~ { FOR list: OpsList _ opsList, list.rest UNTIL list=NIL DO RegisterStyleCommand[frame, list.first.name, list.first.op]; ENDLOOP; TJaM.Execute[frame, TJaM.CvX[prolog]]; }; prolog: ROPE _ " (firstFolio) 1 StyleParam (firstVisibleFolio) 1 StyleParam (lastDropFolio) 1 StyleParam (firstHeaders) 0 StyleParam (maxVerticalExpansion) 3 StyleParam (maxHorizontalExpansion) 1 fil StyleParam (sided) 1 StyleParam (keep) 0 pt StyleParam (keepStretch) 1 fil StyleParam (columnGap) 0.5 in StyleParam (topIndentStretch) 0 StyleParam (bottomIndentStretch) 0 StyleParam (hyphenation) (No) StyleParam (hyphenCode) 45 StyleParam (pageRotation) 0 StyleParam (pageRotationVerso) 0 StyleParam (mediumColor) {mediumBrightness mediumSaturation mediumHue} .cvx .def (mediumHue) 0 StyleParam (mediumSaturation) 0 StyleParam (mediumBrightness) 1 StyleParam "; LetterspacingOp: TJaM.CommandProc ~ { DoStyleOp[frame, letterspacingParam] }; letterspacingParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $letterspacing, real[letterspacing]]], LetterspacingOp]; LetterspacingStretchOp: TJaM.CommandProc ~ { DoStyleOp[frame, letterspacingStretchParam] }; letterspacingStretchParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $letterspacingStretch, real[letterspacingStretch]]], LetterspacingStretchOp]; LetterspacingShrinkOp: TJaM.CommandProc ~ { DoStyleOp[frame, letterspacingShrinkParam] }; letterspacingShrinkParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $letterspacingShrink, real[letterspacingShrink]]], LetterspacingShrinkOp]; LetterspacingGlueOp: TJaM.CommandProc ~ { DoStyleOp[frame, letterspacingGlueParam] }; letterspacingGlueParam: Param _ Preregister[NEW[glue ParamRec _ [glueOps, $letterspacingGlue, glue[letterspacing, letterspacingStretch, letterspacingShrink]]], LetterspacingGlueOp]; PagebreakOp: TJaM.CommandProc ~ { DoStyleOp[frame, pagebreakParam] }; pagebreakParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $pagebreak, real[pagebreak]]], PagebreakOp]; PagebreakStretchOp: TJaM.CommandProc ~ { DoStyleOp[frame, pagebreakStretchParam] }; pagebreakStretchParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $pagebreakStretch, real[pagebreakStretch]]], PagebreakStretchOp]; PagebreakShrinkOp: TJaM.CommandProc ~ { DoStyleOp[frame, pagebreakShrinkParam] }; pagebreakShrinkParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $pagebreakShrink, real[pagebreakShrink]]], PagebreakShrinkOp]; PagebreakGlueOp: TJaM.CommandProc ~ { DoStyleOp[frame, pagebreakGlueParam] }; pagebreakGlueParam: Param _ Preregister[NEW[glue ParamRec _ [glueOps, $pagebreakGlue, glue[pagebreak, pagebreakStretch, pagebreakShrink]]], PagebreakGlueOp]; UnderlineThicknessOp: TJaM.CommandProc ~ { DoStyleOp[frame, underlineThicknessParam] }; underlineThicknessParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $underlineThickness, real[underlineThickness]]], UnderlineThicknessOp]; UnderlineDescentOp: TJaM.CommandProc ~ { DoStyleOp[frame, underlineDescentParam] }; underlineDescentParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $underlineDescent, real[underlineDescent]]], UnderlineDescentOp]; UnderlineHueOp: TJaM.CommandProc ~ { DoStyleOp[frame, underlineHueParam] }; underlineHueParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $underlineHue, real[underlineHue]]], UnderlineHueOp]; UnderlineSaturationOp: TJaM.CommandProc ~ { DoStyleOp[frame, underlineSaturationParam] }; underlineSaturationParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $underlineSaturation, real[underlineSaturation]]], UnderlineSaturationOp]; UnderlineBrightnessOp: TJaM.CommandProc ~ { DoStyleOp[frame, underlineBrightnessParam] }; underlineBrightnessParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $underlineBrightness, real[underlineBrightness]]], UnderlineBrightnessOp]; UnderlineColorOp: TJaM.CommandProc ~ { DoStyleOp[frame, underlineColorParam] }; underlineColorParam: Param _ Preregister[NEW[color ParamRec _ [colorOps, $underlineColor, color[underlineHue, underlineSaturation, underlineBrightness]]], UnderlineColorOp]; StrikeoutThicknessOp: TJaM.CommandProc ~ { DoStyleOp[frame, strikeoutThicknessParam] }; strikeoutThicknessParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $strikeoutThickness, real[strikeoutThickness]]], StrikeoutThicknessOp]; StrikeoutAscentOp: TJaM.CommandProc ~ { DoStyleOp[frame, strikeoutAscentParam] }; strikeoutAscentParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $strikeoutAscent, real[strikeoutAscent]]], StrikeoutAscentOp]; StrikeoutHueOp: TJaM.CommandProc ~ { DoStyleOp[frame, strikeoutHueParam] }; strikeoutHueParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $strikeoutHue, real[strikeoutHue]]], StrikeoutHueOp]; StrikeoutSaturationOp: TJaM.CommandProc ~ { DoStyleOp[frame, strikeoutSaturationParam] }; strikeoutSaturationParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $strikeoutSaturation, real[strikeoutSaturation]]], StrikeoutSaturationOp]; StrikeoutBrightnessOp: TJaM.CommandProc ~ { DoStyleOp[frame, strikeoutBrightnessParam] }; strikeoutBrightnessParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $strikeoutBrightness, real[strikeoutBrightness]]], StrikeoutBrightnessOp]; StrikeoutColorOp: TJaM.CommandProc ~ { DoStyleOp[frame, strikeoutColorParam] }; strikeoutColorParam: Param _ Preregister[NEW[color ParamRec _ [colorOps, $strikeoutColor, color[strikeoutHue, strikeoutSaturation, strikeoutBrightness]]], StrikeoutColorOp]; OutlineBoxThicknessOp: TJaM.CommandProc ~ { DoStyleOp[frame, outlineBoxThicknessParam] }; outlineBoxThicknessParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $outlineBoxThickness, real[outlineboxThickness]]], OutlineBoxThicknessOp]; OutlineBoxBearoffOp: TJaM.CommandProc ~ { DoStyleOp[frame, outlineBoxBearoffParam] }; outlineBoxBearoffParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $outlineBoxBearoff, real[outlineboxBearoff]]], OutlineBoxBearoffOp]; OutlineBoxHueOp: TJaM.CommandProc ~ { DoStyleOp[frame, outlineBoxHueParam] }; outlineBoxHueParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $outlineBoxHue, real[outlineboxHue]]], OutlineBoxHueOp]; OutlineBoxSaturationOp: TJaM.CommandProc ~ { DoStyleOp[frame, outlineBoxSaturationParam] }; outlineBoxSaturationParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $outlineBoxSaturation, real[outlineboxSaturation]]], OutlineBoxSaturationOp]; OutlineBoxBrightnessOp: TJaM.CommandProc ~ { DoStyleOp[frame, outlineBoxBrightnessParam] }; outlineBoxBrightnessParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $outlineBoxBrightness, real[outlineboxBrightness]]], OutlineBoxBrightnessOp]; OutlineBoxColorOp: TJaM.CommandProc ~ { DoStyleOp[frame, outlineBoxColorParam] }; outlineBoxColorParam: Param _ Preregister[NEW[color ParamRec _ [colorOps, $outlineBoxColor, color[outlineboxHue, outlineboxSaturation, outlineboxBrightness]]], OutlineBoxColorOp]; BackgroundAscentOp: TJaM.CommandProc ~ { DoStyleOp[frame, backgroundAscentParam] }; backgroundAscentParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $backgroundAscent, real[backgroundAscent]]], BackgroundAscentOp]; BackgroundDescentOp: TJaM.CommandProc ~ { DoStyleOp[frame, backgroundDescentParam] }; backgroundDescentParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $backgroundDescent, real[backgroundDescent]]], BackgroundDescentOp]; BackgroundHueOp: TJaM.CommandProc ~ { DoStyleOp[frame, backgroundHueParam] }; backgroundHueParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $backgroundHue, real[backgroundHue]]], BackgroundHueOp]; BackgroundSaturationOp: TJaM.CommandProc ~ { DoStyleOp[frame, backgroundSaturationParam] }; backgroundSaturationParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $backgroundSaturation, real[backgroundSaturation]]], BackgroundSaturationOp]; BackgroundBrightnessOp: TJaM.CommandProc ~ { DoStyleOp[frame, backgroundBrightnessParam] }; backgroundBrightnessParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $backgroundBrightness, real[backgroundBrightness]]], BackgroundBrightnessOp]; BackgroundColorOp: TJaM.CommandProc ~ { DoStyleOp[frame, backgroundColorParam] }; backgroundColorParam: Param _ Preregister[NEW[color ParamRec _ [colorOps, $backgroundColor, color[backgroundHue, backgroundSaturation, backgroundBrightness]]], BackgroundColorOp]; AreaHueOp: TJaM.CommandProc ~ { DoStyleOp[frame, areaHueParam] }; areaHueParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $areaHue, real[areaHue]]], AreaHueOp]; AreaSaturationOp: TJaM.CommandProc ~ { DoStyleOp[frame, areaSaturationParam] }; areaSaturationParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $areaSaturation, real[areaSaturation]]], AreaSaturationOp]; AreaBrightnessOp: TJaM.CommandProc ~ { DoStyleOp[frame, areaBrightnessParam] }; areaBrightnessParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $areaBrightness, real[areaBrightness]]], AreaBrightnessOp]; AreaColorOp: TJaM.CommandProc ~ { DoStyleOp[frame, areaColorParam] }; areaColorParam: Param _ Preregister[NEW[color ParamRec _ [colorOps, $areaColor, color[areaHue, areaSaturation, areaBrightness]]], AreaColorOp]; OutlineHueOp: TJaM.CommandProc ~ { DoStyleOp[frame, outlineHueParam] }; outlineHueParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $outlineHue, real[outlineHue]]], OutlineHueOp]; OutlineSaturationOp: TJaM.CommandProc ~ { DoStyleOp[frame, outlineSaturationParam] }; outlineSaturationParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $outlineSaturation, real[outlineSaturation]]], OutlineSaturationOp]; OutlineBrightnessOp: TJaM.CommandProc ~ { DoStyleOp[frame, outlineBrightnessParam] }; outlineBrightnessParam: Param _ Preregister[NEW[real ParamRec _ [realOps, $outlineBrightness, real[outlineBrightness]]], OutlineBrightnessOp]; OutlineColorOp: TJaM.CommandProc ~ { DoStyleOp[frame, outlineColorParam] }; outlineColorParam: Param _ Preregister[NEW[color ParamRec _ [colorOps, $outlineColor, color[outlineHue, outlineSaturation, outlineBrightness]]], OutlineColorOp]; RunFile: PROC [frame: Frame, name: ATOM, fileName: ROPE] RETURNS [ran: BOOL] ~ { known: BOOL; [known, ] _ TJaM.TryToLoad[frame, name]; IF known THEN RETURN [FALSE]; TJaM.Push[frame, fileName]; TJaM.Execute[frame, run]; RETURN [TRUE]; }; StartTheWorks: PUBLIC PROC ~ { frame: Frame _ defaultFrame _ TJaM.NewFrame[]; get _ GetCommand[frame, TJaM.AtomFromRope[".get"]]; run _ GetCommand[frame, TJaM.AtomFromRope[".run"]]; load _ GetCommand[frame, TJaM.AtomFromRope[".load"]]; TJaM.Execute[frame, TJaM.AtomFromRope[".sysdict"]]; sysdict _ TypeCheckDict[TJaM.Pop[frame]]; IF NOT RunFile[frame, $user ,"start.jam"] THEN TJaM.Execute[frame, TJaM.AtomFromRope[".start"]]; userdict _ TJaM.DictTop[frame]; styledict _ InitDict[$TiogaStylesDictionary]; TJaM.AttachDict[styledict, userdict]; TJaM.End[frame]; TJaM.Begin[frame, styledict]; stylesDicts[base] _ InitDict[$TiogaBaseStylesDictionary]; stylesDicts[print] _ InitDict[$TiogaPrintStylesDictionary]; stylesDicts[screen] _ InitDict[$TiogaScreenStylesDictionary]; bindingDict _ InitDict[$TiogaBindingDictionary, 200]; attachmentsDict _ InitDict[$TiogaAttachedStylesDictionary]; [] _ RunFile[frame, $StyleError, "TiogaUtils.jam"]; RegisterWorks1[frame]; RegisterWorks2[frame]; RegisterWorks3[frame]; RegisterWorks4[frame]; RegisterStyleLiteral[frame, $the]; RegisterStyleLiteral[frame, $smaller]; RegisterStyleLiteral[frame, $bigger]; RegisterStyleLiteral[frame, $percent]; RegisterStyleLiteral[frame, $regular]; RegisterStyleLiteral[frame, $bold]; RegisterStyleLiteral[frame, $italic]; RegisterStyleLiteral[frame, TJaM.AtomFromRope["bold+italic"]]; RegisterStyleLiteral[frame, TJaM.AtomFromRope["+bold"]]; RegisterStyleLiteral[frame, TJaM.AtomFromRope["+italic"]]; RegisterStyleLiteral[frame, TJaM.AtomFromRope["-bold"]]; RegisterStyleLiteral[frame, TJaM.AtomFromRope["-italic"]]; RegisterStyleLiteral[frame, TJaM.AtomFromRope["caps+lowercase"]]; RegisterStyleLiteral[frame, TJaM.AtomFromRope["caps+smallcaps"]]; RegisterStyleLiteral[frame, $lowercase]; RegisterStyleLiteral[frame, $caps]; RegisterStyleLiteral[frame, $all]; RegisterStyleLiteral[frame, $visible]; RegisterStyleLiteral[frame, TJaM.AtomFromRope["letters+digits"]]; RegisterStyleLiteral[frame, $none]; RegisterStyleLiteral[frame, $justified]; RegisterStyleLiteral[frame, $flush]; RegisterStyleLiteral[frame, $flushLeft]; RegisterStyleLiteral[frame, $flushRight]; RegisterStyleLiteral[frame, $centered]; RegisterStyleLiteral[frame, $filled]; RegisterStyleLiteral[frame, $outlined]; RegisterStyleLiteral[frame, $filled]; RegisterStyleLiteral[frame, TJaM.AtomFromRope["filled+outlined"]]; RegisterStyleLiteral[frame, $fixed]; RegisterStyleLiteral[frame, $relative]; RegisterStyleLiteral[frame, $looks]; RegisterStyleLiteral[frame, $breakIfPast]; RegisterStyleLiteral[frame, $spaceIfPast]; RegisterStyleLiteral[frame, $blank]; RegisterStyleLiteral[frame, $leaders]; RegisterStyleLiteral[frame, $rule]; RegisterStyleLiteral[frame, $rules]; RegisterStyleLiteral[frame, $aligned]; RegisterStyleLiteral[frame, $congruent]; { frame: ARRAY [0..4) OF Frame; FOR i: NAT IN [0..4) DO frame[i] _ GetFrame[NIL, NIL, screen] ENDLOOP; FOR i: NAT IN [0..4) DO FreeFrame[frame[i], NIL, screen] ENDLOOP; }; NodeStyleOps.InitializeDefaultStyle["Cedar"]; [] _ NodeStyleOps.LoadStyle[NodeStyleOps.defaultStyleName]; }; StartTheWorks[!]; END. ΆNodeStyleSimpleImpl.mesa Copyright Σ 1985, 1986 by Xerox Corporation. All rights reserved. written by Bill Paxton, January 1981 Paxton, December 21, 1982 9:55 am Maxwell, January 6, 1983 9:50 am Russ Atkinson, March 7, 1985 3:29:21 am PST Michael Plass, May 9, 1986 12:27:55 pm PDT Rick Beach, March 27, 1985 10:54:03 am PST Doug Wyatt, September 25, 1986 8:14:48 pm PDT NodeStyleImpl Real Parameters array of real-valued distances next free entry in realArray reserve entry 0 for 0.0 Tabs For num in [0..RulesTabCount), returns the weight and vshift values for that rule. Dimensions NodeStyleOpsImpl Style Operations create a style body copy a style body get from a small cache don't free more than once or disaster! Local Styles Apply Style to Node NodeStyleObsolete.EvalFreeVars[ref, node]; ApplyAll Cache when clearing, go all the way to applyCacheSize rather than stopping at applyCache.depth Update ApplyAll Cache due to Editing Operations if change invalidates one node only, remove that node else clear entire cache Hashing Style Rule Cache Looks Cache Object Cache Flush Caches Style Parameter Extensions May raise NodeStyleOps.nonNumeric or TJaM.Error[undefkey]. May raise NodeStyleOps.nonNumeric or TJaM.Error[undefkey]. Miscellaneous Does an ApplyAll and then returns the style name Initialization register the notify proc that updates the style caches when edits occur initialize all the style caches establish the default styles wired into Tioga provide some basic style attribute values in case no style gets loaded successfully register the special handling procedures for the local style property: StyleDef NodeStyleWorks1Impl Execution Frames for Style Machinery -- style is the StyleRef you will be using with the frame -- styleName tells which style dictionary you want -- will give you default style if requested style bombs during load -- first try to find one that already has the right style -- look for any free one get the proper style dictionary on the frame dictionary stack name and kind are just a hint about what style dictionary is on the frame stack add it to cache of free frames or really free it if cache full remove it from active frame info Style Dictionaries fake it so looks as if had a file saying "BeginStyle (default) AttachStyle EndStyle" Style File handling. Search rule handling Locking to avoid concurrent changes to internal style representation. Running styles and validation of style to file correspondence. Called from elsewhere in Tioga when something changes that may have changed any style. Does not attempt to refresh screen. Called from elsewhere in Tioga when something changes that may have changed a style. Does not attempt to refresh screen. this is probably where the use of working directories for style files needs to be added create rule name dict in baseDict record the style kind expects on op stack Execute Styles Utility routine; ensures same stack depth after execution; does NOT handle TJaM.Stop makes sure that same stack depth after execute makes sure that same stack depth after execute makes sure that same stack depth after execute makes sure that same stack depth after execute names are "look.a", "look.b", "look.c", etc. Implementing Style Attribute Operations -- e.g., "2 pt bigger leading" -- e.g., "2 percent bigger leading" -- e.g., "2 pt smaller leading" -- e.g., "2 percent smaller leading" General Error Routines Name Parameter Operations Real Parameter Operations Glue Parameter Operations Color Parameter Operations Initialization register the various style commands and JaM commands in this module NodeStyleWorks2Impl Support Procs Readonly Style Variables StyleParam Implementation called to declare a special style parameter create a 2-element array with (name, objectToExecute) create a key which is "!!name" (sort of unique, don't you think) like DoStyleOperation, but for special parameters store the object as new value -- add it to the binding dictionary -- add it to the binding dictionary -- add it to the current dictionary register the various style commands and JaM commands in this module NodeStyleWorks3Impl Initialization This must be first to pick up the Preregister calls in the start code. Style Name Font Parameters Font Prefix Font Family Font Size Font Face Font Alphabets Text Rotation Indents Left Indent Right Indent First Indent First Indent on the Right Rest Indent Runaround Left Runaround Right Top Indent Bottom Indent Leading Parameters Line Leading Glue Top Leading Glue Bottom Leading Glue Line Formatting Underlining Strikeout Miscellaneous Positioning Parameters TabStops Line Weight Page Layout Parameters Page Width Text Color Page Break Penalty Parameters Fancy Tabs Insert in list of tab stops. kept sorted by decreasing location, i.e., from right to left on page this may result in a slight decrease in efficiency for the formatters, but it substantially reduces allocations during the creation of the list since styles tend to define tab stops in increasing order, so can add to start of list and list additions must be non-destructive of the previous list PROC [c: CHAR] RETURNS [quit: BOOL _ FALSE] restore name to stack and return default Dimensions NodeStyleWorks4Impl Initialization This must be first to pick up the Preregister calls in the start code. New Style Parameters These are style parameters that have not been given a place NodeStyle.RealParam. They may be used in a style just like any other real-valued style parameter, and they may be accessed from a client program by means of NodeStyleOps.GetStyleParam. Number associated with first formatted page Folios smaller than this will not be printed. Use a large value to kill page numbers. Last folio to be placed at the bottom center of the page Page headers will first appear on the page with this folio. Extra fil is inserted if the vertical expansion ratio would exceed this. Spaces in justified lines are never stretched by more than this amount, possibly resulting in a somewhat ragged right margin. Applies at the node level. Should be 1 or 2 Asserts that a new column or page should be started if there is less than this amount of vertical space remaining when the first line of the node is formatted. Added to the bottomIndentStretch when a new column is started because of a keep. Minimum gap between columns Stretchability at the top of the column Stretchability at the bottom of the column Kind of hyphenation applied to this node (applies at node level) Character code for hyphen (applies at character level) Degrees of counterclockwise rotation for the whole page Degrees of counterclockwise rotation for verso pages (only used if 2 sided) Color of the page background Letter Spacing Glue Pagebreak Glue Underline Dimensions and Color Strikeout Dimensions and Color Outline Box Dimensions and Color Background Dimensions and Color Area Color Outline Color NodeStyleWorksStartImpl if name is unknown in the current frame, then run the named file Some JaM commands needed to run the style machinery Remember the system dictionary, since the style machinery manipulates the dictionary stack Check if we have run the start jam code: (start.jam) .run This provides a user dictionary into which start.jam loads util.jam and errordefs.jam Remember the user dictionary pointer Create the dictionary of Tioga style names Replace userdict by styledict for rest of startup Create and register dictionaries for style rules, name bindings, and attached styles Check if have run the Tioga utility jam code: (TiogaUtils.jam) .run Register various style and JaM commands implemented elsewhere TJaM.Register[frame, $GetFreeVarOp, NodeStyleObsolete.GetFreeVarOp]; TJaM.Register[frame, $GetFreeVarObjOp, NodeStyleObsolete.GetFreeVarObjOp]; Register various literals used by the style machinery as keywords numeric style attributes font attributes font alphabets underlining and strikeout line formatting graphical paths tab stop positioning tab stop attributes Initialize the small cache of frames by allocating and freeing some Initialize the default style Κ`˜codešœ™KšœB™BKšœ$™$Kšœ!™!K™ K™+K™*J™*K™-—K™šΟk ˜ Kšœœ ˜Kšœœ˜ Kšœ œ˜!Kšœœ˜Kšœ œ˜Kšœ œi˜xKšœ œ2˜DKšœœ‹˜ŸKšœœœ ˜*Kšœ˜Kšœ œ(˜:Kšœœ'˜1—K˜Kš Ρblnœœœœœ ˜8Kšœf˜mKšœ ˜šœœœ˜%K™Kšœœœ˜Kšœœ˜Kšœœ˜—head™ šœ™Kšœœœœ˜ šœœœœ˜"K™—š Οn œœœ œœœ˜?šœœ˜Kšœœœ˜Kšœœœ˜Kšœ˜—Kšœ˜K˜—šœ œœ œœœœ œœœ˜OKšΟc™—šœ˜Kšœ™Kšœ™—Kšœœ˜K˜š Ÿ œœœ œœ˜FKšœœœ˜šœœ œ˜@Kšœœœ ˜CKšœ˜—Kšœœ! ˜JKšœ9 ˜RKšœ˜K˜—šŸœœœ%œ ˜HK˜"Kšœœœ/˜UK˜Kšœ˜K˜—š Ÿœœœœ œ ˜QKšœ˜Kšœœœ˜-šœ˜š œœ$œœ˜Dšœœ˜Kš œœœœœ ˜?Kšœ˜—Kšœ˜—Kšœ (˜/K˜—Kšœ˜K˜——™š Ÿ œœœœœ ˜HK˜Kšœœœ˜>Kšœ˜$Kšœ˜K˜—š Ÿœœœ œœ ˜XK˜Kšœ"œœ˜BKšœ"˜(Kšœ˜K™—š Ÿœœœœœ ˜SK˜Kšœ!œœ˜AKšœ!˜'Kšœ˜K™—š Ÿœœœœœ ˜SK˜Kšœ!œœ˜AKšœ!˜'Kšœ˜K™—š Ÿœœœ7œœ˜zKšœ˜Kšœœœ4˜ZK˜K˜—š Ÿœœœœ œ˜KKšœ˜Kšœ˜K˜—š Ÿœœœœœœ˜^K™RKšœ&˜&Kšœ&˜&Kšœ˜K˜—šŸœœ/œ œ ˜cšœ"œœ˜3šœœ˜Kš œœœœœœ ˜VKšœ˜—Kšœ˜—Kšœ (˜.Kšœ˜K˜——šœ ™ Kšœœœ˜"Kšœœœ ˜4Kšœœœ˜7Kšœœœ˜:Kšœœœ˜8Kšœœœ ˜$Kšœœœ˜7Kšœœœ˜9——™šœ™š Ÿ œœœœœ˜3Kšœ8˜8Kšœ1˜7J˜J˜—š Ÿ œœœœœ˜3Jšœ5˜;J˜K˜—K˜šŸœœœœ ˜'Kšœ™Kšœœ ˜Kšœ˜K˜—šŸœœœ˜+Kšœ™K˜K˜K˜—š Ÿœœœœ œœ˜DKšœ™Kšœœœ˜Kšœœœœ˜%Kš œœœœœ˜*Kš œœœœœ˜*Kšœ˜Kšœ˜—K˜š Ÿœœœœœ˜:Kšœ&™&Kšœœœ˜Kšœœœ˜Kšœœœœ˜Kšœœœœ˜Kšœ˜K˜—šŸ œœœœ ˜ZKšœ?˜?K˜Kšœ1˜1K˜K˜—š Ÿ œœœœœœ˜:šŸœœ˜(K˜6K˜—Kšœ œœ˜-Kšœœ˜Kšœ˜K˜—šŸ œœœœœœœ˜GšŸœœ˜*šœ˜ Kšœ)˜-Kšœ<˜@—K˜—Kšœ œœ˜/Kšœœ˜Kšœ˜K˜—š Ÿ œœœœœœ˜Kšœœœœ ˜@Kšœœœœ ˜BK˜šŸœœ˜Kšœœ˜,Kšœœ˜(Kšœ˜K˜—šŸœœœ˜CK˜—š Ÿœœœœœœ˜>Kšœœœ˜K˜K˜K˜—šŸœœœœ˜2KšœX™XKš œœœœœœ˜MKšœ˜K˜K˜—šŸœœœœ˜EKšœœœ˜Kšœœ$˜.šœœœœ˜,šœœ ˜-šœœœ˜)Kšœ œ˜Kšœ˜—Kšœ˜Kšœ˜Kšœ˜—Kšœ˜—Kšœ˜K˜—š Ÿœœœ0œ œ œ˜yKšœœœ˜Kšœœ$˜.Kšœœ 1˜MKšœ(˜(š œœ œœ˜6šœœ#œ  ˜IKšœ$˜$Kšœ(˜(Kšœ˜Kšœœ˜Kšœ˜—Kšœ˜—Kšœœ˜Kšœ˜K˜—šŸœœœ'œ˜TKšœœœ˜Kšœœ$˜.Kšœœœ˜'K˜Kšœ!˜!Kš œœœœ œœ˜HKšœ˜K˜K˜——™/Kšœœ˜#šŸœœ œœ ˜.Kšœ5™5Kšœ™šŸœœ˜#Kšœœœ˜9Kšœ"˜&Kšœ˜—šœœ˜Kš œœœœœœ˜cKšœœœ,˜;šœœœœ ˜SKšœœ ˜;šœœ ˜šœ ˜#Kšœœœ%˜FKšœ˜—šœ ˜#K˜%—Kšœ˜—Kšœ˜—Kšœœœ)˜8šœœœ˜(Kšœ$œ˜:Kšœ˜—Kšœœ 6˜H—K˜K˜——™šŸ œœ>œœœœœ˜wKšœœœ œœœœœœ7˜qKšœž˜žKšœ!œ˜;šœ˜K˜———™Kšœœ ˜7Kšœœ ˜DKšœœœ˜0Kš œœœœœ˜2šœœœœ ˜8K˜—Kšœ œœ˜#šœœœ˜Kšœœ %˜:Kšœœ˜Kšœœ˜Kšœ œ˜Kšœœ˜Kšœ˜K˜—šŸœœ˜Kšœœ˜&Kšœœ˜(Kšœœ˜)Kšœ˜K˜—š Ÿœœœœœ˜3Kšœœœ˜Kšœ˜K˜K˜—š Ÿœœœœœ˜6šœœœ˜#K˜Kš œœœœœ˜IK˜—Kšœ˜K˜—K˜šŸ œœœœ˜IK˜Kšœ˜š Ÿœœœœœ˜.Kšœœœ˜Kšœ˜K˜&šœ ˜šœ˜ šœœœ˜.K˜K˜"Kšœœ˜Kšœ˜—Kšœœœ ˜1Kšœ˜—Kšœœ˜ Kšœ œœœ˜#Kšœ˜—Kšœ˜—šŸœœœ˜Kšœœœ˜Kšœ˜Kšœ œ˜8šœ .˜1šœ˜ Kšœœœœ ˜IKšœœ ˜'Kšœ˜—Kšœœ˜ Kšœ œœ  ˜(Kšœ˜—K˜K˜K˜K˜$K˜—Kš œœœ œœœ˜-Kšœ!œ˜3Kšœœœ˜!Kšœ %˜3Kšœ4œ˜KKšœœ œœ˜7Kšœ˜K˜——™ Kšœœ ˜8Kšœœ ˜FKšœœœ˜2Kšœœœœ ˜;Kšœœœœ ˜:Kšœ œœ˜%šœœœ˜Kšœœ˜Kšœœ˜Kšœœ˜Kšœ œ˜Kšœœ˜Kšœ˜K˜—šŸœœ˜Kšœœ˜(Kšœœ˜*Kšœœ˜+K˜K˜—š Ÿœœœœœ˜4Kšœœœ˜K˜K˜K˜—šŸœœœœ˜.Kšœœœœ˜.K˜Kšœœœ&œ˜VKšœ˜K˜—K˜šŸ œœœ4˜KKšœ˜K˜š Ÿœœœœœ˜/Kšœœœ˜Kšœ˜K˜(šœ ˜šœ˜!šœ œœ˜0K˜K˜$Kšœœ˜Kšœ˜—Kšœœ ˜1Kšœ˜—Kšœœ˜!Kšœ œœ˜Kšœ˜—Kšœœ˜Kšœ˜—šŸœœœ˜Kšœœœ˜Kšœ˜Kšœ"œ˜;šœ /˜2šœ˜!Kšœ œ œœ ˜KKšœœ ˜1Kšœ˜—Kšœœ˜!Kšœ œœ  ˜(Kšœ˜—K˜K˜K˜K˜&K˜—Kšœœœ˜%Kšœ œ˜3Kšœœœ˜"Kšœ %˜3Kšœ5œ˜OK˜K˜——™ Kšœœ ˜9Kšœœ ˜HKšœœœ˜4Kšœœœœ˜@šœœœœ ˜BK˜—šœœœ˜Kšœœ˜#Kšœ œ˜ Kšœœ˜Kšœ œ˜Kšœœ˜Kšœ˜K˜—šŸœœ˜Kšœœ˜.Kšœœ˜,Kšœœ˜-Kšœ˜K˜—š Ÿœœœœœ˜5Kšœœœ˜K˜K˜K˜—šŸœœœœ˜/Kšœœœœ˜/Kšœ˜Kš œœœœœ˜QKšœ˜K˜—šŸ œœœ9˜QK˜Kšœ˜š Ÿœœœœœ˜0Kšœœœ˜Kšœ˜K˜*šœ ˜šœ˜$šœ œ œ˜2K˜ K˜&Kšœœ˜Kšœ˜—Kšœœ ˜'Kšœ˜—Kšœœ˜"Kšœ œœ˜Kšœ˜—Kšœœ˜Kšœ˜—šŸœœœ˜ Kšœœœ˜Kšœ˜Kšœ$œ˜>šœ 0˜3šœ˜$Kšœ œ!œœ ˜MKšœœ ˜'Kšœ˜—Kšœœ˜"Kšœ œœ  ˜(Kšœ˜—K˜"K˜ K˜ K˜(K˜—Kšœœœ˜#Kšœ#œ˜7Kšœœœ˜#Kšœ %˜3Kšœ7œ˜RKšœ˜K˜——™ šŸ œœœœ˜"Kšœœœ˜Kšœ œ˜Kšœ˜K˜—šŸ œœœ˜"K˜K˜K˜K˜K˜K˜——™šœ œœœ˜ K™—šŸ œœœœ œœœ˜gKšœ:™:Kšœ9˜9šœœ˜Jšœœ!˜'Jšœœ#˜)Jšœœ ˜—Kšœ˜ Kšœ˜K˜—šŸœœœœ œœœ˜kKšœ:™:Kšœ9˜9šœœ˜Jšœœ!˜'Jšœœ;˜AJšœœ ˜—Kšœ˜ Kšœ˜K˜—š Ÿœœœœ œœ˜nK˜ Kšœœ&˜/šœ"œœ˜3šœœ˜Jš œœœœœ ˜NJšœ˜—Kšœ˜—K˜4Kšœ%˜%K˜1Kšœ˜ Kšœ˜K˜——šœ ™ š Ÿœœœœœ˜IKšœ0™0K˜K˜K˜K˜K˜K˜——šœ™šŸœœœ&œ˜RK˜"Kšœœ˜$K˜KšœG™GKšœœ˜Kšœœ˜!Kšœœ˜Kšœœ˜Kšœœ˜ KšœF˜FK˜Kšœ™K˜K˜K˜K˜Kšœ œ˜K˜Kšœ-™-K˜K˜K˜K˜KšœS™SK˜+K˜$K˜#K˜#K˜4K˜4K˜3K˜4K˜2K˜5K˜5Kšœ-˜-Kšœ+˜+Kšœ-˜-Kšœ*˜*K˜KšœO™OKšœg˜gK˜Kšœ ˜ Kšœ˜———™šœ$™$Kšœœœ˜K˜Kšœœ˜Kšœ œ˜%Kšœœ˜K˜Kšœ œœ˜$Kšœœœ1˜MK˜š Ÿœœœœœ˜_Kšœ9™9Kšœ2™2KšœC™CKšœœ˜ šŸ œœœœ˜7Kšœœœ˜K˜$šœœœ˜Kšœ:™:š œœœœ˜DKšœ#œœ˜1—š œœœœ˜DKšœ#œœ˜1—š œœœœ˜DKšœ#œœ˜1—š œœœœ˜DKšœ#œœ˜2——Kšœ™Kšœœœ$œ˜AKš œœœœ$œ˜FKš œœœœ$œ˜FKš œœœœ$œ˜Fšœ˜Kšœ˜K˜K˜K˜—K˜—šŸ œœœ˜Kšœœœ˜Kšœ œœ#˜7Kšœœ œœ#˜Kšœ œœ)œ˜GKšœœœ,˜NKšœ˜—Kšœ˜—Kšœ 9˜Všœ œœ˜Kšœ=™=K˜Kšœœœ˜K˜=šœœ )˜9šœ)œ !˜SK˜K˜<šœœ.˜>Kšœœ˜ —Kšœ ˜—šœœœ ˜-šœ!˜(Kšœœ˜——Kšœ˜—Kšœœœ8˜HKšœ˜—Kšœœ!œœ˜FK˜K˜—K˜š Ÿ œœœœœ˜OKšœO™OKšœœœ˜K˜"Kšœ>™>šœœœ˜Kšœ?˜?—šœœœœ˜Kšœ?˜?—šœœœœ˜ K˜?—šœœœœ˜K˜?—Kšœ  ˜CKšœ ™ šœ˜Kšœœ œ˜)Kšœœ œ˜)Kšœœ œ˜)Kšœœ œ˜)š œœ&œœ˜DKš œœœœœ˜EKšœ˜——K˜—K˜šŸ œœœœ˜DšŸœœœœ˜(Kšœœœ˜šœ˜Kšœ œ ˜Kšœ œ ˜Kšœ œ ˜Kšœ œ ˜š œœ&œœ˜DKšœœœ ˜+Kšœ˜ ———šœœœ ˜=šœ œ˜Kšœ œœ$˜Kšœ˜—š Ÿ œœ œ œœ ˜GKšœœœœE˜WKšœœ8˜BKšœ œœ˜Kšœœ˜+š œ œœœ˜&Kšœ*œ)œ œ˜kKšœ˜Kšœ˜—Kš œ œœœœ˜$Kšœœ#˜.Kšœ˜——™EšŸœœœ œ˜(Kšœœ˜*šŸœœœ˜Kš œœœœœ˜PKšœ;˜;Kšœ˜—šŸœœœ˜Kšœ$˜$Kšœœœœ˜JKšœ˜—Kšœ˜Kšœ œ˜Kšœ ˜ Kšœ˜——šœ>™>š Ÿœœœœ œœ˜?K™VK™#šŸœœ˜š Ÿœœœœœœ˜=Kšœœœ œ˜2Kšœœ˜Kšœ˜—Kšœ(˜(Kšœ˜—Kšœ˜Kšœ˜K˜—šŸ œœœ œœ œœ˜PK™TK™#šŸœœ˜Kšœ0˜0Kšœœ,˜Fš œ œœ œœ˜=Kšœ ˜šœ˜Kšœœœ ˜*Kšœœœ ˜FKšœœ ˜Kšœ œ˜Kšœ˜——Kšœ˜—Kšœ˜Kšœ˜K˜—šŸœœœœœœœ˜TšŸœœ˜Kšœœœ˜ KšœW™WKšœ0˜0K˜7Kš œ œœœœ˜*Kšœ-˜-Kšœ"œ˜)Kšœ œ˜'Kšœ˜Kšœ"˜"˜Kšœ œ ˜Kšœœœ˜+Kšœœœ˜*Kšœœœ˜,Kšœ˜—Kšœ˜Kšœ œ ˜Kšœœœ˜.Kšœœ4˜>Kšœœœ˜2Kšœ˜—Kšœ˜Kšœ˜K˜—šŸœœœœœœœ˜]Kšœœœ˜ K˜7šœ$˜$Kšœœ˜#Kšœœœ˜+Kšœœœ˜*Kšœœœ˜,Kšœ˜—Kšœ œ ˜Kšœ˜—K˜—K˜Kšœœ(˜;Kšœœ(˜;K˜š Ÿœœœœœœ˜\Kšœœ˜ K˜ K˜*Kšœœ˜+šœ˜Kšœ ˜ K˜$K˜—K˜K˜—Kšœ œœ œœœœ œœ˜^šœœœ œœœœ œœ˜MKšœ-˜-Kšœ/˜/Kšœ-˜-Kšœ˜—šœœœ œœœœ œœ˜HKšœ)˜)Kšœ+˜+Kšœ)˜)Kšœ˜—K˜K˜Kšœœœ ,˜IKšœ œœ (˜CKš œ œœœœ ,˜UK˜šŸ œ˜"Kšœœœ  ˜NK˜+šŸ œœ˜%Kšœ˜Kšœ˜Kšœ˜—šŸœœœ˜˜HKšœœœ˜!Kšœ.˜.šœ˜K˜——šŸ œœ˜#KšŸœœ=˜FKšœœœ˜!Kšœ+˜+šœ˜K˜——šŸ œœ˜%KšŸœœ?˜HKšœœœ˜!Kšœ+˜+šœ˜K˜——šŸ œœ˜%KšŸœœI˜RKšœœœ˜!Kšœ+˜+šœ˜K˜———šœ™K˜Kšœ œœX˜rK˜šŸ œœ ˜ KšŸœœ>˜HKšœœœ˜"Kšœ4˜4šœ˜K˜——šŸœœ˜$KšŸœœ=˜FKšœœœ˜"Kšœ1˜1šœ˜K˜——šŸœœ˜&KšŸœœ?˜HKšœœœ˜"Kšœ1˜1šœ˜K˜——šŸœœ˜&KšŸœœI˜RKšœœœ˜"Kšœ1˜1Kšœ˜K˜——™K˜šŸœœœ˜.K˜KšœC™CKšœ7˜7Kšœ3˜3Kšœ5˜5Kšœ5˜5Kšœ7˜7Kšœ9˜9K˜.K˜8K˜:K˜8K˜6K˜6K˜8K˜———™šœ ™ š Ÿ œœœœœ˜IKšœœ˜ K˜ K˜+Kšœœœœ˜Kšœ˜Kšœ˜K˜—š Ÿœ œœœœ˜8šœœœ˜Kšœœ˜KšŸ œœ ˜5šœ*œ˜2Kšœœ˜Kšœœœ˜,Kš œœœ œ,œ˜LKšœ˜K˜#K˜K˜—Kšœ˜—Kšœ˜ Kšœ˜K˜—š Ÿœ œœœœ˜8š Ÿœœœœœ˜8Kšœ˜—Kšœ7˜=Kšœ˜K˜—š Ÿœœœœœ˜K˜K˜—š Ÿœ œœ œœ˜_K™5K˜Kšœ˜Kšœ%˜%Kšœ˜K˜K˜—š Ÿ œœœœœœ˜?K™@Kšœ œœ˜.Kšœœœ ˜K˜&Kšœ5˜5Kšœ%˜%K˜ K˜K˜—šŸ œ˜Kšœ1™1Kšœœ˜ Kšœœ˜ Kšœœ˜ K˜$šŸœœ˜K˜Kšœ/˜/K˜K˜K˜—šŸ œœœ ˜%šœ&œœ˜7Kšœœœ˜%Kšœœœ ˜)Kšœ˜—K˜Kšœ ˜3Kšœ˜Kšœ˜—šŸœœ˜Kšœœ0˜DK˜—KšŸœœ&˜0šŸœœœ˜Kšœœ˜ K˜K˜K˜K˜—šŸœœœ˜Kšœ˜Kšœ˜Kšœ˜—šŸœœœ˜Kšœ˜Kšœ˜Kšœ˜—šŸœœ œ˜!Kšœœ˜ K˜K˜K˜K˜—Kšœ $˜:K˜$šœœœ˜(Kšœ™—šœœ˜K˜˜ Kš˜K˜$šœœ˜ Kšœ˜!šœœœ!˜=Kšœ œ˜——Kšœ˜—˜ Kš˜Kšœ$˜$šœœ˜ Kšœ˜"šœœœ!˜=Kšœ œ˜——Kšœ˜—K˜)Kšœ˜—K˜K™—šŸœœœœ˜YKšœ!˜!Kšœ#™#Kšœ4˜4šœ˜K˜——šŸœœœœ˜@Kšœ#™#K˜"Kšœ#™#K˜(K˜K˜—šŸœ˜(Kšœœ˜Kšœœ˜ Kšœœ˜ K˜šœœœ˜K˜%Kšœ ˜ K˜!Kšœ ˜ Kšœ˜—šœ˜Kšœ ˜ Kšœœœœ˜Kšœ˜K˜ Kšœ œ˜*Kšœ˜—K˜K˜—šŸœœœ˜.KšœC™CK˜.K˜*K˜4K˜0Kšœ,˜,K˜<šœ˜K˜————™šœ™K™FK™Kšœ œœœ˜>Kšœ œœœ ˜$šœœ˜K˜—šŸ œœ&œ ˜JJšœ œ˜,Jšœ ˜J˜J™—šŸœœœ˜.šœ$œœ˜8Kšœ<˜˜MKšœ(œœ†˜ΖK˜šŸœ˜šœœ˜0K˜K˜%Kšœ˜Kšœ˜Kšœœ˜—˜K˜——šŸœ˜%šŸœœœ˜'Kšœ˜Kšœ˜Kšœ˜—šœœ˜&K˜K˜%Kšœ˜Kšœ˜Kšœ ˜—Kšœ˜—Kšœœ'˜9Kšœœ'˜=—šœ ™ KšŸœ=˜KKšœ'œP˜z——™šœ ™ KšŸ œ;˜GKšœ%œJ˜r—šœ ™ KšŸ œ<˜IKšœ&œM˜v—šœ ™ KšŸ œ<˜IKšœ&œM˜v—šœ™KšŸœA˜SKšœ+œ\˜Š—šœ ™ KšŸ œ;˜GKšœ%œJ˜r—™KšŸœ>˜MKšœ(œS˜~—™KšŸœ?˜OKšœ)œV˜‚—šœ ™ KšŸ œ:˜EKšœ$œG˜n—šœ ™ KšŸœ=˜KKšœ'œP˜z——™šœ™KšŸ œ=˜JKšœ&œE˜nK˜KšŸœC˜WKšœ-œZ˜ŠK˜KšŸœB˜UKšœ,œW˜†K˜KšŸœ@˜QKšœ*œl˜™K˜—šœ™KšŸ œ<˜HKšœ%œJ˜rK˜KšŸœB˜UKšœ,œ_˜ŽK˜KšŸœA˜SKšœ+œ\˜ŠK˜KšŸœ?˜OKšœ)œw˜£K˜—šœ™KšŸœ?˜NKšœ(œS˜~K˜KšŸœE˜[Kšœ/œh˜šK˜KšŸœD˜YKšœ.œe˜–K˜KšŸœB˜UKšœ,œ†˜΅——šœ™KšŸœ@˜PKšœ)œœŽ˜ΠK˜šŸœ˜ šœœ˜1K˜K˜K˜K˜Kšœœ˜K˜K˜——šŸœ˜&šŸœœœ˜(Kšœœ˜0—šœœ˜'K˜K˜K˜K˜Kšœ ˜—Kšœ˜K˜—KšŸœD˜XKšœ-œœž˜δK˜šŸœ˜$šœœ˜5K˜K˜K˜K˜Kšœœ˜K˜K˜——šŸœ˜*šŸœœœ˜(Kšœœ˜0—šœœ˜+K˜K˜K˜K˜Kšœ ˜—Kšœ˜——šœ ™ KšŸ œ<˜IKšœ&œœ‚˜ΑK˜šŸœ˜šœœ˜.K˜K˜%K˜K˜ Kšœœ˜—K˜—Kšœœ'˜=˜K˜—šŸœ˜#KšŸœœœ2œ ˜Ušœœ˜$K˜K˜%K˜K˜ Kšœ ˜—Kšœ˜——šœ ™ KšŸ œ:˜EKšœ$œœz˜·K˜šŸ œ˜šœœ˜,K˜K˜%K˜K˜ Kšœœ˜—˜K˜——šŸœ˜!KšŸœœœ2œ ˜Ušœœ˜"K˜K˜%K˜K˜ Kšœ ˜—Kšœ˜——™$KšŸœ7˜?Kšœ!œ>˜bK˜KšŸœ7˜?Kšœ!œ>˜bK˜KšŸ œ<˜HKšœ%œJ˜r—šœ™KšŸ œ:˜DKšœ#œD˜j—šœ ™ KšŸ œ;˜GKšœ%œJ˜r—™šœ ™ KšŸ œ:˜EKšœ$œG˜nK˜KšŸ œ;˜GKšœ%œJ˜rK˜KšŸ œ;˜GKšœ%œJ˜rK˜KšŸ œ<˜IKšœ&œM˜vK˜KšŸ œ:˜EKšœ$œG˜nK˜KšŸœ=˜KKšœ'œP˜zK˜KšŸœ=˜KKšœ'œP˜zK˜KšŸœ=˜KKšœ'œP˜zK˜KšŸœ>˜MKšœ(œS˜~K˜KšŸ œ;˜GKšœ%œJ˜rK˜KšŸœ7˜?Kšœ!œ?˜c——šœ ™ KšŸ œ8˜AKšœ"œA˜fK˜KšŸœ?˜OKšœ)œV˜‚K˜KšŸœ?˜OKšœ)œV˜‚K˜KšŸ œ:˜EKšœ$œh˜—šœ™KšŸœA˜SKšœ+œ\˜ŠK˜KšŸœB˜UKšœ,œy˜¨K˜KšŸœB˜UKšœ,œw˜¦K˜KšŸœB˜UKšœ,œ{˜ͺK˜KšŸœB˜UKšœ,œy˜¨—™ šŸœ˜%Kšœ"˜"Kšœœ˜(Kšœ˜K˜—šŸ œ˜K˜"Kšœ'˜'Kšœœ˜K˜Ešœb™bKšœ¦™¦—K˜Kšœ$˜$šœœœ+˜GKšœœ˜*—šœ )˜0Kšœœœ˜$Kš œœœ œ œ˜,Kšœ˜šœœœ˜0š œœœ"œ ˜DKšœ œ˜Kšœ˜Kšœ˜—Kšœ œ œ˜ K˜Kšœ˜Kšœ˜—Kšœ˜—K˜—šŸœ˜(K˜"Kšœœ˜ Kšœœ˜ K˜!šœœœ +˜Kšœ œœœ ˜$šœœ˜K˜—šŸ œœ&œ ˜JJšœ œ˜,Jšœ ˜J˜J™—šŸœœœ˜.šœ$œœ˜8Kšœ<˜˜MKšœ(œS˜~K˜KšŸœE˜[Kšœ/œh˜šK˜KšŸœD˜YKšœ.œe˜–K˜KšŸœB˜UKšœ,œ†˜΅—™KšŸ œ:˜EKšœ$œG˜nK˜KšŸœA˜SKšœ+œ\˜ŠK˜KšŸœ@˜QKšœ*œY˜†K˜KšŸœ>˜MKšœ(œr˜—™KšŸœC˜WKšœ-œb˜’K˜KšŸœA˜SKšœ+œ\˜ŠK˜KšŸœ=˜KKšœ'œP˜zK˜KšŸœD˜YKšœ.œe˜–K˜KšŸœD˜YKšœ.œe˜–K˜KšŸœ?˜OKšœ)œ˜­—™KšŸœC˜WKšœ-œb˜’K˜KšŸœ@˜QKšœ*œY˜†K˜KšŸœ=˜KKšœ'œP˜zK˜KšŸœD˜YKšœ.œe˜–K˜KšŸœD˜YKšœ.œe˜–K˜KšŸœ?˜OKšœ)œ˜­—™ KšŸœD˜YKšœ.œe˜–K˜KšŸœB˜UKšœ,œ_˜ŽK˜KšŸœ>˜MKšœ(œS˜~K˜KšŸœE˜[Kšœ/œh˜šK˜KšŸœE˜[Kšœ/œh˜šK˜KšŸœ@˜QKšœ*œ†˜³—™KšŸœA˜SKšœ+œ\˜ŠK˜KšŸœB˜UKšœ,œ_˜ŽK˜KšŸœ>˜MKšœ(œS˜~K˜KšŸœE˜[Kšœ/œh˜šK˜KšŸœE˜[Kšœ/œh˜šK˜KšŸœ@˜QKšœ*œ†˜³—šœ ™ KšŸ œ8˜AKšœ"œA˜fK˜KšŸœ?˜OKšœ)œV˜‚K˜KšŸœ?˜OKšœ)œV˜‚K˜KšŸ œ:˜EKšœ$œh˜—šœ ™ KšŸ œ;˜GKšœ%œJ˜rK˜KšŸœB˜UKšœ,œ_˜ŽK˜KšŸœB˜UKšœ,œ_˜ŽK˜KšŸœ=˜KKšœ'œw˜‘——™š Ÿœœœ œœœ˜PKšœ@™@Kšœœ˜ K˜(Kšœœœœ˜Kšœ˜K˜Kšœœ˜Kšœ˜K˜—šŸ œœœ˜Kšœ.˜.K™Kšœ3™3Kšœ3˜3Kšœ3˜3Kšœ5˜5K˜KšœZ™ZKšœ3˜3Kšœ)˜)K˜Kšœ9™9K™Ušœœ$˜.Kšœœ˜1K˜—Kšœ$™$K˜K˜Kšœ*™*K˜-K˜%K™Kšœ1™1Kšœ˜K˜K˜K™TK˜9K˜;K˜=K˜5K˜;K˜KšœC™CK˜3K˜K™=K˜K˜K˜K˜KšœD™DKšœJ™JK™KšœA™AKšœ™Kšœ"˜"Kšœ&˜&Kšœ%˜%Kšœ&˜&K™Kšœ™Kšœ&˜&Kšœ#˜#Kšœ%˜%Kšœ>˜>Kšœ8˜8Kšœ:˜:Kšœ8˜8Kšœ:˜:K™Kšœ™KšœA˜AKšœA˜AKšœ(˜(Kšœ#˜#K™Kšœ™Kšœ"˜"Kšœ&˜&KšœA˜AKšœ#˜#K˜Kšœ™Kšœ(˜(Kšœ$˜$Kšœ(˜(Kšœ)˜)Kšœ'˜'K™Kšœ™Kšœ%˜%Kšœ'˜'Kšœ%˜%KšœB˜BK™Kšœ™Kšœ$˜$Kšœ'˜'K™Kšœ™Kšœ$˜$Kšœ*˜*Kšœ*˜*Kšœ$˜$Kšœ&˜&Kšœ#˜#Kšœ$˜$Kšœ&˜&Kšœ(˜(K™KšœC™Cšœ˜Kšœœœ˜Kšœœœœœœ œ˜FKš œœœœœ œ˜AKšœ˜—K˜Kšœ™K˜-K˜;Kšœ˜K˜—K˜—K˜Kšœ˜—…—fζd