<> <> <> <> <> DIRECTORY CGArea USING [Empty, Ref, Remove], CGContext USING [Rep], CGDevice USING [Ref, Rep], CGMatrix USING [Make, Ref], CGSource USING [Ref], CGStorage USING [qZone], Graphics, GraphicsBasic USING [Trap], JaM USING [State, PushReal, Register], Real, TAGraphicsHacks, TJaMGraphics, TJaMGraphicsContexts USING [AddContext, EnableContext, DisableContext]; TAGraphicsHacksImpl: CEDAR PROGRAM IMPORTS CGArea, CGMatrix, CGStorage, Graphics, JaM, TJaMGraphics, TJaMGraphicsContexts EXPORTS GraphicsBasic, TAGraphicsHacks = { <> DeviceObject: PUBLIC TYPE = CGDevice.Rep; ContextObject: PUBLIC TYPE = CGContext.Rep; <> boundsBox: Graphics.Box; nullBoundsBox: Graphics.Box = [Real.LargestNumber, Real.LargestNumber, -Real.LargestNumber, -Real.LargestNumber]; Data: TYPE = REF DataRep; DataRep: TYPE = RECORD [ matrix: CGMatrix.Ref _ NIL -- base transformation matrix ]; dataZone: ZONE = CGStorage.qZone; repZone: ZONE = CGStorage.qZone; state: JaM.State; NewBoxerDevice: PROCEDURE RETURNS[CGDevice.Ref] = { data: Data _ dataZone.NEW[DataRep]; data.matrix _ CGMatrix.Make[[1,0,0,1,0,0]]; boundsBox _ nullBoundsBox; RETURN[repZone.NEW[CGDevice.Rep _ [ GetMatrix: GetMatrix, GetBounds: GetBounds, Show: BoxerShow, GetRaster: BoxerGetRaster, data: data]]]; }; InitBoxerDevice: PROCEDURE RETURNS [Graphics.Context] = { RETURN [Graphics.NewContext[NewBoxerDevice[]]]; }; GetMatrix: SAFE PROC[self: CGDevice.Ref] RETURNS[CGMatrix.Ref] = TRUSTED { data: Data _ NARROW[self.data]; RETURN[data.matrix]; }; GetBounds: SAFE PROC[self: CGDevice.Ref] RETURNS[Graphics.Box] = TRUSTED { RETURN[[0.1, 0.1, 4000-.1, 4000-.1]]}; BoxerShow: SAFE PROC[self: CGDevice.Ref, area: CGArea.Ref, src: CGSource.Ref, map: CGMatrix.Ref] = TRUSTED { <> UNTIL CGArea.Empty[area] DO trap: GraphicsBasic.Trap _ CGArea.Remove[area]; { OPEN boundsBox, trap; xmin _ MIN[xmin, xbotL]; xmin _ MIN[xmin, xtopL]; ymin _ MIN[ymin, ybot]; xmax _ MAX[xmax, xbotR]; xmax _ MAX[xmax, xtopR]; ymax _ MAX[ymax, ytop]}; ENDLOOP; }; BoxerGetRaster: SAFE PROC[self: CGDevice.Ref] RETURNS[LONG POINTER,CARDINAL] = TRUSTED { <> RETURN[NIL,0]; }; JBeginBox: PROCEDURE[state: JaM.State] = { <> BeginBox[]; }; JEndBox: PROCEDURE[state: JaM.State] = { box: Graphics.Box; box _ EndBox[]; JaM.PushReal[state, box.xmin]; JaM.PushReal[state, box.ymin]; JaM.PushReal[state, box.xmax]; JaM.PushReal[state, box.ymax]; }; BeginBox: PUBLIC PROCEDURE = { init: PROC[dc: Graphics.Context] = {}; <> TJaMGraphicsContexts.EnableContext[state, $Boxer]; TJaMGraphics.Painter[init, state]; }; EndBox: PUBLIC PROCEDURE RETURNS[Graphics.Box] = { <> TJaMGraphicsContexts.DisableContext[state, $Boxer]; IF boundsBox=nullBoundsBox THEN RETURN[[0,0,0,0]] ELSE RETURN[boundsBox] }; RegisterGraphicsHacks: PUBLIC PROCEDURE [initState: JaM.State] ~ { state _ initState; JaM.Register[state, ".beginbox", JBeginBox]; JaM.Register[state, ".endbox", JEndBox]; TJaMGraphicsContexts.AddContext[state, InitBoxerDevice, $Boxer, FALSE]; }; }.