DIRECTORY Rope, TSTypes, TSGlue, TSFont, TSGraphic, TSObject; TSObjectImpl: CEDAR MONITOR IMPORTS TSObject, TSFont, TSTypes EXPORTS TSObject = BEGIN OPEN TSObject; InitiallyZeroInt: TYPE = INT _ 0; forceStats: RECORD [ tagRecEnd: INT _ 0, ignore: INT _ 0, produce: INT _ 0, exception: INT _ 0, font: INT _ 0, rope: INT _ 0, offset: INT _ 0, parameter: ARRAY ParameterType OF InitiallyZeroInt, listParameter: ARRAY ListParameterType OF InitiallyZeroInt, end: INT _ 0 ]; ClearForceStats: PROC = {forceStats _ []}; ForceCurrentItem: PROCEDURE [self: ListReader] = { IF self.tagOffset >= tagRecSize THEN { self.itemList.tagList _ self.itemList.tagList.rest; self.tagOffset _ 0; }; SELECT self.itemList.tagList.first[self.tagOffset] FROM ignore => { self.Next[]; }; produce => { self.itemList.listWriter.producer[self.itemList.listWriter]; ForceCurrentItem[self]; }; exception => { t: REF ANY; self.itemList.exceptionList _ self.itemList.exceptionList.rest; t _ self.itemList.exceptionList.first; SELECT TRUE FROM ISTYPE[t, TSObject.Font] => { self.currentFont _ NARROW[t]; self.Next[]; }; ISTYPE[t, ROPE] => { self.baseRope _ NARROW[t]; self.ropeOffset _ 0; self.Next[]; }; ISTYPE[t, TSObject.RopeOffset] => { self.ropeOffset _ NARROW[t,RopeOffset]^.ropeOffset; self.Next[]; }; ISTYPE[t, TSObject.Parameter] => { p: TSObject.Parameter _ NARROW[t]; self.parameter[p.parameterType] _ p.parameter; }; ISTYPE[t, TSObject.ListParameter] => { p: TSObject.ListParameter _ NARROW[t]; self.listParameter[p.listParameterType] _ p.listParameter; }; ENDCASE => {}; }; end => { IF self.itemList.successor = NIL THEN RETURN ELSE { self.itemList _ self.itemList.successor^; self.tagOffset _ 0; ForceCurrentItem[self]; }; }; ENDCASE => {}; }; Next: PUBLIC PROCEDURE [self: ListReader] = { SELECT self.itemList.tagList.first[self.tagOffset] FROM char, space, ignore => self.ropeOffset _ self.ropeOffset + 1; exception, hyphen => {}; ENDCASE => ERROR; self.tagOffset _ self.tagOffset + 1; IF self.tagOffset >= tagRecSize THEN ForceCurrentItem[self] ELSE SELECT self.itemList.tagList.first[self.tagOffset] FROM ignore, produce, exception, end => ForceCurrentItem[self]; ENDCASE => {}; }; CreateItemList: PUBLIC PROCEDURE [ producer: ProducerProc, writerData: REF ANY _ NIL ] RETURNS [new: ItemList] = { new _ NEW[ItemListRec]; new.listWriter _ NEW[ListWriterRec]; new.listWriter.producer _ producer; new.listWriter.parameter _ [TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn]; new.listWriter.writerData _ writerData; new.tagList _ new.listWriter.tagList _ LIST[produceArray]; new.exceptionList _ new.listWriter.exceptionList _ LIST[NIL]; stats.newListsCreated _ stats.newListsCreated + 1; }; SingletonList: PUBLIC PROCEDURE [item: REF ANY] RETURNS [new: ItemList] = { new _ CreateItemList[producer: NIL]; new.listWriter.ProduceItem[item]; new.listWriter.ProduceEnd[]; new.listWriter _ NIL; }; ItemListFromExplicitList: PUBLIC PROCEDURE [explicitList: LIST OF REF ANY _ NIL] RETURNS [new: ItemList] = { new _ CreateItemList[producer: NIL]; WHILE explicitList # NIL DO new.listWriter.ProduceItem[explicitList.first]; explicitList _ explicitList.rest; ENDLOOP; new.listWriter.ProduceEnd[]; new.listWriter _ NIL; }; Copy: PUBLIC PROCEDURE [self: ItemList] RETURNS [new: ItemList] = { new _ NEW[ItemListRec _ self^]; stats.newListsCreated _ stats.newListsCreated + 1; IF self.successor # NIL THEN new.successor _ self.successor.Copy[]; }; Concat: PUBLIC PROCEDURE [a, b: TSObject.ItemList] = { WHILE a.successor # NIL DO a _ a.successor ENDLOOP; a.successor _ b; }; listReaderCacheSize: NAT = 30; listReaderCache: ARRAY [0..listReaderCacheSize) OF ListReader; listReaderCacheFront, listReaderCacheRear: [0..listReaderCacheSize] _ 0; CreateReader: PUBLIC PROCEDURE [list: ItemList] RETURNS [reader: ListReader] = { reader _ GetReader[]; reader.itemList _ list^; FOR t: TSObject.ParameterType IN TSObject.ParameterType DO reader.parameter[t] _ TSTypes.zeroDimn ENDLOOP; ForceCurrentItem[reader]; }; CopyReader: PUBLIC PROCEDURE [reader: ListReader] RETURNS [copy: ListReader] = { copy _ GetReader[]; copy^ _ reader^; }; GetReader: ENTRY PROCEDURE RETURNS [reader: ListReader] = INLINE { ENABLE UNWIND => NULL; IF listReaderCacheFront = listReaderCacheRear THEN { reader _ NEW[ListReaderRec]; stats.readersCreated _ stats.readersCreated + 1; } ELSE { listReaderCacheFront _ listReaderCacheFront + 1; IF listReaderCacheFront = listReaderCacheSize THEN listReaderCacheFront _ 0; reader _ listReaderCache[listReaderCacheFront]; listReaderCache[listReaderCacheFront] _ NIL; }; stats.listReadersStarted _ stats.listReadersStarted + 1; }; DestroyReader: PUBLIC ENTRY PROCEDURE [reader: ListReader] = { ENABLE UNWIND => NULL; t: [0..listReaderCacheSize] _ listReaderCacheRear + 1; IF t = listReaderCacheSize THEN t _ 0; IF reader.itemList.tagList = NIL THEN ERROR; -- This has already been destroyed! reader^ _ [itemList: [], parameter: [TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn, TSTypes.zeroDimn]]; IF t # listReaderCacheFront THEN { listReaderCacheRear _ t; listReaderCache[t] _ reader; }; }; Expand: PUBLIC PROCEDURE [self: ListReader] RETURNS [explicitList: LIST OF REF ANY _ NIL] = { p: REF ANY; IF self.End[] THEN RETURN; SELECT self.CurrentTag FROM char => { p _ NEW[BoxRec _ [ self.currentFont.CharDimensions[self.CurrentChar[]], char [self.currentFont, self.CurrentChar[]] ]]; }; space => { p _ NEW[TSGlue.Glue _ self.currentFont.SpaceGlue[]]; }; exception => { p _ self.CurrentItem[]; IF ISTYPE[p, Kerf] THEN { t: Kerf _ NARROW[p]; IF t.join # NIL THEN p _ t.join.first; -- not quite right, but should be good enough }; }; ENDCASE; self.Next[]; explicitList _ IF p=NIL THEN self.Expand[] ELSE CONS[p, self.Expand[]]; }; Extend: PUBLIC PROCEDURE [self: ListWriter] = { self.tagList.rest _ LIST[produceArray]; self.tagList _ self.tagList.rest; self.tagOffset _ 0; stats.extentsCreated _ stats.extentsCreated + 1; }; produceArray: TagRec = [ produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce, produce ]; ProduceParameter: PUBLIC PROCEDURE [ self: ListWriter, parameterType: ParameterType, parameterValue: Dimn ] = { IF self.parameter[parameterType] # parameterValue THEN { p: Parameter _ NEW[ParameterRec _ [ parameterType: parameterType, parameter: parameterValue ]]; self.ProduceItem[p]; self.parameter[parameterType] _ parameterValue; }; }; MakeGlue: PUBLIC PROCEDURE [space, plus, minus: Dimn _ TSTypes.zeroDimn] RETURNS [p: REF ANY] = { IF plus = TSTypes.zeroDimn AND minus = TSTypes.zeroDimn THEN { kern: TSObject.Kern _ NEW[Dimn _ space]; p _ kern; } ELSE { glue: TSObject.Glue _ NEW[TSGlue.Glue _ [space, plus, minus]]; p _ glue; } }; MakeKerf: PUBLIC PROCEDURE [prebreak, join, postbreak: LIST OF REF ANY _ NIL, penalty: TSTypes.Penalty _ 0] RETURNS [p: TSObject.Kerf] = { p _ NEW[TSObject.KerfRec]; p.prebreak _ prebreak; p.join _ join; p.postbreak _ postbreak; p.penalty _ penalty; }; stats: RECORD [ newListsCreated: INT _ 0, readersCreated: INT _ 0, listReadersStarted: INT _ 0, extentsCreated: INT _ 0 ]; fillGlue: PUBLIC REF ANY = MakeGlue[plus: TSGlue.fill]; filGlue: PUBLIC REF ANY = MakeGlue[plus: TSGlue.fil]; bigGlue: PUBLIC REF ANY = MakeGlue[space: TSTypes.IntDimn[1000, TSTypes.mm]]; END. Michael Plass, September 1, 1982 9:03 pm: Added Michael Plass, September 15, 1982 10:59 am: ENABLE UNWIND. Michael Plass, November 2, 1982 10:26 am. CEDARized. Michael Plass, November 12, 1982 9:33 am: Added ΎTSObjectImpl.mesa Michael Plass, November 12, 1982 9:33 am Last Edited by: Beach, May 24, 1983 9:10 am FS forceStats.tagRecEnd _ forceStats.tagRecEnd + 1; FS forceStats.ignore _ forceStats.ignore + 1; FS forceStats.produce _ forceStats.produce + 1; FS forceStats.exception _ forceStats.exception + 1; FS forceStats.font _ forceStats.font + 1; FS forceStats.rope _ forceStats.rope + 1; FS forceStats.offset _ forceStats.offset + 1; FS forceStats.parameter[p.parameterType] _ forceStats.parameter[p.parameterType] + 1; FS forceStats.listParameter[p.listParameterType] _ forceStats.listParameter[p.listParameterType] + 1; FS forceStats.end _ forceStats.end + 1; Otherwise let the collector get it. Κ 6– "cedar" style˜Jšœ™Jšœ)™)JšΟk+™+š ˜ J˜J˜J˜J˜J˜ J˜ J˜—Jšœ œœœ ˜PJšœœ ˜J˜Jšœœœ˜!J˜šœ œ˜Jšœ œ˜Jšœœ˜Jšœ œ˜Jšœ œ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœ œœ˜3Jšœœœ˜;Jšœœ˜ J˜J˜—JšΟnœœ˜*J˜šžœ œ˜2šœœ˜&J˜3J˜JšΟc3™3J˜—šœ-˜7˜ J˜ JšŸ-™-J˜—˜ J˜J˜HJ˜šž œœ œœ˜PJ˜J˜šœœ˜:J˜&Jšœ˜—J˜J˜J˜—šž œœ œœ˜PJ˜J˜J˜J˜—š ž œœ œœœ˜BJšœœœ˜šœ,œ˜4Jšœ œ˜J˜0J˜—šœ˜J˜0Jšœ,œ˜LJ˜/Jšœ(œ˜,J˜—J˜8J˜J˜—šž œœœ œ˜>Jšœœœ˜J˜6Jšœœ˜&Jš œœœœŸ#˜PJ˜Ϊšœœ˜"J˜J˜J˜—JšŸ#™#J˜J˜—šžœœ œ˜+Jš œœœœœœ˜1Jšœœœ˜ Jšœ œœ˜šœ˜˜ šœœ ˜J˜4J˜+J˜—J˜—˜ Jšœœ-˜4J˜—˜J˜šœœ œ˜Jšœ œ˜Jšœ œœŸ-˜TJ˜—J˜—Jšœ˜—J˜ šœœœœ˜*Jšœœ˜—J˜J˜—šžœœ œ˜/Jšœœ˜'J˜!J˜J˜0J˜J˜—˜J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜,J˜+J˜J˜—šžœœ œ˜$J˜J˜J˜J˜šœ0œ˜8šœœ˜#J˜J˜J˜—J˜J˜/J˜—J˜J˜—šžœœ œ.˜HJšœœœ˜šœœœ˜>Jšœœ˜(J˜ J˜—šœ˜Jšœœ%˜>J˜ J˜—J˜J˜—šžœœ œœœœœœ˜kJšœ˜Jšœœ˜J˜J˜J˜J˜J˜J˜—šœœ˜Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜J˜J˜—Jšœ œœœ˜7J˜Jšœ œœœ˜5J˜Jšœ œœœ6˜MJ˜Jšœ˜J˜J˜1Jšœ-œœ˜;J˜4J˜1—…—!F-: