DIRECTORY CGAIS, FS, Real, Rope, SirPress, TSArtwork, TSOutputPress, TextNode, TSGraphic, IO, TSOutput, TSTypes USING [Dimn, zeroDimn, RealDimn, DimnRatio, bp, Dimensions]; TSIncludeAISImpl: CEDAR PROGRAM IMPORTS FS, Real, Rope, SirPress, TSArtwork, TextNode, IO, TSTypes = BEGIN OPEN TSTypes; bytesPerPage: NAT ~ 512; -- as per press file format. micasPerPoint: REAL = 2540.0/72.0; pointsPerMica: REAL = 72.0/2540.0; ObjectFromBranchProc: TYPE = TSArtwork.ObjectFromBranchProc; ROPE: TYPE = Rope.ROPE; IncludeAISRec: TYPE = RECORD [aisFileName: ROPE, height, width: REAL _ -1, indent: REAL _ 0, screen: INT _ 85, aisStream: IO.STREAM, wordOffset: INT, rasterPart: CGAIS.RasterPart, uca: CGAIS.UCA]; Break: PROC [char: CHAR] RETURNS [IO.CharClass] = { IF char = ': THEN RETURN [break]; IF char = ' OR char = ' OR char = ', OR char = '; OR char = '\n THEN RETURN [sepr]; RETURN [other]; }; GetName: PROC [stream: IO.STREAM] RETURNS [name: ROPE] ~ { name _ NIL; name _ IO.GetTokenRope[stream, Break ! IO.EndOfStream => CONTINUE].token; }; GetBP: PROC [stream: IO.STREAM] RETURNS [REAL] = { r: REAL _ IO.GetReal[stream]; unit: ROPE _ GetName[stream]; multipler: REAL _ SELECT TRUE FROM unit.Equal["in"] => 72.0, unit.Equal["pt"] => 72.0/72.27, unit.Equal["cm"] => 72.0/2.54, unit.Equal["mm"] => 72.0/25.4, unit.Equal["bp"] => 1.0, ENDCASE => 0.0; IF multipler = 0.0 THEN ERROR; RETURN [r*multipler]; }; ReadBlock: UNSAFE PROC [stream: IO.STREAM, destPointer: LONG POINTER, wordCount: INT] = UNCHECKED { bytes: INT _ IO.UnsafeGetBlock[stream, [destPointer, 0, wordCount*2]]; IF bytes # wordCount*2 THEN ERROR; }; IncludeAISFromBranch: ObjectFromBranchProc = { data: REF IncludeAISRec _ NEW[IncludeAISRec]; textNode: TextNode.RefTextNode _ TextNode.NarrowToTextNode[node]; nodeContents: ROPE _ textNode.rope; stream: IO.STREAM _ IO.RIS[nodeContents]; header: CGAIS.Header; rasterPart: CGAIS.RasterPart; uca: CGAIS.UCA; dotSize: REAL _ 0; imageWidth, imageHeight: CARDINAL _ 0; byteIndex: INT _ 0; data.aisFileName _ GetName[stream]; UNTIL IO.EndOf[stream] DO keyword: ROPE _ GetName[stream]; colon: ROPE _ GetName[stream]; IF colon.Equal[":"] THEN NULL ELSE ERROR; SELECT TRUE FROM keyword.Equal["Height", FALSE] => data.height _ GetBP[stream]; keyword.Equal["Width", FALSE] => data.width _ GetBP[stream]; keyword.Equal["Indent", FALSE] => data.indent _ GetBP[stream]; keyword.Equal["DotSize", FALSE] => dotSize _ GetBP[stream]; keyword.Equal["Screen", FALSE] => data.screen _ IO.GetInt[stream]; ENDCASE => ERROR; ENDLOOP; data.aisStream _ FS.StreamOpen[data.aisFileName]; TRUSTED {ReadBlock[data.aisStream, @header, SIZE[CGAIS.Header]]}; IF header.password # CGAIS.password THEN ERROR; -- not an AIS file. data.wordOffset _ header.attributeLength; byteIndex _ IO.GetIndex[data.aisStream]; DO TRUSTED {ReadBlock[data.aisStream, @rasterPart, SIZE[CGAIS.RasterPart]]}; IF rasterPart.aph.length = 0 THEN ERROR; byteIndex _ byteIndex + 2*rasterPart.aph.length; IF byteIndex/2 > header.attributeLength THEN ERROR; IF rasterPart.aph.type = raster THEN EXIT; IO.SetIndex[data.aisStream, byteIndex]; ENDLOOP; IF rasterPart.codingType # CGAIS.UCACodingType THEN ERROR; -- not the kind we expected TRUSTED {ReadBlock[data.aisStream, @uca, SIZE[CGAIS.UCA]]}; data.rasterPart _ rasterPart; data.uca _ uca; IF rasterPart.scanDirection MOD 4 < 2 THEN { imageWidth _ rasterPart.scanCount; imageHeight _ rasterPart.scanLength; } ELSE { imageWidth _ rasterPart.scanLength; imageHeight _ rasterPart.scanCount; }; IF data.height < 0 AND data.width < 0 THEN { IF dotSize <= 0 THEN ERROR; --must specify dotSize if height and width are omitted. data.height _ dotSize*imageHeight; data.width _ dotSize*imageWidth; }; IF data.height < 0 THEN data.height _ (data.width * imageHeight)/imageWidth; IF data.width < 0 THEN data.width _ (data.height * imageWidth)/imageHeight; object _ NEW[TSGraphic.ObjectRec]; object.paintProc _ IncludeAISPaint; object.layoutProc _ IncludeAISLayout; object.data _ data; }; IncludeAISLayout: TSGraphic.LayoutProc = { data: REF IncludeAISRec _ NARROW[self.data]; extent _ [zeroDimn, RealDimn[data.width+data.indent, bp], zeroDimn, RealDimn[data.height, bp]]; }; IncludeAISPaint: TSGraphic.PaintProc = TRUSTED { data: REF IncludeAISRec ~ NARROW[self.data]; handle: TSOutput.Handle ~ NARROW[context]; x: INT ~ Real.RoundLI[(DimnRatio[originX, bp]+data.indent)*micasPerPoint]; y: INT ~ Real.RoundLI[(DimnRatio[originY, bp])*micasPerPoint]; pressState: TSOutputPress.PressState ~ NARROW[handle.outputState]; pressHandle: SirPress.PressHandle ~ pressState.pressHandle; windowWidth: INT ~ Real.RoundLI[data.width*micasPerPoint]; windowHeight: INT ~ Real.RoundLI[data.height*micasPerPoint]; bytesPerLine: INT ~ data.uca.wordsPerScanLine*2; ScratchRec: TYPE ~ RECORD [SEQUENCE length: NAT OF WORD]; scratch: REF ScratchRec _ NEW[ScratchRec[data.uca.wordsPerScanLine]]; pressHandle.BeginScannedRectangle[ x: x, y: y-windowHeight, dotsPerLine: data.rasterPart.scanLength, numberOfLines: data.rasterPart.scanCount, width: windowWidth, height: windowHeight, nextLineDirection: LOOPHOLE[data.rasterPart.scanDirection MOD 4], nextDotDirection: LOOPHOLE[data.rasterPart.scanDirection / 4], coding: SELECT data.uca.bitsPerSample FROM 0 => bitMap, 1 => bitSampled, 2 => bitBitSampled, 4 => nybbleSampled, 8 => byteSampled, ENDCASE => ERROR, samplingProperties: [screenFrequency: data.screen] ]; scratch[bytesPerLine/2-1] _ 0; -- make sure array is big enough IO.SetIndex[data.aisStream, data.wordOffset*2]; FOR i: INT IN [0..data.rasterPart.scanCount) DO TRUSTED {ReadBlock[data.aisStream, @scratch[0], scratch.length]}; TRUSTED {pressHandle.UnsafeShowLine[@scratch[0]]}; ENDLOOP; pressHandle.EndScannedRectangle; IO.Close[data.aisStream]; }; TSArtwork.Register["IncludeAIS", IncludeAISFromBranch]; END. €TSIncludeAISImpl.mesa Michael Plass, December 19, 1983 12:23 pm Last edited by Tim Diebert: May 22, 1984 12:02:17 pm PDT ส ~˜– "cedar" stylešœ™J– "cedar" style™)J– "cedar" style™8– "cedar" stylešฯk ˜ J– "cedar" stylešœ˜J– "cedar" style˜J– "cedar" stylešœ˜J– "cedar" stylešœ˜J– "cedar" stylešœ ˜ J– "cedar" stylešœ ˜ J– "cedar" stylešœ˜J– "cedar" stylešœ ˜ J– "cedar" stylešœ ˜ J– "cedar" stylešœ˜J– "cedar" style˜ J– "cedar" stylešœœ7˜DJ– "cedar" style˜——– "cedar" stylešœœ˜J– "cedar" stylešœ0œ ˜B– "cedar" stylešœœœ ˜J– "cedar" style˜—J– "cedar" stylešœœฯc˜5J– "cedar" stylešœœ˜"– "cedar" stylešœœ˜"J– "cedar" style˜—J– "cedar" stylešœœ"˜<– "cedar" stylešœœœ˜J– "cedar" style˜—– "cedar" stylešœœœœœœœœœœœœœ˜ฤJ– "cedar" style˜—– "cedar" styleš ฯnœœœœœ˜3Jšœ œœ ˜!Jšœ œ œ œ œ œœ˜UJšœ ˜Jšœ˜J– "cedar" style˜—š Ÿœœ œœœœ˜:Jšœœ˜ Jšœœœœ˜IJ˜J˜—– "cedar" styleš Ÿœœ œœœœ˜2Jšœœœ˜Jšœœ˜šœ œœœ˜"Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜Jšœ˜—Jšœœœ˜Jšœ˜Jšœ˜J– "cedar" style˜—– "cedar" stylešŸ œœœ œœœœ œ œ˜cJšœœœ7˜FJšœœœ˜"Jšœ˜J– "cedar" style˜—– "cedar" stylešŸœ˜.Jšœœœ˜-JšœA˜AJšœœ˜#Jš œœœœœ˜)Jšœœ˜Jšœ œ ˜Jšœœœ˜Jšœ œ˜Jšœœ˜&Jšœ œ˜Jšœ#˜#šœœ˜Jšœ œ˜ Jšœœ˜Jš œœœœœ˜)šœœ˜Jšœœ!˜>Jšœœ ˜Jšœœ˜;Jšœœ%˜BJšœœ˜—Jšœ˜—Jšœ1˜1Jšœ%œœ ˜AJš œœ œœž˜CJšœ)˜)Jšœ œ˜(š˜Jšœ)œœ˜IJšœœœ˜(Jšœ0˜0Jšœ&œœ˜3Jšœœœ˜*Jšœ%˜'Jšœ˜—Jš œœœœž˜WJšœ"œœœ˜;Jšœ˜Jšœ˜šœœœ˜,Jšœ"˜"Jšœ$˜$J˜—šœ˜Jšœ#˜#Jšœ#˜#J˜—šœœœ˜,Jš œœœžœžœžœž ˜SJšœ"˜"Jšœ ˜ J˜—Jšœœ5˜LJšœœ5˜KJšœ œ˜"Jšœ#˜#Jšœ%˜%Jšœ˜Jšœ˜J– "cedar" style˜—– "cedar" stylešŸœ˜*Jšœœœ ˜,Jšœ_˜_Jšœ˜J– "cedar" style˜—– "cedar" stylešŸœœ˜0Jšœœœ ˜,Jšœœ ˜*JšœœD˜JJšœœ8˜>Jšœ'œ˜BJšœ;˜;J– "cedar" stylešœ œ*˜:J– "cedar" stylešœœ+˜– "cedar" stylešœœ˜*J– "cedar" stylešœ ˜ J– "cedar" stylešœ˜J– "cedar" stylešœ˜J– "cedar" stylešœ˜J– "cedar" stylešœ˜J– "cedar" stylešœ˜—J– "cedar" stylešœ2˜2J˜—Jšœž ˜?Jšœ-˜/šœœœ ˜/Jšœ:˜AJšœ+˜2Jšœ˜—J– "cedar" stylešœ ˜ Jšœ˜Jšœ˜J– "cedar" style˜—– "cedar" stylešœ7˜7J– "cedar" style˜—J– "cedar" stylešœ˜—J˜—…—ฎ"ฌ