-- BcplFontFile.Mesa: Last modified by Geschke on November 6, 1979 10:31 AM -- Last changed by Doug Wyatt, August 27, 1980 11:52 AM -- Mesa 6 version: assumes REALs are Ieee format DIRECTORY BcplFontFileDefs, RealConvert USING [BcplToIeee], AltoDefs, InlineDefs, Mopcodes, StreamDefs, StringDefs, SystemDefs; BcplFontFile: PROGRAM IMPORTS BcplFontFileDefs, RealConvert, InlineDefs, StringDefs, StreamDefs, SystemDefs EXPORTS BcplFontFileDefs SHARES BcplFontFileDefs = BEGIN OPEN BcplFontFileDefs; BcplToMesaReal: PROCEDURE[b: BcplREAL] RETURNS[REAL] = INLINE BEGIN RETURN[RealConvert.BcplToIeee[LOOPHOLE[b]]] END; inStream: StreamDefs.StreamHandle _ NIL; inSDname: POINTER TO name RawIndex; inSDsplines: POINTER TO splines RawIndex; inSDfontname: STRING _ [40]; inBaseIndex: StreamDefs.StreamIndex; mesaSplineData: mesaSplineDataDesc; mesaSplineDir: mesaSplineDirDesc; OpenSDFontFile: PUBLIC PROCEDURE [file: STRING] = BEGIN c: CHARACTER; inSDend: POINTER TO end RawIndex; inSplineData: SplineDataDesc; inSplineDir: SplineDirDesc; nChars: CARDINAL; IF inStream # NIL THEN ERROR; inStream _ StreamDefs.NewWordStream[file, StreamDefs.Read]; inSDname _ GetRawIndex[SystemDefs.AllocateHeapNode]; IF inSDname.hdr.type # name THEN ERROR; inSDfontname.length _ 0; StringDefs.BcplToMesaString[@inSDname.fontname, inSDfontname]; inSDsplines _ GetRawIndex[SystemDefs.AllocateHeapNode]; IF inSDsplines.hdr.type # splines OR inSDsplines.rotation # 0 THEN ERROR; inSDend _ GetRawIndex[SystemDefs.AllocateHeapNode]; IF inSDend.hdr.type # end THEN ERROR; SystemDefs.FreeHeapNode[inSDend]; nChars _ inSDsplines.ec-inSDsplines.bc+1; inSplineData _ DESCRIPTOR[ SystemDefs.AllocatePages[ SystemDefs.PagesForWords[nChars*SIZE[BcplSplineData]]], nChars]; StreamDefs.SetIndex[ inStream, LongPointerToStreamIndex[BcplToMesaLongPointer[inSDsplines.startaddress]]]; [] _ StreamDefs.ReadBlock[inStream, BASE[inSplineData], nChars*SIZE[BcplSplineData]]; mesaSplineData _ LOOPHOLE[inSplineData]; inBaseIndex_StreamDefs.GetIndex[inStream]; inSplineDir _ DESCRIPTOR[ SystemDefs.AllocatePages[ SystemDefs.PagesForWords[nChars*SIZE[bcplLONGPOINTER]]], nChars]; [] _ StreamDefs.ReadBlock[inStream, BASE[inSplineDir], nChars*SIZE[bcplLONGPOINTER]]; mesaSplineDir _ LOOPHOLE[inSplineDir]; -- convert BCPL dir and spline data to Mesa FOR c IN [inSDsplines.bc..inSDsplines.ec] DO IF inSplineDir[c-inSDsplines.bc] = LOOPHOLE[LOOPHOLE[LONG[-1], LONG INTEGER], bcplLONGPOINTER] THEN BEGIN mesaSplineDir[c-inSDsplines.bc] _ NIL; LOOP END; mesaSplineDir[c-inSDsplines.bc] _ BcplToMesaLongPointer[inSplineDir[c-inSDsplines.bc]]; BEGIN bcplData: POINTER TO BcplSplineData _ @inSplineData[c-inSDsplines.bc]; mesaData: POINTER TO SplineData _ @mesaSplineData[c-inSDsplines.bc]; mesaData.xwidth _ BcplToMesaReal[bcplData.xwidth]; mesaData.ywidth _ BcplToMesaReal[bcplData.ywidth]; mesaData.bbox _ BcplToMesaReal[bcplData.bbox]; mesaData.bboy _ BcplToMesaReal[bcplData.bboy]; mesaData.rightx _ BcplToMesaReal[bcplData.rightx]; mesaData.topy _ BcplToMesaReal[bcplData.topy]; END; ENDLOOP; -- at this point we are prepared to read splines from the SD file RETURN END; CloseSDFontFile: PUBLIC PROCEDURE = BEGIN inStream.destroy[inStream]; inStream _ NIL; SystemDefs.FreeHeapNode[inSDname]; SystemDefs.FreeHeapNode[inSDsplines]; SystemDefs.FreePages[BASE[mesaSplineData]]; SystemDefs.FreePages[BASE[mesaSplineDir]]; RETURN END; GetRawIndex: PROCEDURE [userAlloc: PROCEDURE [CARDINAL] RETURNS [POINTER]] RETURNS [POINTER TO UNSPECIFIED] = BEGIN p:POINTER TO RawIndex; p_ userAlloc[SIZE[RawIndex]]; []_StreamDefs.ReadBlock[inStream,p,SIZE[IndexHeader]]; []_StreamDefs.ReadBlock[inStream,p+SIZE[IndexHeader],p.hdr.length-1]; RETURN[p]; END; GetSplineCommands: PUBLIC PROCEDURE[char: CHARACTER, userAlloc: AllocProc] RETURNS [sd: SplineDataPtr, scp: SplineCommandPtr] = BEGIN index: StreamDefs.StreamIndex; last: SplineCommandPtr; IF char-inSDsplines.bc ~ IN[0..LENGTH[mesaSplineDir]) OR mesaSplineDir[char-inSDsplines.bc] = NIL THEN RETURN[NIL, NIL]; sd _ @mesaSplineData[char-inSDsplines.bc]; index _ LongPointerToStreamIndex[ StreamIndexToLongCardinal[inBaseIndex] +mesaSplineDir[char-inSDsplines.bc]]; StreamDefs.SetIndex[inStream, index]; [scp,index] _ GetNextCommand[index, userAlloc]; last _ scp; DO [last.next,index] _ GetNextCommand[index, userAlloc]; IF last.next.type = EndDefinition THEN EXIT; last _ last.next; ENDLOOP; RETURN END; GetNextCommand: PROCEDURE[index: StreamDefs.StreamIndex, userAlloc: AllocProc] RETURNS [SplineCommandPtr, StreamDefs.StreamIndex] = BEGIN bsc: BcplSplineCommand; scc: SplineCommandCode; scp: SplineCommandPtr; StreamDefs.SetIndex[inStream, index]; scc _ BcplToMesaCommandCode[bsc.type _ inStream.get[inStream]]; []_StreamDefs.ReadBlock[ inStream, @bsc+1, (SELECT scc FROM MoveTo, DrawTo => SIZE[MoveTo BcplSplineCommand], DrawCurve => SIZE[DrawCurve BcplSplineCommand], ENDCASE => SIZE[EndDefinition BcplSplineCommand])-1]; scp _ userAlloc[SELECT scc FROM MoveTo, DrawTo => SIZE[MoveTo SplineCommand], DrawCurve => SIZE[DrawCurve SplineCommand], ENDCASE => SIZE[EndDefinition SplineCommand]]; SELECT scc FROM MoveTo => scp^ _ [, MoveTo[,]]; DrawTo => scp^ _ [, DrawTo[,]]; DrawCurve => scp^ _ [, DrawCurve[,,,,,]]; NewObject => scp^ _ [, NewObject[]]; EndDefinition => scp^ _ [, EndDefinition[]]; ENDCASE; scp.next _ NIL; WITH scp SELECT FROM MoveTo, DrawTo => BEGIN x _ BcplToMesaReal[bsc.x]; y _ BcplToMesaReal[bsc.y]; END; DrawCurve => BEGIN x0 _ BcplToMesaReal[bsc.x0]; y0 _ BcplToMesaReal[bsc.y0]; x1 _ BcplToMesaReal[bsc.x1]; y1 _ BcplToMesaReal[bsc.y1]; x2 _ BcplToMesaReal[bsc.x2]; y2 _ BcplToMesaReal[bsc.y2]; END; ENDCASE; RETURN[scp, StreamDefs.GetIndex[inStream]] END; BcplToMesaCommandCode: PROCEDURE[bcc: BcplCommandCode] RETURNS [SplineCommandCode] = BEGIN SELECT bcc FROM 1 => RETURN[MoveTo]; 2 => RETURN[DrawTo]; 3 => RETURN[DrawCurve]; -1 => RETURN[NewObject]; -2 => RETURN[EndDefinition]; ENDCASE => ERROR END; LongPointerToStreamIndex: PROCEDURE [l:LONG POINTER] RETURNS [s:StreamDefs.StreamIndex]= BEGIN s.page _ InlineDefs.LowHalf[(LOOPHOLE[l,LONG CARDINAL]*2)/AltoDefs.CharsPerPage]; s.byte _ InlineDefs.LowHalf[(LOOPHOLE[l,LONG CARDINAL]*2) MOD AltoDefs.CharsPerPage];END; StreamIndexToLongCardinal: PROCEDURE [s:StreamDefs.StreamIndex] RETURNS [l:LONG CARDINAL]= BEGIN l _ InlineDefs.LowHalf[LOOPHOLE[s,LONG CARDINAL]] *AltoDefs.CharsPerPage; l _ (InlineDefs.HighHalf[LOOPHOLE[s,LONG CARDINAL]] +l)/2; END; END. (1792)\3b17B20b7B3b28B245b12B556b14B2614b15B262b11B310b17B781b14B1502b22B258b25B243b26B