-- SplineFontWriterJaM.mesa <<-- Written by Michael Plass on November 8, 1982 10:58 am>> <<-- Last edit by Michael Plass on December 2, 1982 1:17 pm>> <<-- Last edit by Maureen Stone on May 16, 1984 10:58:49 am PDT>> DIRECTORY IO, FS USING [StreamOpen], FitJaM, Curve, JaM, Real, Rope, Cubic, Vector USING [Vec]; SplineFontWriterJaM: CEDAR PROGRAM IMPORTS JaM, IO, FitJaM, Real, Rope, Curve, FS, Cubic = BEGIN ROPE: TYPE = Rope.ROPE; fontFile: IO.STREAM _ NIL; face: ROPE _ "M R R"; family: ROPE _ "UNKNOWN"; originx, originy: REAL _ 0.0; fiducial: INT _ 15840; -- this is 2*2*2*2*2*3*3*5*11 - lots of small factors. quad: REAL _ 1.0; Open: PROCEDURE [f: JaM.State] = { fileName: ROPE _ JaM.PopRope[f]; IF fontFile # NIL THEN fontFile.Close[]; fontFile _ NIL; IF fileName.Length[] > 0 THEN fontFile _ FS.StreamOpen[fileName, $append]; }; Family: PROCEDURE [f: JaM.State] = { family _ JaM.PopRope[f]; }; Face: PROCEDURE [f: JaM.State] = { face _ JaM.PopRope[f]; }; Origin: PROCEDURE [f: JaM.State] = { originy _ JaM.PopReal[f]; originx _ JaM.PopReal[f]; }; Quad: PROCEDURE [f: JaM.State] = { quad _ JaM.PopReal[f]; }; Close: PROCEDURE [f: JaM.State] = { IF fontFile # NIL THEN fontFile.Close[]; fontFile _ NIL; }; Char: PROCEDURE [f: JaM.State] = { widthy: REAL _ JaM.PopReal[f]; widthx: REAL _ JaM.PopReal[f]; charCode: NAT _ JaM.PopInt[f]; BezierSequenceRec: TYPE = RECORD[SEQUENCE length: NAT OF Cubic.Bezier]; bezier: REF BezierSequenceRec _ NEW[BezierSequenceRec[Curve.CountContours[Curve.defaultHandle]]]; k: NAT _ 0; NewContour: PROC [] = { WriteCurrentOutline[]; }; NewCubic: PROC [c: Cubic.Bezier] = { bezier[k] _ [b0: Grid[c.b0], b1: Transform[c.b1], b2: Transform[c.b2], b3: Grid[c.b3]]; k _ k+1; }; Transform: PROC [vec: Vector.Vec] RETURNS [gridVec: Vector.Vec] = { gridVec.x _ (vec.x-originx)*fiducial/quad; gridVec.y _ (vec.y-originy)*fiducial/quad; }; Grid: PROC [vec: Vector.Vec] RETURNS [gridVec: Vector.Vec] = { gridVec.x _ Real.RoundLI[(vec.x-originx)*fiducial/quad]; gridVec.y _ Real.RoundLI[(vec.y-originy)*fiducial/quad]; }; WriteCurrentOutline: PROC = { IF k=0 THEN RETURN; fontFile.PutF["\n ((%d (", IO.int[k+1]]; FOR i: NAT IN [0..k) DO fontFile.PutF["(%d %d) ", IO.int[Real.RoundLI[bezier[i].b0.x]], IO.int[Real.RoundLI[bezier[i].b0.y]]]; ENDLOOP; fontFile.PutF["(%d %d)", IO.int[Real.RoundLI[bezier[0].b0.x]], IO.int[Real.RoundLI[bezier[0].b0.y]]]; fontFile.PutRope[")\n NIL ("]; FOR i: NAT IN [0..k) DO coeffs: Cubic.Coeffs _ Cubic.BezierToCoeffs[bezier[i]]; IF i>0 THEN fontFile.PutRope[" "]; fontFile.PutF["(%g %g", IO.real[coeffs.c1.x], IO.real[coeffs.c1.y]]; fontFile.PutF[" %g %g", IO.real[coeffs.c2.x*2.0], IO.real[coeffs.c2.y*2.0]]; fontFile.PutF[" %g %g)", IO.real[coeffs.c3.x*6.0], IO.real[coeffs.c3.y*6.0]]; ENDLOOP; fontFile.PutRope[")\n NATURAL))"]; k _ 0; }; fontFile.PutRope["\n((FAMILY "]; fontFile.PutRope[family];fontFile.PutRope[")\n"]; fontFile.PutF[" (CHARACTER %d)\n", IO.int[charCode]]; fontFile.PutRope[" (FACE "]; fontFile.PutRope[face];fontFile.PutRope[")\n"]; fontFile.PutF[" (WIDTH %d %d)\n", IO.int[Real.RoundLI[widthx*fiducial/quad]], IO.int[Real.RoundLI[widthy*fiducial/quad]]]; fontFile.PutF[" (FIDUCIAL %d %d)\n", IO.int[fiducial], IO.int[fiducial]]; fontFile.PutRope[" (SPLINES"]; Curve.EnumerateContours[handle: Curve.defaultHandle, newContour: NewContour, newCubic: NewCubic]; WriteCurrentOutline[]; fontFile.PutRope["))\n"]; }; SFWriterJaMInit: FitJaM.InitProc = { <> JaM.Register[state, "SF.Open", Open]; -- -> . Opens .sf file in append mode JaM.Register[state, "SF.Family", Family]; -- -> . sets the family for subsequent DrawChar operations. JaM.Register[state, "SF.Face", Face]; -- -> . sets the face for subsequent DrawChar operations. JaM.Register[state, "SF.Origin", Origin]; -- -> . says what the character origins are. JaM.Register[state, "SF.Quad", Quad]; -- -> . says what the units are. JaM.Register[state, "SF.Close", Close]; -- -> . closes .sf file. JaM.Register[state, "SF.Char", Char]; -- . -> . Takes the current path and writes it out as a character in .sf format. }; FitJaM.RegisterInit[$SFWriterJaMInit, SFWriterJaMInit]; END.