--ContourJaM.mesa -- Last Changed: Maureen Stone December 12, 1984 12:42:27 pm PST -- Written by: Maureen Stone DIRECTORY Imager, ImagerBasic USING [PixelArray, PixelBufferRep, PixelBuffer, DeviceRectangle, ColorRep, PathMapType], ImagerTransform USING [InverseTransform, Concat, Transform, Translate, Rotate], ImagerPixelMaps USING [PixelMap, DeviceRectangle, Create, ShiftMap, Clear, Trim, Copy, Window], ImagerMasks USING [PixelArrayFromPixelMap], Vector USING [Vec], Cubic USING [Bezier], FitJaM USING [defaultFitState, InitProc, RegisterInit], FitState USING [ResetData, AddSample, NewContour, NextContour, AddLink, EnumerateLinks, Handle], FS USING [Error, StreamOpen], Real USING [RoundLI], Scaled USING [FromReal, zero], SampledColors USING[bitmap, intensity, PixelArrayFromAIS, DrawImage], UFFileManager USING[KeyOf], UFPressFontReader USING[Size, Range, Family, Face, Resolution, GetCharInfo, GetCharRaster, CharInfo, GetCharOutline, FontKey, NumberOfFontsInFile], Font USING [Key, Create, FONT, Box, Pair, FontBoundingBox, WidthVector], Outline, JaMImager USING[Painter], JaM, Rope USING [ROPE, Fetch, FromChar], Basics USING [LowByte, LowHalf], AIS USING [Error], IO USING [STREAM, Close], SDtoSF USING [PathToStream]; ContourJaM: CEDAR PROGRAM IMPORTS Imager, SampledColors, JaMImager, AIS, JaM, Rope, FitState, ImagerTransform, Outline, FS, FitJaM, Real, Scaled, UFFileManager, UFPressFontReader, Font, ImagerPixelMaps, ImagerMasks, Basics, SDtoSF, IO EXPORTS = BEGIN acFont: InternalFont; sdFont: RECORD [font: Font.FONT, fontKey: UFPressFontReader.FontKey, scale: REAL]; sfFont: IO.STREAM; pixels: ImagerBasic.PixelArray; colorOperator: ATOM; outline: Outline.Handle _ NEW[Outline.Rec]; OpenAIS: PROCEDURE[state: JaM.State] = { ENABLE AIS.Error =>{JaM.ExecuteRope[state, "(AIS file error) .print" ! JaM.Stop => CONTINUE]; CONTINUE}; [pixels, colorOperator] _ SampledColors.PixelArrayFromAIS[JaM.PopRope[state]]; outline.tValue _ 128.5; outline.border _ 255; SetWindowFromPixels[]; }; OpenSF: PROC [state: JaM.State] = { sfFont _ FS.StreamOpen[JaM.PopRope[state], $append! FS.Error => IF error.group=user THEN JaM.ExecuteRope[state, "(Invalid file name) .print" ! JaM.Stop => CONTINUE]]; }; CloseSF: PROC [state: JaM.State] = {IO.Close[sfFont]}; WriteSFChar: PROC [state: JaM.State] = { s: REAL _ JaM.PopReal[state]; -- pointsize/resolution to make it a "1 point font" char: CHAR _ Rope.Fetch[JaM.PopRope[state],0]; PathMap: ImagerBasic.PathMapType = { fitState: FitState.Handle _ NARROW[data]; newContour: PROC[x,y: REAL] = {move[[s*x,s*y]]}; newCubic: PROC[c: Cubic.Bezier] = { curve[[s*c.b1.x, s*c.b1.y], [s*c.b2.x, s*c.b2.y], [s*c.b3.x, s*c.b3.y]]}; FitState.EnumerateLinks[fitState, newContour, newCubic]; }; SDtoSF.PathToStream[ dest: sfFont, pathMap: PathMap, pathData: FitJaM.defaultFitState, family: acFont.family, face: "M R R", charCode: VAL[char], widthx: acFont.charRep[char].fWidth, widthy: acFont.charRep[char].sWidth]; }; FontNotFound: SIGNAL = CODE; OpenACFont: PROCEDURE[state: JaM.State] = { ENABLE FontNotFound =>{JaM.ExecuteRope[state, "(File not found or file not an AC font) .print" ! JaM.Stop => CONTINUE]; CONTINUE}; acFont _ LoadAC[JaM.PopRope[state]]; JaM.PushRope[state,"A"]; GetACChar[state]; }; OpenSDFont: PROCEDURE[state: JaM.State] = { ENABLE FS.Error =>{JaM.ExecuteRope[state, "(file not found) .print" ! JaM.Stop => CONTINUE]; CONTINUE}; scale: REAL _ JaM.PopReal[state]; name: Rope.ROPE _ JaM.PopRope[state]; font: Font.FONT _ Font.Create[name, Imager.Scale[scale]]; sdFont _ [font, [font.graphicsKey, 0],scale]; }; GetACChar: PROCEDURE[state: JaM.State] = { IF acFont=NIL THEN { JaM.ExecuteRope[state, "(Please open a font) .print"! JaM.Stop => CONTINUE]; RETURN}; pixels _ acFont.charRep[Rope.Fetch[JaM.PopRope[state],0]].pixels; SetWindowFromPixels[]; colorOperator _ SampledColors.bitmap; outline.tValue _ 1; outline.border _ 0; }; GetSDChar: PROC [state: JaM.State] ~ { IF sdFont.font=NIL THEN { JaM.ExecuteRope[state, "(Please open a font) .print"! JaM.Stop => CONTINUE]; RETURN}; pixels _ PAFromSDChar[Rope.Fetch[JaM.PopRope[state],0]]; SetWindowFromPixels[]; colorOperator _ SampledColors.bitmap; outline.tValue _ 1; outline.border _ 0; }; ShowWindow: PROCEDURE[state: JaM.State] = { path: Imager.Trajectory _ Imager.MoveTo[[outline.xStart, outline.yStart]]; Paint: PROC[dc: Imager.Context] = { Imager.MaskStrokeClosed[dc, path, 0]; }; path _ Imager.LineTo[path, [outline.xStart, outline.yStart+outline.yPixels]]; path _ Imager.LineTo[path, [outline.xStart+outline.xPixels, outline.yStart+outline.yPixels]]; path _ Imager.LineTo[path, [outline.xStart+outline.xPixels, outline.yStart]]; JaMImager.Painter[Paint, state]; }; ResetWindow: PROCEDURE[state: JaM.State] = { SetWindowFromPixels[]; }; SetWindowFromPixels: PROC = { --find an upright box in client space sx, sy, ex, ey: REAL; [[sx, sy]] _ ImagerTransform.Transform[[0,0],pixels.m]; [[ex,ey]] _ ImagerTransform.Transform[[pixels.xPixels,pixels.yPixels],pixels.m]; outline.xStart _ Real.RoundLI[MIN[sx,ex]]; outline.xPixels _ Real.RoundLI[MAX[sx,ex]]-outline.xStart; outline.yStart _ Real.RoundLI[MIN[sy,ey]]; outline.yPixels _ Real.RoundLI[MAX[sy,ey]]-outline.yStart; }; InternalFont: TYPE ~ REF InternalFontRep; InternalFontRep: TYPE ~ RECORD [ family: Rope.ROPE _ NIL, face: [0..255] _ 0, bitsPerEmQuad: REAL _ 0, charRep: ARRAY CHAR OF InternalCharRep ]; InternalCharRep: TYPE ~ RECORD [ fWidth, sWidth: REAL, pixels: ImagerBasic.PixelArray ]; LoadAC: PROC [fileName: Rope.ROPE] RETURNS [internalFont: InternalFont] ~ TRUSTED { fileKey: Font.Key _ UFFileManager.KeyOf[fileName]; sizeInMeters: REAL; bc, ec: CHAR; IF UFPressFontReader.NumberOfFontsInFile[fileKey] = 0 THEN SIGNAL FontNotFound; [bc, ec] _ UFPressFontReader.Range[[fileKey, 0]]; sizeInMeters _ UFPressFontReader.Size[[fileKey, 0]]; internalFont _ NEW [InternalFontRep]; internalFont.family _ UFPressFontReader.Family[[fileKey, 0]]; internalFont.face _ UFPressFontReader.Face[[fileKey, 0]]; internalFont.bitsPerEmQuad _ sizeInMeters*UFPressFontReader.Resolution[[fileKey, 0]].xRes/0.0254; FOR char: CHAR IN [bc..ec] DO info: UFPressFontReader.CharInfo _ UFPressFontReader.GetCharInfo[[fileKey, 0], char]; pixelArray: ImagerBasic.PixelArray _ UFPressFontReader.GetCharRaster[[fileKey, 0], char]; internalFont.charRep[char] _ [ fWidth: info.widthX*internalFont.bitsPerEmQuad, sWidth: -info.widthY*internalFont.bitsPerEmQuad, pixels: pixelArray ]; ENDLOOP; }; Window: PROCEDURE[state: JaM.State] = { y2: REAL _ JaM.PopReal[state]; x2: REAL _ JaM.PopReal[state]; y1: REAL _ JaM.PopReal[state]; x1: REAL _ JaM.PopReal[state]; dx1, dx2, dy1, dy2: REAL; IF y2 open a font file JaM.Register[state,"Contour.openSDFont", OpenSDFont]; --(name) size => open a font file JaM.Register[state,"Contour.showPA",ShowPA]; --use Imager to display the current file JaM.Register[state,"Contour.getACChar", GetACChar]; --(char) => sets up a character for outlining JaM.Register[state,"Contour.getSDChar", GetSDChar]; --(char) => scan converts an SD char at the current size and sets it up for outlining JaM.Register[state,"Contour.setSDContour", SetSDContour]; --(char) => creates contour from an sd char JaM.Register[state,"Contour.windowPA", Window]; --x1 y1 x2 y2 => Set a window on the ais image JaM.Register[state,"Contour.showWindow", ShowWindow]; --draws outline of window JaM.Register[state,"Contour.resetWindow", ResetWindow]; --resets window to the size of the pixel array JaM.Register[state,"Contour.getValue", GetValue]; --x, y => returns the value in the ps JaM.Register[state,"Outline.tvalue",SetOutlineT]; -- Outline threshhold value JaM.Register[state,".outline",OutlineEdge]; --find the contours JaM.Register[state,".outlineBlackCenter",OutlineBlackCenter]; --find the edge through the black region. Makes sense for binary files. JaM.Register[state,".outlineBlackEdge",OutlineBlackEdge]; --find the edge around the black region. Makes sense for binary files. JaM.Register[state,"Outline.drawContour",ODrawContour]; --number .drawContour JaM.Register[state,"Outline.drawAllContours",ODrawAllContours]; --.drawAllContour JaM.Register[state,"Outline.setsa",OSetSamples]; --send numbered contour's samples to FitState JaM.Register[state,"Outline.setallsa",OSetAllSamples]; --send all contours to FitState JaM.Register[state,".cvchar",CVChar]; --Convert a number to a character }; outline.get _ Get; outline.newEdge _ NewEdge; FitJaM.RegisterInit[$ContourJaM, Init]; END. 0Copied out of RasterFontWriterImpl. Changed PixelMap to PixelArray will be in client coordinates if came from .touch Now have a rectangle with x1, y1 in the lower left, x2, y2 in the upper right Transform from View to Client space. Imager.ConcatT[dc, pixels.m]; Create a pixelarray and set pixels Κ γ– "cedar" style˜J˜Jšœ˜J˜@J˜šΟk ˜ Jšœ˜Jšœ œS˜dJšœœ:˜OJšœœJ˜_Jšœ œ˜+Jšœœ˜Jšœœ ˜Jšœœ+˜7Jšœ œR˜`Jšœœ˜Jšœœ ˜Jšœœ˜Jšœœ2˜EJšœœ˜Jšœœ|˜“Jšœœœœ$˜HJ˜Jšœ œ ˜Jšœ˜Jšœœœ˜#Jšœœ˜ Jšœœ ˜Jšœœœ ˜Jšœœ˜—J˜šœ  ˜Jšœ#œ‘˜ΠJšœ˜J˜Jšœ˜Jšœœ œ-œ˜RJšœ œ˜J˜Jšœœ˜Jšœœ˜+J˜šΟnœ œ˜(JšœœIœœ˜hJšœN˜NJ˜J˜Jšœ˜Jšœ˜—J˜šžœœ˜#šœ œ)œ ˜?šœ˜JšœCœ˜R—Jšœ˜——šžœœœ˜6J˜—šž œœ˜(JšœœΟc3˜QJšœœ$˜.˜$Jšœœ˜)Jšœ œœ˜0šœ œ˜#JšœI˜I—J˜8J˜—šœ˜JšœB˜BJšœ0œ˜;JšœJ˜J—J˜J˜—Jšœœœ˜šž œ œ˜+Jšœgœ ˜‚Jšœ$˜$J˜J˜Jšœ˜J˜—šž œ œ˜+JšœœIœ ˜gJšœœ˜!Jšœ œ˜%Jšœ œ*˜9Jšœ-˜-Jšœ˜J˜—šž œ œ˜*šœœœ˜JšœBœœ˜U—JšœA˜AJ˜Jšœ%˜%J˜J˜J˜J˜—šž œœ˜&šœ œœ˜JšœBœœ˜U—Jšœ8˜8J˜Jšœ%˜%J˜J˜Jšœ˜—J˜šž œ œ˜+JšœJ˜Jšžœœ˜#J˜%Jšœ˜—JšœM˜MJšœ]˜]JšœM˜MJšœ ˜ Jšœ˜J˜—šž œ œ˜,Jšœ˜J˜J˜—šžœœŸ%˜CJšœœ˜J˜7J˜QJšœœ ˜*Jšœœ˜:Jšœœ ˜*Jšœœ˜:J˜—J™CJšœœœ˜)šœœœ˜ Jšœ œœ˜J˜Jšœœ˜Jšœ œœœ˜&Jšœ˜—šœœœ˜ Jšœœ˜J˜Jšœ˜—š žœœœœ œ˜SJšœ2˜2Jšœœ˜Jšœœ˜ Jšœ4œœ˜OJšœ1˜1Jšœ4˜4Jšœœ˜%Jšœ=˜=Jšœ9˜9Jšœa˜ašœœœ ˜JšœU˜UJšœY˜Yšœ˜Jšœ/˜/Jšœ0˜0Jšœ˜J˜—Jšœ˜—Jšœ˜—J˜šžœ œ˜'Jšœœ˜Jšœœ˜Jšœœ˜Jšœœ˜J™1Jšœœ˜Jšœœœ˜-Jšœœœ˜-JšœM™MJ™$JšœG˜GJšœG˜GJ˜#J˜#J˜(J˜(J˜—J˜šžœ œ˜)Jšœœ˜Jšœœ˜Jšœœ˜ Jšœœ˜JšœC˜CJ˜1J˜J˜—J˜Jšœœœ˜Jšœ"œ ˜Eš žœœ œœœœ˜1šžœœ˜#Jšœ œœŸ ˜)šœœ˜%Jšœ"˜"J˜!J˜—Jšœ˜—Jšœœ˜ Jšœ=˜=Jšœb˜bJšœœœ ˜7Jšœ ˜J˜J˜—Jšœ7˜7šžœ œ˜'šžœœ˜#J˜1Jšœ˜—Jšœ ˜ Jšœ˜—J˜Jšœœœ˜šžœ œ œœœ œœ˜XJšœœ ˜"šžœœ˜#šœœ˜ J™Jšœ"˜"J˜&J˜—J˜Jšœ˜—Jšœœ!˜.Jšœ˜Jšœ˜—J˜Jšœ œ˜šž œœ˜(J˜J˜)Jšœ˜J˜J˜—šžœœ˜/J˜J˜0Jšœ˜J˜J˜—šžœœ˜-J˜J˜-Jšœ˜J˜J˜—šž œ œ˜-Jšœ-˜-Jšœ˜J˜—šžœ œ˜1Jš œœœœ œ˜GJšœ˜J˜—šžœ œœ˜=šžœœ˜#Jšœœ˜ Jšœœœ˜šœœœ˜Jšœœ ˜Jšœ)˜-Jšœ˜J˜—J˜,J˜—Jšœ ˜ Jšœ˜—J˜J˜šΟb œœœœ!˜HJšœ1˜1Jšœ=˜=Jšœ²˜²Jšœa˜aJšœ4œ'˜^Jšœ5˜5JšœD˜DJšœ˜Jšœ˜J˜J˜Jšœ˜J™"Jšœ˜Jšœ:ŸΟi˜VJšœ2˜2šœ˜Jšœ3˜3Jšœ#˜#—Jšœ˜J˜—šž œœ˜)JšœœŸ˜6Jšœ˜Jšœ˜šœ œœ˜ J˜,J˜J˜—šœ œœ˜ J˜JšœQ˜QJ˜1J˜J˜—šœ œœŸ$˜XJšœ8˜8J˜1J˜J˜—šœ œ˜J˜-J˜—Jšœl˜lJšœ˜J˜—šž œœ˜(Jšœœ˜ J˜Jšœ˜J˜—šžœœ˜+šœœœœ˜ Jšœ˜Jšœœ-˜CJšœ˜—J˜J˜—šžœ œœ˜+šœœœ˜Jšœ0˜0J˜—Jšœ4˜4J˜,Jšœ˜J˜—Jšž œ œ;˜Qšœ œ˜'Jšœœœ4˜AJ˜&Jšœ˜—J˜J˜šœ˜Jšœ-Ÿ˜FJšœ/Ÿ˜IJšœ7Ÿ˜RJšœ/Ÿ-˜\Jšœ7Ÿ˜SJšœ7Ÿ!˜XJšœ-Ÿ(˜UJšœ5Ÿ-˜bJšœ5ŸU˜ŠJšœ;Ÿ+˜fJšœ1ŸΠci‘˜`Jšœ7Ÿ˜PJšœ9Ÿ.˜gJšœ3Ÿ%˜XJ˜Jšœ2Ÿ˜MJšœ,Ÿ˜?Jšœ>ŸH˜†Jšœ:ŸG˜Jšœ8Ÿ˜MJšœ@Ÿ˜QJšœ1Ÿ-˜^Jšœ7Ÿ˜VJšœ&Ÿ!˜GJ˜J˜—J˜J˜J˜'Jšœ˜——…—8\Fo