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. ContourJaM.mesa Copyright c 1985 by Xerox Corporation. All rights reserved. Written by: Maureen Stone Last Changed: Maureen Stone December 12, 1984 12:42:27 pm PST Doug Wyatt, September 5, 1985 3:38:06 pm PDT Copied 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˜codešœ™Kšœ Οmœ1™‘H˜†Kšœ:‘G˜Kšœ8‘˜MKšœ@‘˜QKšœ1‘-˜^Kšœ7‘˜VKšœ&‘!˜GK˜K˜—K˜K˜K˜'Kšžœ˜——…—7μFϊ