-- CGBitmapImpl.mesa -- Last changed by Doug Wyatt, October 4, 1982 11:37 am DIRECTORY CGArea USING [Ref], CGBitmapDevice USING [New], CGClipper USING [SetBox], CGContext USING [GenBox, Ref, ResetPool], CGDevice USING [Ref], CGMatrix USING [Assign, Concat, Id, Map, New, Ref, SetTrans, Translate], CGPrivate USING [Context], CGScreen USING [Bits], CGSource USING [Ref, Rep], CGStorage USING [pZone, qZone], GraphicsBasic USING [black, Box, Vec], GraphicsOps USING [BitmapRef, BitmapRep, Texture]; CGBitmapImpl: CEDAR PROGRAM IMPORTS CGBitmapDevice, CGClipper, CGContext, CGMatrix, CGScreen, CGStorage EXPORTS CGContext, CGPrivate, GraphicsOps = { OPEN GraphicsBasic; BitmapRef: TYPE = GraphicsOps.BitmapRef; BitmapRep: TYPE = GraphicsOps.BitmapRep; Data: TYPE = REF DataRep; DataRep: PUBLIC TYPE = RECORD [ lastid: CGMatrix.Id, -- id of last matrix used to form map map: CGMatrix.Ref, -- bitmap to device matrix mask: CGSource.Ref -- source info for bitmap ]; Context: TYPE = CGPrivate.Context; ContextData: TYPE = CGContext.Ref; BitmapDataRep: PUBLIC TYPE = DataRep; -- export into CGContext dataZone: ZONE = CGStorage.qZone; srcZone: ZONE = CGStorage.qZone; repZone: ZONE = CGStorage.qZone; bitmapZone: ZONE = CGStorage.pZone; GetData: PROC[self: ContextData] RETURNS[Data] = INLINE { data: Data _ self.bitmapdata; RETURN[IF data=NIL THEN MakeData[self] ELSE data] }; MakeData: PROC[self: ContextData] RETURNS[Data] = { data: Data _ dataZone.NEW[DataRep _ [lastid: 0, map: NIL, mask: NIL]]; data.map _ CGMatrix.New[]; data.mask _ srcZone.NEW[CGSource.Rep _ [type: array, mode: opaque, fat: FALSE, bps: 0, color: GraphicsBasic.black, xbase: NIL, xrast: 0, Get: NIL]]; self.bitmapdata _ data; RETURN[data]; }; DrawBits: PUBLIC UNSAFE PROC[self: Context, base: LONG POINTER, raster: CARDINAL, bitsPerPixel: [0..16), x, y, w, h: CARDINAL, xorigin, yorigin: INTEGER] = CHECKED { ctx: ContextData _ NARROW[self.data]; data: Data _ GetData[ctx]; device: CGDevice.Ref _ ctx.device; cp: Vec _ ctx.cp; src: CGSource.Ref _ ctx.src; T: CGMatrix.Ref _ ctx.matrix; M: CGMatrix.Ref _ data.map; mask: CGSource.Ref _ data.mask; IF data.lastid#T.id THEN { CGMatrix.Assign[M,T]; IF ctx.yUp THEN CGMatrix.Concat[M,1,0,0,-1]; data.lastid _ T.id }; IF base=NIL THEN { [base: base, raster: raster] _ CGScreen.Bits[] }; mask.xbase _ base; mask.xrast _ raster; mask.bps _ bitsPerPixel; mask.type _ array; mask.mode _ src.mode; mask.color _ src.color; mask.raw _ (bitsPerPixel#0); -- crock! CGMatrix.SetTrans[M,cp]; CGMatrix.Translate[M,-xorigin,-yorigin]; { box: Box _ [xmin: x, xmax: x+w, ymin: y, ymax: y+h]; area: CGArea.Ref _ CGContext.GenBox[ctx,box,M]; device.Show[device,area,mask,M]; }; }; SetTargetBitmap: PUBLIC PROC[self: Context, bitmap: BitmapRef] = { ctx: ContextData _ NARROW[self.data]; device: CGDevice.Ref _ IF bitmap=NIL THEN CGBitmapDevice.New[NIL,0,0] ELSE CGBitmapDevice.New[ base: bitmap.base, raster: bitmap.raster, height: bitmap.height]; m: CGMatrix.Ref _ device.GetMatrix[device]; dbase: LONG POINTER _ NIL; drast: CARDINAL _ 0; ctx.device _ device; CGMatrix.Assign[ctx.matrix,m]; ctx.yUp _ TRUE; ctx.cp _ CGMatrix.Map[m,[0,0]]; CGClipper.SetBox[ctx.clipper,device.GetBounds[device]]; ctx.src^ _ [type: const, fat: FALSE, mode: opaque, bps: 0, color: GraphicsBasic.black, xbase: NIL, xrast: 0, Get: NIL]; ctx.boxing _ ctx.newbox _ FALSE; IF device.GetRaster#NIL THEN { [dbase,drast] _ device.GetRaster[device] }; IF dbase=NIL THEN { ctx.dbase _ NIL; ctx.drast _ 0; ctx.haveRaster _ FALSE } ELSE { ctx.dbase _ dbase; ctx.drast _ drast; ctx.haveRaster _ TRUE }; CGContext.ResetPool[ctx]; }; NewBitmap: PUBLIC PROC[width,height: CARDINAL] RETURNS[BitmapRef] = { Words: TYPE = RECORD[SEQUENCE COMPUTED CARDINAL OF CARDINAL]; raster: CARDINAL = (width+15)/16; base: REF _ bitmapZone.NEW[Words[raster*height]]; RETURN[repZone.NEW[BitmapRep _ [base: base, raster: raster, width: width, height: height]]]; }; ScreenBitmap: PUBLIC PROC RETURNS[BitmapRef] = { raster,height: CARDINAL; [raster: raster, height: height] _ CGScreen.Bits[]; RETURN[repZone.NEW[BitmapRep _ [ base: NIL, raster: 0, -- Convention: NIL means the screen width: 16*raster, height: height]]]; }; DrawTexturedBox: PUBLIC PROC[self: Context, box: Box, texture: GraphicsOps.Texture] = { ctx: ContextData _ NARROW[self.data]; data: Data _ GetData[ctx]; device: CGDevice.Ref _ ctx.device; src: CGSource.Ref _ data.mask; TRUSTED { src.xbase _ @texture }; src.xrast _ 1; src.type _ tile; src.mode _ ctx.src.mode; src.color _ ctx.src.color; { area: CGArea.Ref _ CGContext.GenBox[ctx, box, ctx.matrix]; device.Show[device, area, src, NIL] }; }; }.