<> <> <> <> DIRECTORY Imager, ImagerBackdoor, ImagerFont, ImagerMemory, ImagerPath, ImagerPrivate, PrincOpsUtils, Rope; ImagerMemoryImpl: CEDAR PROGRAM IMPORTS Imager, ImagerBackdoor, ImagerPrivate, PrincOpsUtils, Rope EXPORTS Imager, ImagerMemory ~ BEGIN OPEN Imager; IntKey: TYPE ~ ImagerBackdoor.IntKey; RealKey: TYPE ~ ImagerBackdoor.RealKey; Clipper: TYPE ~ ImagerBackdoor.Clipper; StrokeDashes: TYPE ~ ImagerPrivate.StrokeDashes; Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD[head, tail: CommandList]; CommandList: TYPE ~ LIST OF Command; Class: TYPE ~ ImagerPrivate.Class; ClassRep: PUBLIC TYPE ~ ImagerPrivate.ClassRep; --export to Imager Command: TYPE ~ REF CommandRep; CommandRep: TYPE ~ RECORD[SELECT type: * FROM DoSave => [body: CommandList, all: BOOL], SetInt => [key: IntKey, val: INT], SetReal => [key: RealKey, val: REAL], SetT => [m: Transformation], SetFont => [font: Font], SetColor => [color: Color], SetClipper => [clipper: Clipper], SetStrokeDashes => [strokeDashes: StrokeDashes], < [key: IntKey] RETURNS[INT],>> < [key: RealKey] RETURNS[REAL],>> < [] RETURNS[Transformation],>> < [] RETURNS[Font],>> < [] RETURNS[Color],>> < [] RETURNS[Clipper],>> < [] RETURNS[StrokeDashes],>> ConcatT => [m: Transformation], Scale2T => [s: VEC], RotateT => [a: REAL], TranslateT => [t: VEC], Move => [rounded: BOOL], SetXY => [p: VEC], SetXYRel => [v: VEC], Show => [string: XStringSeq, xrel: BOOL], ShowText => [text: REF READONLY TEXT, start, len: NAT, xrel: BOOL], StartUnderline => [], MaskUnderline => [dy, h: REAL], CorrectMask => [], CorrectSpace => [v: VEC], Space => [x: REAL], SetCorrectMeasure => [v: VEC], SetCorrectTolerance => [v: VEC], Correct => [body: CommandList], DontCorrect => [body: CommandList, saveCP: BOOL], SetGray => [f: REAL], SetSampledColor => [pa: PixelArray, m: Transformation, colorOperator: ColorOperator], SetSampledBlack => [pa: PixelArray, m: Transformation, clear: BOOL], MaskFill => [path: Path, parity: BOOL], MaskRectangle => [r: Rectangle], MaskRectangleI => [x, y, w, h: INTEGER], MaskStroke => [path: Path, closed: BOOL], MaskVector => [p1, p2: VEC], MaskPixel => [pa: PixelArray], MaskBits => [bits: Bits], DrawBits => [bits: Bits], Clip => [path: Path, parity: BOOL, exclude: BOOL], ClipRectangle => [r: Rectangle, exclude: BOOL], ClipRectangleI => [x, y, w, h: INTEGER, exclude: BOOL] < [rounded: BOOL] RETURNS[VEC],>> < [] RETURNS[Rectangle],>> ENDCASE ]; XStringSeq: TYPE ~ REF XStringSeqRec; XStringSeqRec: TYPE ~ RECORD [ SEQUENCE n: CARDINAL OF XChar ]; Path: TYPE ~ LIST OF PathRec; PathRec: TYPE ~ RECORD [SELECT type: * FROM move => [p: VEC], line => [p1: VEC], curve => [p1, p2, p3: VEC], conic => [p1, p2: VEC, r: REAL], arc => [p1, p2: VEC], dummy => [] --Should never occur after creation ENDCASE ]; <> DoPath: PROC [path: Path, moveTo: ImagerPath.MoveToProc, lineTo: ImagerPath.LineToProc, curveTo: ImagerPath.CurveToProc, conicTo: ImagerPath.ConicToProc, arcTo: ImagerPath.ArcToProc] ~ { FOR each: Path _ path, each.rest UNTIL each=NIL DO WITH each.first SELECT FROM m: move PathRec => moveTo[m.p]; l: line PathRec => lineTo[l.p1]; cu: curve PathRec => curveTo[cu.p1, cu.p2, cu.p3]; co: conic PathRec => conicTo[co.p1, co.p2, co.r]; arc: arc PathRec => arcTo[arc.p1, arc.p2]; ENDCASE => ERROR; ENDLOOP; }; GetPath: PROC [pathProc: PathProc] RETURNS [path: Path] ~ { AppendToPath: PROC [pathRec: PathRec] ~ { pathTail _ pathTail.rest _ LIST[pathRec]; }; MoveTo: ImagerPath.MoveToProc ~ { AppendToPath[[move [p]]] }; LineTo: ImagerPath.LineToProc ~ { AppendToPath[[line [p1]]] }; CurveTo: ImagerPath.CurveToProc ~ { AppendToPath[[curve [p1, p2, p3]]] }; ConicTo: ImagerPath.ConicToProc ~ { AppendToPath[[conic [p1, p2, r]]] }; ArcTo: ImagerPath.ArcToProc ~ { AppendToPath[[arc [p1, p2]]] }; pathTail: Path _ path _ LIST[[dummy []]]; pathProc[MoveTo, LineTo, CurveTo, ConicTo, ArcTo]; path _ path.rest; --Drop the dummy record }; GetBody: PROC [context: Context, action: PROC] RETURNS [body: CommandList] ~ { savedData: Data ~ NARROW[context.data]; data: Data; context.data _ NEW[DataRep _ [NIL, NIL]]; --Start with a fresh trail action[]; --Perform the action data _ NARROW[context.data]; context.data _ savedData; RETURN [data.head] }; Append: PROC[data: Data, command: CommandRep] ~ { tail: CommandList ~ LIST[NEW[CommandRep _ command]]; IF data.tail=NIL THEN data.head _ tail ELSE data.tail.rest _ tail; data.tail _ tail; }; ReplayList: PROC [cList: CommandList, into: Context] ~ { FOR each: CommandList _ cList, each.rest UNTIL each=NIL DO WITH each.first^ SELECT FROM cmd: DoSave CommandRep => { Action: PROC ~ { ReplayList[cmd.body, into]; }; IF cmd.all THEN Imager.DoSaveAll[into, Action] ELSE Imager.DoSave[into, Action]; }; cmd: SetInt CommandRep => ImagerBackdoor.SetInt[into, cmd.key, cmd.val]; cmd: SetReal CommandRep => ImagerBackdoor.SetReal[into, cmd.key, cmd.val]; cmd: SetT CommandRep => ImagerBackdoor.SetT[into, cmd.m]; cmd: SetFont CommandRep => Imager.SetFont[into, cmd.font]; cmd: SetColor CommandRep => Imager.SetColor[into, cmd.color]; cmd: SetClipper CommandRep => ImagerBackdoor.SetClipper[into, cmd.clipper]; cmd: SetStrokeDashes CommandRep => ImagerPrivate.SetStrokeDashes[into, cmd.strokeDashes]; cmd: ConcatT CommandRep => Imager.ConcatT[into, cmd.m]; cmd: Scale2T CommandRep => Imager.Scale2T[into, cmd.s]; cmd: RotateT CommandRep => Imager.RotateT[into, cmd.a]; cmd: TranslateT CommandRep => Imager.TranslateT[into, cmd.t]; cmd: Move CommandRep => { IF cmd.rounded THEN Imager.Trans[into] ELSE Imager.Move[into]; }; cmd: SetXY CommandRep => Imager.SetXY[into, cmd.p]; cmd: SetXYRel CommandRep => Imager.SetXYRel[into, cmd.v]; cmd: Show CommandRep => { FeedChar: Imager.XStringProc ~ { <<~ PROC [charAction: XCharProc]>> <> FOR i: CARDINAL IN [0..cmd.string.n) DO charAction[cmd.string[i]]; ENDLOOP; }; Imager.Show[into, FeedChar, cmd.xrel]; }; cmd: ShowText CommandRep => Imager.ShowText[into, cmd.text, cmd.start, cmd.len, cmd.xrel]; cmd: StartUnderline CommandRep => Imager.StartUnderline[into]; cmd: MaskUnderline CommandRep => Imager.MaskUnderline[into, cmd.dy, cmd.h]; cmd: CorrectMask CommandRep => Imager.CorrectMask[into]; cmd: CorrectSpace CommandRep => Imager.CorrectSpace[into, cmd.v]; cmd: Space CommandRep => Imager.Space[into, cmd.x]; cmd: SetCorrectMeasure CommandRep => Imager.SetCorrectMeasure[into, cmd.v]; cmd: SetCorrectTolerance CommandRep => Imager.SetCorrectTolerance[into, cmd.v]; cmd: Correct CommandRep => { Action: PROC ~ { ReplayList[cmd.body, into]; }; Imager.Correct[into, Action]; }; cmd: DontCorrect CommandRep => { Action: PROC ~ { ReplayList[cmd.body, into]; }; Imager.DontCorrect[into, Action, cmd.saveCP]; }; cmd: SetGray CommandRep => Imager.SetGray[into, cmd.f]; cmd: SetSampledColor CommandRep => Imager.SetSampledColor[into, cmd.pa, cmd. m, cmd.colorOperator]; cmd: SetSampledBlack CommandRep => Imager.SetSampledBlack[into, cmd.pa, cmd. m, cmd.clear]; cmd: MaskFill CommandRep => { PathProc: Imager.PathProc ~ { DoPath[cmd.path, moveTo, lineTo, curveTo, conicTo, arcTo]; }; Imager.MaskFill[into, PathProc, cmd.parity]; }; cmd: MaskRectangle CommandRep => Imager.MaskRectangle[into, cmd.r]; cmd: MaskRectangleI CommandRep => Imager.MaskRectangleI[into, cmd.x, cmd.y, cmd.w, cmd.h]; cmd: MaskStroke CommandRep => { PathProc: Imager.PathProc ~ { DoPath[cmd.path, moveTo, lineTo, curveTo, conicTo, arcTo]; }; Imager.MaskStroke[into, PathProc, cmd.closed]; }; cmd: MaskVector CommandRep => Imager.MaskVector[into, cmd.p1, cmd.p2]; cmd: MaskPixel CommandRep => Imager.MaskPixel[into, cmd.pa]; cmd: MaskBits CommandRep => Imager.MaskBits[into, LOOPHOLE[cmd.bits.data], cmd.bits.wordsPerLine, cmd.bits.sMin, cmd.bits.fMin, cmd.bits.sSize, cmd.bits.fSize, cmd.bits.tx, cmd.bits.ty]; cmd: DrawBits CommandRep => ImagerBackdoor.DrawBits[into, LOOPHOLE[cmd.bits.data], cmd.bits.wordsPerLine, cmd.bits.sMin, cmd.bits.fMin, cmd.bits.sSize, cmd.bits.fSize, cmd.bits.tx, cmd.bits.ty]; cmd: Clip CommandRep => { PathProc: Imager.PathProc ~ { DoPath[cmd.path, moveTo, lineTo, curveTo, conicTo, arcTo]; }; Imager.Clip[into, PathProc, cmd.parity, cmd.exclude]; }; cmd: ClipRectangle CommandRep => Imager.ClipRectangle[into, cmd.r, cmd.exclude]; cmd: ClipRectangleI CommandRep => Imager.ClipRectangleI[into, cmd.x, cmd.y, cmd.w, cmd.h, cmd.exclude]; ENDCASE => ERROR; ENDLOOP; }; <> NewMemoryContext: PUBLIC PROC RETURNS [c: Context] ~ { c _ NEW[Imager.ContextRep _ [class: memoryClass, data: NEW[DataRep _ [NIL, NIL]]]]; }; Replay: PUBLIC PROC [c, into: Context] ~ { cList: CommandList ~ NARROW[c.data, Data].head; ReplayList[cList, into]; }; <> Bits: TYPE ~ RECORD [ wordsPerLine, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER, data: REF BitsData ]; BitsData: TYPE ~ RECORD [SEQUENCE size: CARDINAL OF WORD]; MakeBits: PROC [base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] RETURNS [bits: Bits] ~ { bits _ [wordsPerLine, sMin, fMin, sSize, fSize, tx, ty, NEW[BitsData[wordsPerLine*sSize]]]; TRUSTED {PrincOpsUtils.LongCopy[from: base, to: LOOPHOLE[bits.data], nwords: wordsPerLine*sSize];} }; MemoryDoSave: PROC[context: Context, action: PROC, all: BOOL] ~ { body: CommandList ~ GetBody[context, action]; Append[NARROW[context.data], [DoSave [body, all]]]; }; MemorySetInt: PROC[context: Context, key: IntKey, val: INT] ~ { Append[NARROW[context.data], [SetInt [key, val]]]; }; MemorySetReal: PROC[context: Context, key: RealKey, val: REAL] ~ { Append[NARROW[context.data], [SetReal [key, val]]]; }; MemorySetT: PROC[context: Context, m: Transformation] ~ { Append[NARROW[context.data], [SetT [m]]]; }; MemorySetFont: PROC[context: Context, font: Font] ~ { Append[NARROW[context.data], [SetFont [font]]]; }; MemorySetColor: PROC[context: Context, color: Color] ~ { Append[NARROW[context.data], [SetColor [color]]]; }; MemorySetClipper: PROC[context: Context, clipper: Clipper] ~ { Append[NARROW[context.data], [SetClipper [clipper]]]; }; MemorySetStrokeDashes: PROC[context: Context, strokeDashes: StrokeDashes] ~ { Append[NARROW[context.data], [SetStrokeDashes [strokeDashes]]]; }; MemoryGetInt: PROC[context: Context, key: IntKey] RETURNS[INT] ~ { Imager.Error[[$unimplemented, "Not implemented"]]}; MemoryGetReal: PROC[context: Context, key: RealKey] RETURNS[REAL] ~ { Imager.Error[[$unimplemented, "Not implemented"]]}; MemoryGetT: PROC[context: Context] RETURNS[Transformation] ~ { Imager.Error[[$unimplemented, "Not implemented"]]}; MemoryGetFont: PROC[context: Context] RETURNS[Font] ~ { Imager.Error[[$unimplemented, "Not implemented"]]}; MemoryGetColor: PROC[context: Context] RETURNS[Color] ~ { Imager.Error[[$unimplemented, "Not implemented"]]}; MemoryGetClipper: PROC[context: Context] RETURNS[Clipper] ~ { Imager.Error[[$unimplemented, "Not implemented"]]}; MemoryGetStrokeDashes: PROC[context: Context] RETURNS[StrokeDashes] ~ { Imager.Error[[$unimplemented, "Not implemented"]]}; MemoryConcatT: PROC[context: Context, m: Transformation] ~ { Append[NARROW[context.data], [ConcatT [m]]]; }; MemoryScale2T: PROC[context: Context, s: VEC] ~ { Append[NARROW[context.data], [Scale2T [s]]]; }; MemoryRotateT: PROC[context: Context, a: REAL] ~ { Append[NARROW[context.data], [RotateT [a]]]; }; MemoryTranslateT: PROC[context: Context, t: VEC] ~ { Append[NARROW[context.data], [TranslateT [t]]]; }; MemoryMove: PROC[context: Context, rounded: BOOL] ~ { Append[NARROW[context.data], [Move [rounded]]]; }; MemorySetXY: PROC[context: Context, p: VEC] ~ { Append[NARROW[context.data], [SetXY [p]]]; }; MemorySetXYRel: PROC[context: Context, v: VEC] ~ { Append[NARROW[context.data], [SetXYRel [v]]]; }; MemoryShow: PROC[context: Context, string: XStringProc, xrel: BOOL] ~ { CountXChars: ImagerFont.XCharProc ~ { n _ n+1; }; InstallXChar: ImagerFont.XCharProc ~ { xString[n] _ char; n _ n+1; }; xString: XStringSeq; n: INT _ 0; string[CountXChars]; --Count number of chars fed back xString _ NEW[XStringSeqRec[n]]; n _ 0; string[InstallXChar]; --Install each character Append[NARROW[context.data], [Show [string: xString, xrel: xrel]]]; }; MemoryShowText: PROC[context: Context, text: REF READONLY TEXT, start, len: NAT, xrel: BOOL] ~ { newText: REF TEXT ~ Rope.ToRefText[Rope.FromRefText[text]]; Append[NARROW[context.data], [ShowText [newText, start, len, xrel]]]; }; MemoryStartUnderline: PROC[context: Context] ~ { Append[NARROW[context.data], [StartUnderline []]]}; MemoryMaskUnderline: PROC[context: Context, dy, h: REAL] ~ { Append[NARROW[context.data], [MaskUnderline [dy, h]]]; }; MemoryCorrectMask: PROC[context: Context] ~ { Append[NARROW[context.data], [CorrectMask []]]}; MemoryCorrectSpace: PROC[context: Context, v: VEC] ~ { Append[NARROW[context.data], [CorrectSpace [v]]]; }; MemorySpace: PROC[context: Context, x: REAL] ~ { Append[NARROW[context.data], [Space [x]]]; }; MemorySetCorrectMeasure: PROC[context: Context, v: VEC] ~ { Append[NARROW[context.data], [SetCorrectMeasure [v]]]; }; MemorySetCorrectTolerance: PROC[context: Context, v: VEC] ~ { Append[NARROW[context.data], [SetCorrectTolerance [v]]]; }; MemoryCorrect: PROC[context: Context, action: PROC] ~ { body: CommandList ~ GetBody[context, action]; Append[NARROW[context.data], [Correct [body]]]; }; MemoryDontCorrect: PROC[context: Context, action: PROC, saveCP: BOOL] ~ { body: CommandList ~ GetBody[context, action]; Append[NARROW[context.data], [DontCorrect [body, saveCP]]]; }; MemorySetGray: PROC[context: Context, f: REAL] ~ { Append[NARROW[context.data], [SetGray [f]]]; }; MemorySetSampledColor: PROC[context: Context, pa: PixelArray, m: Transformation, colorOperator: ColorOperator] ~ { Append[NARROW[context.data], [SetSampledColor [pa, m, colorOperator]]]; }; MemorySetSampledBlack: PROC[context: Context, pa: PixelArray, m: Transformation, clear: BOOL] ~ { Append[NARROW[context.data], [SetSampledBlack [pa, m, clear]]]; }; MemoryMaskFill: PROC[context: Context, path: PathProc, parity: BOOL] ~ { pathList: Path ~ GetPath[path]; Append[NARROW[context.data], [MaskFill [pathList, parity]]]; }; MemoryMaskRectangle: PROC[context: Context, r: Rectangle] ~ { Append[NARROW[context.data], [MaskRectangle [r]]]; }; MemoryMaskRectangleI: PROC[context: Context, x, y, w, h: INTEGER] ~ { Append[NARROW[context.data], [MaskRectangleI [x, y, w, h]]]; }; MemoryMaskStroke: PROC[context: Context, path: PathProc, closed: BOOL] ~ { pathList: Path ~ GetPath[path]; Append[NARROW[context.data], [MaskStroke [pathList, closed]]]; }; MemoryMaskVector: PROC[context: Context, p1, p2: VEC] ~ { Append[NARROW[context.data], [MaskVector [p1, p2]]]; }; MemoryMaskPixel: PROC[context: Context, pa: PixelArray] ~ { Append[NARROW[context.data], [MaskPixel [pa]]]; }; MemoryMaskBits: PROC[context: Context, base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] ~ { bits: Bits ~ MakeBits[base, wordsPerLine, sMin, fMin, sSize, fSize, tx, ty]; Append[NARROW[context.data], [MaskBits [bits]]]; }; MemoryDrawBits: PROC[context: Context, base: LONG POINTER, wordsPerLine: NAT, sMin, fMin, sSize, fSize: NAT, tx, ty: INTEGER] ~ { bits: Bits ~ MakeBits[base, wordsPerLine, sMin, fMin, sSize, fSize, tx, ty]; Append[NARROW[context.data], [DrawBits [bits]]]; }; MemoryClip: PROC[context: Context, path: PathProc, parity: BOOL, exclude: BOOL] ~ { pathList: Path ~ GetPath[path]; Append[NARROW[context.data], [Clip [pathList, parity, exclude]]]; }; MemoryClipRectangle: PROC[context: Context, r: Rectangle, exclude: BOOL] ~ { Append[NARROW[context.data], [ClipRectangle [r, exclude]]]; }; MemoryClipRectangleI: PROC[context: Context, x, y, w, h: INTEGER, exclude: BOOL] ~ { Append[NARROW[context.data], [ClipRectangleI [x, y, w, h, exclude]]]; }; MemoryGetCP: PROC[context: Context, rounded: BOOL] RETURNS[VEC] ~ { Imager.Error[[$unimplemented, "Not implemented"]]}; MemoryGetBoundingRectangle: PROC[context: Context] RETURNS[Rectangle] ~ { Imager.Error[[$unimplemented, "Not implemented"]]}; memoryClass: Class ~ NEW[ClassRep _ [ type: $Memory, DoSave: MemoryDoSave, SetInt: MemorySetInt, SetReal: MemorySetReal, SetT: MemorySetT, SetFont: MemorySetFont, SetColor: MemorySetColor, SetClipper: MemorySetClipper, SetStrokeDashes: MemorySetStrokeDashes, GetInt: MemoryGetInt, GetReal: MemoryGetReal, GetT: MemoryGetT, GetFont: MemoryGetFont, GetColor: MemoryGetColor, GetClipper: MemoryGetClipper, GetStrokeDashes: MemoryGetStrokeDashes, ConcatT: MemoryConcatT, Scale2T: MemoryScale2T, RotateT: MemoryRotateT, TranslateT: MemoryTranslateT, Move: MemoryMove, SetXY: MemorySetXY, SetXYRel: MemorySetXYRel, Show: MemoryShow, ShowText: MemoryShowText, StartUnderline: MemoryStartUnderline, MaskUnderline: MemoryMaskUnderline, CorrectMask: MemoryCorrectMask, CorrectSpace: MemoryCorrectSpace, Space: MemorySpace, SetCorrectMeasure: MemorySetCorrectMeasure, SetCorrectTolerance: MemorySetCorrectTolerance, Correct: MemoryCorrect, DontCorrect: MemoryDontCorrect, SetGray: MemorySetGray, SetSampledColor: MemorySetSampledColor, SetSampledBlack: MemorySetSampledBlack, MaskFill: MemoryMaskFill, MaskRectangle: MemoryMaskRectangle, MaskRectangleI: MemoryMaskRectangleI, MaskStroke: MemoryMaskStroke, MaskVector: MemoryMaskVector, MaskPixel: MemoryMaskPixel, MaskBits: MemoryMaskBits, DrawBits: MemoryDrawBits, Clip: MemoryClip, ClipRectangle: MemoryClipRectangle, ClipRectangleI: MemoryClipRectangleI, GetCP: MemoryGetCP, GetBoundingRectangle: MemoryGetBoundingRectangle ]]; <> END.