DIRECTORY Font USING [WidthVector], ViewerClasses USING [Viewer, PaintProc, ViewerClass, ViewerClassRec], ViewerOps USING [RegisterViewerClass, CreateViewer, PaintViewer], Imager, Rope USING [Length, ROPE, ActionType, Cat, Map, Equal], Real, Graphics USING [Path, NewPath, MoveTo, LineTo, CurveTo, DrawStroke, SetPaintMode], ImagerPixelMaps USING [PixelMap, Create, Clear], ImagerBridge USING [SetViewFromGraphicsContext], ImagerBasic USING [ColorRep], ImagerPD USING [PDFileDescription, Raven, Puffin, PlateMaker]; JunoImagerTest: CEDAR PROGRAM IMPORTS Font, Imager, ViewerOps, ImagerBridge, Graphics, ImagerPD, ImagerPixelMaps, Rope, Real = BEGIN OPEN Gr: Graphics, Im: Imager, ImBas: ImagerBasic, ImMaps: ImagerPixelMaps, ImPD: ImagerPD; Color: TYPE = Im.Color; Coords: TYPE = Im.Pair; Trajectory: TYPE = Im.Trajectory; ROPE: TYPE = Rope.ROPE; bm: REF ImMaps.PixelMap _ NIL; -- Internal bitmap (screen buffer) bmCtx: Im.Context; -- A context that paints into bm. Origin at bottom left, 1 dot/unit ctx: Im.Context _ NIL; -- Either bmCtx or a PD context (or NIL at first). SetScreenContext: PUBLIC PROC [width, height: INTEGER _ 0] = BEGIN IF width = 0 THEN width _ bm.fSize; IF height = 0 THEN height _ bm.sSize; IF bm=NIL OR width # bm.fSize OR height # bm.sSize THEN {bm _ NEW [ImMaps.PixelMap _ ImMaps.Create [lgBitsPerPixel: 0, bounds:[sMin:0, fMin:0, sSize: height, fSize: width]]]; bmCtx _ Im.Create[deviceType: $LFDisplay -- , data: bm --]}; ctx _ bmCtx; ImMaps.Clear[bm^]; ResetContextProps[width: 0, color: invert] END; SetPaperContext: PUBLIC PROC [device: ATOM, fileName: Rope.ROPE, width, height: INTEGER, mag: REAL _ 1.0] = BEGIN ctx _ Im.Create[$PD, SELECT device FROM $Raven => ImPD.Raven[fileName], $Puffin => ImPD.Puffin[fileName], $PlateMaker => ImPD.PlateMaker[fileName], ENDCASE => ERROR]; ResetContextProps[width: 0.4, color: black, mag: mag]; Im.ClipRectangle[ctx, 0, 0, width, height] END; ResetContextProps: PROC [width: REAL, color: Color, mag: REAL _ 1.0] = BEGIN Im.ScaleT[ctx, 0.0254/72/mag]; Im.SetPriorityImportant[ctx, TRUE]; DoSetFont[ctx: ctx, name: "TimesRoman", face: $regular, size: 10]; [] _ SetEnds[$round]; [] _ SetColor[color]; [] _ SetWidth[width]; [] _ SetJustification[$left] END; currentColor: Color _ Im.black; SetColor: PUBLIC PROC [color: Color] RETURNS [old: Color] = BEGIN old _ currentColor; Im.SetColor[ctx, color]; currentColor _ color END; invert: Color _ Im.XOR; black: Color _ Im.black; white: Color _ Im.white; IntensityToColor: PUBLIC PROC [intensity: REAL] RETURNS [color: Color] = BEGIN color _ Im.MakeGray[intensity] END; RGBToColor: PUBLIC PROC [r, g, b: REAL] RETURNS [color: Color] = BEGIN color _ NEW [ImBas.ColorRep[constant] _ [constant[x: Real.RoundI[r*10000], y: Real.RoundI[g*10000], Y: Real.RoundI[b*10000]]]] END; currentEnds: ATOM _ $round; SetEnds: PUBLIC PROC [ends: ATOM] RETURNS [old: ATOM] = BEGIN old _ currentEnds; Im.SetStrokeEnd [ctx, SELECT ends FROM $round => round, $square => square, $butt => butt, ENDCASE => ERROR]; currentEnds _ ends END; currentWidth: REAL _ 0; SetWidth: PUBLIC PROC [width: REAL] RETURNS [old: REAL] = BEGIN old _ currentWidth; Im.SetStrokeWidth [ctx, width]; currentWidth _ width END; currentFont: Im.FONT; currentFontName: ROPE _ "Helvetica"; currentSize: REAL _ 12; currentFace: ATOM _ $regular; SetFont: PUBLIC PROC [name: ROPE] RETURNS [old: ROPE] = BEGIN old _ currentFontName; IF NOT Rope.Equal[currentFontName, name] THEN {DoSetFont [ctx, name, currentFace, currentSize]} END; SetFontSize: PUBLIC PROC [size: REAL] RETURNS [old: REAL] = BEGIN old _ currentSize; IF currentSize # size THEN {DoSetFont [ctx, currentFontName, currentFace, size]} END; SetFace: PUBLIC PROC [face: ATOM] RETURNS [old: ATOM] = BEGIN old _ currentFace; IF currentFace # face THEN {DoSetFont [ctx, currentFontName, face, currentSize]} END; DoSetFont: PROC [ctx: Im.Context, name: ROPE, face: ATOM, size: REAL] = BEGIN currentFont _ Im.MakeFont [name: Rope.Cat["Xerox/PressFonts/", name, SELECT face FROM $regular => "/MRR", $italic => "/MIR", $bold => "/BRR", $boldItalic => "/BIR", ENDCASE => ERROR], size: size]; currentFontName _ name; currentFace _ face; currentSize _ size; Im.SetFont [ctx, currentFont] END; currentJustification: ATOM _ $left; SetJustification: PUBLIC PROC [justification: ATOM] RETURNS [old: ATOM] = BEGIN old _ currentJustification; currentJustification _ justification END; DrawPoint: PUBLIC PROC[pix: Coords] = BEGIN dim: REAL = MAX [1, currentWidth]; Im.MaskRectangle[ctx, pix.x-dim, pix.y-dim, dim+dim, dim+dim] END; DrawEdge: PUBLIC PROC [p, q: Coords, thin: BOOL _ TRUE] = BEGIN Im.MaskVector [context: ctx, p1: [p.x, p.y], p2: [q.x, q.y], strokeWidth: IF thin THEN 0 ELSE Im.defaultStrokeWidth] END; DrawArc: PUBLIC PROC [p, r, s, q: Coords, thin: BOOL _ TRUE] = BEGIN Im.MaskStroke [context: ctx, t: Im.MoveTo[p].CurveTo[r, s, q], strokeWidth: IF thin THEN 0 ELSE Im.defaultStrokeWidth] END; AppendEdge: PUBLIC PROC [t: Trajectory, p, q: Coords] RETURNS [new: Trajectory] = BEGIN IF t = NIL THEN t _ Im.MoveTo[p]; new _ t.LineTo[q]; END; AppendArc: PUBLIC PROC [t: Trajectory, p, r, s, q: Coords] RETURNS [new: Trajectory] = BEGIN IF t = NIL THEN t _ Im.MoveTo[p]; new _ t.CurveTo[r, s, q]; END; FillTrajectory: PUBLIC PROC [t: Trajectory] = BEGIN Im.MaskFill[ctx, t] END; StrokeTrajectory: PUBLIC PROC [t: Trajectory] = BEGIN Im.MaskStroke[ctx, t] END; DrawChar: PUBLIC PROC [coords: Coords, char: CHAR] = BEGIN Im.SetXY[ctx, coords]; Im.ShowChar[ctx, char] END; DrawRope: PUBLIC PROC [coords: Coords, rope: ROPE] = BEGIN lft: Im.Pair; IF currentJustification = $left THEN {lft _ coords} ELSE {vec: Im.Pair _ [0,0]; {Act: Rope.ActionType = TRUSTED {w: Im.Pair =Font.WidthVector[currentFont, c]; vec _ [vec.x+w.x, vec.y+w.y]}; [] _ Rope.Map[base: rope, len: rope.Length[], action: Act]}; lft.x _ coords.x - (IF currentJustification = $right THEN vec.x ELSE vec.x/2); lft.y _ coords.y - (IF currentJustification = $right THEN vec.y ELSE vec.y/2)}; Im.SetXY[ctx, lft]; Im.ShowCharacters[ctx, rope] END; prc: REF PROC _ NEW [PROC _ NIL]; Do: PROC [prc: REF PROC] = BEGIN ViewerOps.PaintViewer[viewer: vv, hint: client, clearClient: FALSE, whatChanged: prc] END; PaintMe: ViewerClasses.PaintProc = BEGIN IF whatChanged = $TestGraphics THEN {path: Gr.Path _ Gr.NewPath[]; Gr.MoveTo[path, 400, 600]; Gr.LineTo[path, 400, 500]; Gr.LineTo[path, 500, 500]; Gr.CurveTo[path, 450, 500, 400, 450, 400, 400]; [] _ Gr.SetPaintMode[self: context, mode: invert]; Gr.DrawStroke[self: context, path: path, width: 15, ends: round]} ELSE IF whatChanged # NIL THEN {Proc: REF PROC = NARROW [whatChanged]; ImagerBridge.SetViewFromGraphicsContext [imager: bmCtx, graphics: context]; Proc^[]} END; vc: ViewerClasses.ViewerClass = NEW [ViewerClasses.ViewerClassRec _ [paint: PaintMe]]; vv: ViewerClasses.Viewer; t: Trajectory _ NIL; ViewerOps.RegisterViewerClass[flavor: $Crap, class: vc]; vv _ ViewerOps.CreateViewer[flavor: $Crap, info: [iconic:FALSE, name:"Crap"]]; SetScreenContext[width: 600, height: 800]; Do[NEW[PROC _ {DrawEdge[[50,50], [200,200]]}]]; Do[NEW[PROC _ {DrawRope[[250,250], "Fee Fi Foo Fum\n(this is fun...)"]}]]; [] _ SetFontSize[12]; Do[NEW[PROC _ {DrawRope[[300,300], "Fee Fi Foo Fum\n(this is fun...)"]}]]; Do[NEW[PROC _ {DrawPoint[[150, 150]]}]]; [] _ SetWidth[15]; [] _ SetEnds[$round]; t _ AppendEdge[t, [100,300], [100, 200]]; t _ AppendEdge[t, [100,200], [200,200]]; t _ AppendArc [t, [200,200], [150, 200], [100, 150], [100, 100]]; ViewerOps.PaintViewer[viewer: vv, hint: client, whatChanged: $TestGraphics]; [] _ SetColor[IntensityToColor[0.4]]; Do[NEW[PROC _ {FillTrajectory[t]}]]; [] _ SetColor[IntensityToColor[0.8]]; Do[NEW[PROC _ {StrokeTrajectory[t]}]]; {r: INTEGER _ 0; THROUGH [1..500] DO THROUGH [1..1000] DO r _ r + r - r ENDLOOP ENDLOOP}; SetPaperContext[device: $Raven, width: 600, height: 800, fileName: "ImagerTest.PD"]; DrawEdge[[50,50], [200,200]]; DrawRope[[250,250], "Fee Fi Foo Fum\n(this is fun...)"]; [] _ SetColor[IntensityToColor[0.4]]; FillTrajectory[t]; [] _ SetColor[IntensityToColor[0.8]]; StrokeTrajectory[t]; [] _ Im.SpecialOp[ctx, $Close, NIL] END. : JunoImagerTest.mesa Last Edited by: Stolfi, June 5, 1984 2:41:05 am PDT Tests Imager stuff for Juno. Important: initialization call must give width # 0, height # 0. - - - - INITIALIZATION: - - - - LINES, STROKES, FILLED PATHS - - - - CHARS AND ROPES Performs Proc while attching ctx to the viewer vv ʬ˜šœ™™J™5—J™—šœÏk ˜ Jšœœœ=œ@œ œ‰œYœœ0˜ú—šœÏbœ ˜šœ˜JšœX˜XJšœ˜——šœ˜šœ˜JšœW˜W—Jšœœ ˜Jšœ œ ˜Jšœ œ˜"Jšœœœœ˜JšœžœœœÏc"˜BJšœžœŸD˜XJšœžœœŸ2˜Jš œÏnœœœœ˜=J™?šœ˜Jš œœ œœ œ˜JJš œœœœœœ±Ÿœ˜üJšœK˜K—Jšœœ˜—šœ œœœ œœœœ ˜nšœ˜Jš œœœvœœd˜’—Jšœœ˜—š œ œœ œœ ˜Gšœ˜Jšœå˜å—Jšœœ˜—Jšœ ˜ š œ œœœœ˜<šœ˜JšœC˜C—Jšœœ˜—Jšœœ3˜Jš œ œœœ œœ˜Išœ˜Jšœ˜—Jšœœ˜—š œ  œœœ œœ˜Ašœ˜Jšœ œbœ˜ˆ—Jšœœ˜—Jšœœ ˜š œ œœœœœœ˜8šœ˜Jš œ/œœHœœ˜¬—Jšœœ˜—Jšœœ˜š œ œœœ œœœ˜:šœ˜JšœI˜I—Jšœœ˜—Jšœœ˜Jšœœ˜%Jšœœ˜Jšœœ ˜š œ œœœœœœ˜8šœ˜Jšœœœ#œ4˜y—Jšœœ˜—š œ  œœœœœœ˜<šœ˜Jšœœœ8˜f—Jšœœ˜—š œ œœœœœœ˜8šœ˜Jšœœœ8˜f—Jšœœ˜—š œ  œœœœœ˜Hšœ˜Jš œMœœsœœn˜Î—Jšœœ˜—Jšœœ ˜$š œ œœœœœœ˜Jšœ˜JšœA˜A—Jšœœ˜——š œ™šœ  œœœ˜&šœ˜JšœœœQ˜a—Jšœœ˜——š œ$™%š œ œœœœœ˜:šœ˜JšœNœœœ˜x—Jšœœ˜—š œ œœœœœ˜?šœ˜JšœPœœœ˜z—Jšœœ˜—š œ  œœœœ˜Ršœ˜Jšœœœœ%˜5—Jšœœ˜—š œ  œœœ%œ˜Wšœ˜Jšœœœœ,˜<—Jšœœ˜—šœ œœœ˜.šœ˜Jšœ˜—Jšœœ˜—šœ œœœ˜0šœ˜Jšœ˜—Jšœœ˜——š œ™š œ œœœœ˜5šœ˜Jšœ.˜.—Jšœœ˜—š œ œœœœ˜5šœ˜Jšœœœœ žœœºœœœ"œœœ ˜ÏJšœ1˜1—Jšœœ˜—Jš œœœœœœ˜"š œ œœœœ˜J™1šœ˜Jšœ>œ˜V—Jšœœ˜—šœžœ˜#šœ˜Jšœœœ¬œœœœ œœœœj˜ó—Jšœœ˜—Jšœ!œc˜‡Jšœsœ˜ˆJšœ+˜+Jšœœœ$˜0Jš œœœYœœ?˜¬Jšœœœ˜)Jšœ)˜)Jšœ•˜•JšœN˜NJš œ*œœCœœ˜˜Jšœœœ œœ œœœ˜[JšœÁœ˜Å—Jšœœ˜—…— ü*â