<> <> <> DIRECTORY Imager, ImagerBasic, ImagerDefault, ImagerPrivate, ImagerTransform, Real; ImagerDefaultImpl: CEDAR PROGRAM IMPORTS Imager, ImagerTransform, Real EXPORTS ImagerDefault SHARES Imager ~ BEGIN OPEN ImagerDefault; Trajectory: TYPE ~ Imager.Trajectory; TrajectoryRep: TYPE ~ Imager.TrajectoryRep; <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <<];>> <<>> <> <> <> <> <<};>> <<>> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> <> DoSave: PUBLIC PROC[context: Context, body: PROC] ~ { WITH context.state SELECT FROM state: State => { saved: ImagerState.StateRep ~ state^; propList: Atom.PropList ~ context.propList; Restore: PROC ~ { IF context.state#state THEN ERROR; state.T _ saved.T; state.priorityImportant _ saved.priorityImportant; state.mediumXSize _ saved.mediumXSize; state.mediumYSize _ saved.mediumYSize; state.fieldXMin _ saved.fieldXMin; state.fieldYMin _ saved.fieldYMin; state.fieldXMax _ saved.fieldXMax; state.fieldYMax _ saved.fieldYMax; state.showVec _ saved.showVec; state.color _ saved.color; state.noImage _ saved.noImage; state.strokeWidth _ saved.strokeWidth; state.strokeEnd _ saved.strokeEnd; state.underlineStart _ saved.underlineStart; state.amplifySpace _ saved.amplifySpace; state.correctPass _ saved.correctPass; state.correctShrink _ saved.correctShrink; state.correctTX _ saved.correctTX; state.correctTY _ saved.correctTY; state.clipper _ saved.clipper; context.propList _ propList; }; body[! UNWIND => Restore[]]; Restore[]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; DoSaveAll: PUBLIC PROC[context: Context, body: PROC] ~ { WITH context.state SELECT FROM state: State => { saved: ImagerBasic.StateRep ~ state^; propList: Atom.PropList ~ context.propList; Restore: PROC ~ { IF context.state#state THEN ERROR; state^ _ saved; context.propList _ propList; }; body[! UNWIND => Restore[]]; Restore[]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetPriorityImportant: PUBLIC PROC[context: Context, priorityImportant: BOOL] ~ { WITH context.state SELECT FROM state: State => { state.priorityImportant _ IF priorityImportant THEN 1 ELSE 0; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetFont: PUBLIC PROC[context: Context, font: FONT] ~ { WITH context.state SELECT FROM state: State => { state.showVec _ font; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetColor: PUBLIC PROC[context: Context, color: Color] ~ { WITH context.state SELECT FROM state: State => { state.color _ color; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetNoImage: PUBLIC PROC[context: Context, noImage: BOOL] ~ { WITH context.state SELECT FROM state: State => { state.noImage _ IF noImage THEN 1 ELSE 0; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetStrokeWidth: PUBLIC PROC[context: Context, strokeWidth: REAL] ~ { WITH context.state SELECT FROM state: State => { state.strokeWidth _ strokeWidth; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetStrokeEnd: PUBLIC PROC[context: Context, strokeEnd: StrokeEnd] ~ { WITH context.state SELECT FROM state: State => { state.strokeEnd _ SELECT strokeEnd FROM square => 0, butt => 1, round => 2, ENDCASE => ERROR; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetAmplifySpace: PUBLIC PROC[context: Context, amplifySpace: REAL] ~ { WITH context.state SELECT FROM state: State => { state.amplifySpace _ amplifySpace; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetCorrectShrink: PUBLIC PROC[context: Context, correctShrink: REAL] ~ { WITH context.state SELECT FROM state: State => { state.correctShrink _ correctShrink; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetSampledColor: PUBLIC PROC[context: Context, pa: PixelArray, pixelT: Transformation, colorOperator: ATOM] ~ { WITH context.state SELECT FROM state: State => { color: ImagerBasic.SampledColor ~ NEW[ImagerBasic.ColorRep.sampled _ [sampled[ transparent: FALSE, pa: pa, m: pixelT.Concat[state.T], colorOperator: colorOperator ]]]; state.color _ color; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetSampledBlack: PUBLIC PROC[context: Context, pa: PixelArray, pixelT: Transformation, transparent: BOOLEAN] ~ { WITH context.state SELECT FROM state: State => { color: ImagerBasic.SampledColor ~ NEW[ImagerBasic.ColorRep.sampled _ [sampled[ transparent: transparent, pa: pa, m: pixelT.Concat[state.T], colorOperator: $SampledBlack ]]]; state.color _ color; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; ConcatT: PUBLIC PROC[context: Context, m: Transformation] ~ { WITH context.state SELECT FROM state: State => { state.T _ ImagerTransform.Concat[m, state.T]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; ScaleT: PUBLIC PROC[context: Context, s: REAL] ~ { WITH context.state SELECT FROM state: State => { state.T _ ImagerTransform.PreScale[s, state.T]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; Scale2T: PUBLIC PROC[context: Context, sx, sy: REAL] ~ { WITH context.state SELECT FROM state: State => { state.T _ ImagerTransform.PreScale2[sx, sy, state.T]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; RotateT: PUBLIC PROC[context: Context, a: REAL] ~ { WITH context.state SELECT FROM state: State => { state.T _ ImagerTransform.PreRotate[a, state.T]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; TranslateT: PUBLIC PROC[context: Context, x, y: REAL] ~ { WITH context.state SELECT FROM state: State => { state.T _ ImagerTransform.PreTranslate[x, y, state.T]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; Move: PUBLIC PROC[context: Context] ~ { WITH context.state SELECT FROM state: State => { new: Pair _ [state.cpx, state.cpy]; t: ImagerTransform.TransformationRec _ state.T.Contents; state.T _ ImagerTransform.Create[t.a, t.b, new.x, t.d, t.e, new.y]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; Trans: PUBLIC PROC[context: Context] ~ { WITH context.state SELECT FROM state: State => { new: Pair _ Imager.DRound[[state.cpx, state.cpy]]; t: ImagerTransform.TransformationRec _ state.T.Contents; state.T _ ImagerTransform.Create[t.a, t.b, new.x, t.d, t.e, new.y]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetXY: PUBLIC PROC[context: Context, x, y: REAL] ~ { WITH context.state SELECT FROM state: State => { [[state.cpx, state.cpy]] _ ImagerTransform.Transform[[x, y], state.T]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetXYI: PUBLIC PROC[context: Context, x, y: INTEGER] ~ { WITH context.state SELECT FROM state: State => { [[state.cpx, state.cpy]] _ ImagerTransform.Transform[[x, y], state.T]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetXYRel: PUBLIC PROC[context: Context, x, y: REAL] ~ { WITH context.state SELECT FROM state: State => { delta: Pair ~ ImagerTransform.TransformVec[[x, y], state.T]; state.cpx _ state.cpx + delta.x; state.cpy _ state.cpy + delta.y; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetXYRelI: PUBLIC PROC[context: Context, x, y: INTEGER] ~ { WITH context.state SELECT FROM state: State => { delta: Pair ~ ImagerTransform.TransformVec[[x, y], state.T]; state.cpx _ state.cpx + delta.x; state.cpy _ state.cpy + delta.y; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; <> <> < {>> <> <<};>> < ERROR Imager.Error[$Bug];>> <<};>> <<>> <> <> < {>> <> <<};>> < ERROR Imager.Error[$Bug];>> <<};>> <<>> MaskVector: PUBLIC PROC[context: Context, x1, y1, x2, y2: REAL] ~ { MapVector: PathProc ~ { moveToP[[x1, y1]]; lineToP[[x2, y2]] }; context.MaskStroke[MapVector]; }; MaskVectorI: PUBLIC PROC[context: Context, x1, y1, x2, y2: INTEGER] ~ { MaskVector[context, x1, y1, x2, y2]; }; StartUnderline: PUBLIC PROC[context: Context] ~ { WITH context.state SELECT FROM state: State => { cp: Pair ~ ImagerTransform.InverseTransform[[state.cpx, state.cpy], state.T]; state.underlineStart _ cp.x; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; MaskUnderline: PUBLIC PROC[context: Context, dy, h: REAL] ~ { body: PROC ~ { WITH context.state SELECT FROM state: State => { cp: Pair ~ ImagerTransform.InverseTransform[[state.cpx, state.cpy], state.T]; context.SetXY[state.underlineStart, cp.y-dy-h]; context.Trans[]; context.MaskRectangle[0, 0, cp.x-state.underlineStart, h]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; context.DoSaveAll[body]; }; IntegerMaskUnderline: PUBLIC PROC [context: Context, dy, h: INTEGER] ~ { MaskUnderline[context, dy, h]; }; ClipOutline: PUBLIC PROC[context: Context, pathMap: PathMapType, pathData: REF] ~ { WITH context.state SELECT FROM state: State => { trans: ImagerTransform.TransformationRec ~ state.T.Contents; XForm: PROC [p: Pair] RETURNS [Pair] ~ { RETURN [[trans.a*p.x+trans.b*p.y+trans.c, trans.d*p.x+trans.e*p.y+trans.f]] }; tList: LIST OF Trajectory _ NIL; Move: PROC [p: Pair] ~ {tList _ CONS[Imager.MoveTo[XForm[p]], tList]}; Line: PROC [p: Pair] ~ {tList.first _ tList.first.LineTo[XForm[p]]}; Curve: PROC [p1, p2, p3: Pair] ~ { tList.first _ tList.first.CurveTo[XForm[p1], XForm[p2], XForm[p3]] }; Conic: PROC [p1, p2: Pair, r: REAL] ~ { tList.first _ tList.first.ConicTo[XForm[p1], XForm[p2], r] }; pathMap[pathData, Move, Line, Curve, Conic]; state.clipper _ CONS[[exclude: FALSE, easyRectangle: FALSE, pathMap: MapTrajectoryList, pathData: tList], state.clipper]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; MapTrajectory: PathMapType = { t: Trajectory = NARROW[data]; move[t.lp]; FOR x: Trajectory _ t, x.prev UNTIL x.prev=NIL DO p0: Pair = x.prev.lp; WITH x SELECT FROM x: REF TrajectoryRep[line] => line[p0]; x: REF TrajectoryRep[curve] => curve[x.p2, x.p1, p0]; x: REF TrajectoryRep[conic] => conic[x.p1, p0, x.r]; x: REF TrajectoryRep[move] => ERROR; ENDCASE => ERROR; ENDLOOP; }; MapTrajectoryList: PathMapType = { FOR x: LIST OF Trajectory _ NARROW[data], x.rest UNTIL x = NIL DO MapTrajectory[x.first, move, line, curve, conic] ENDLOOP; }; ExcludeOutline: PUBLIC PROC[context: Context, pathMap: PathMapType, pathData: REF] ~ { WITH context.state SELECT FROM state: State => { ClipOutline[context, pathMap, pathData]; state.clipper.first.exclude _ TRUE; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; ClipRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] ~ { WITH context.state SELECT FROM state: State => { pathMap: PathMapType ~ { move[[x, y]]; line[[x+w, y]]; line[[x+w, y+h]]; line[[x, y+h]]; }; t: ImagerTransform.TransformationRec ~ state.T.Contents; ClipOutline[context, pathMap, NIL]; state.clipper.first.easyRectangle _ (t.a = 0 AND t.e = 0) OR (t.b = 0 AND t.d = 0); }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; ClipRectangleI: PUBLIC PROC[context: Context, x, y, w, h: INTEGER] ~ { ClipRectangle[context, x, y, w, h]; }; ExcludeRectangle: PUBLIC PROC[context: Context, x, y, w, h: REAL] ~ { WITH context.state SELECT FROM state: State => { ClipRectangle[context, x, y, w, h]; state.clipper.first.exclude _ TRUE; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; ExcludeRectangleI: PUBLIC PROC[context: Context, x, y, w, h: INTEGER] ~ { ExcludeRectangle[context, x, y, w, h]; }; CorrectMask: PUBLIC PROC[context: Context] ~ { WITH context.state SELECT FROM state: State => { SELECT state.correctPass FROM 1 => state.correctMaskCount _ state.correctMaskCount + 1; 2 => IF state.correctMaskCount > 0 THEN { spx: REAL ~ state.correctMaskX/state.correctMaskCount; spy: REAL ~ state.correctMaskY/state.correctMaskCount; state.correctMaskX _ state.correctMaskX - spx; state.correctMaskY _ state.correctMaskY - spy; state.correctMaskCount _ state.correctMaskCount - 1; state.cpx _ state.cpx + spx; state.cpy _ state.cpy + spy; }; ENDCASE => NULL; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; CorrectSpace: PUBLIC PROC[context: Context, x, y: REAL] ~ { WITH context.state SELECT FROM state: State => CorrectSpaceView[context, ImagerTransform.TransformVec[[x, y], state.T]]; ENDCASE => ERROR Imager.Error[$InvalidState]; }; CorrectSpaceView: PUBLIC PROC[context: Context, v: Pair] ~ { WITH context.state SELECT FROM state: State => { SELECT state.correctPass FROM 1 => { state.correctSumX _ state.correctSumX + v.x; state.correctSumY _ state.correctSumY + v.y; }; 2 => { Div: PROC [num, denom: REAL] RETURNS [REAL] ~ { IF denom = 0.0 THEN { IF num = 0.0 THEN RETURN [0.0] ELSE ERROR Imager.Error[$ZeroDivideInCorrectSpace] } ELSE RETURN [num/denom] }; spx: REAL ~ Div[v.x*state.correctSpaceX, state.correctSumX]; spy: REAL ~ Div[v.y*state.correctSpaceY, state.correctSumY]; state.correctSumX _ state.correctSumX - v.x; state.correctSumY _ state.correctSumY - v.y; state.correctSpaceX _ state.correctSpaceX - spx; state.correctSpaceY _ state.correctSpaceY - spy; state.cpx _ state.cpx + spx; state.cpy _ state.cpy + spy; }; ENDCASE => NULL; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetCorrectMeasure: PUBLIC PROC[context: Context, x, y: REAL] ~ { WITH context.state SELECT FROM state: State => { [[state.correctMX, state.correctMY]] _ ImagerTransform.TransformVec[[x, y], state.T]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SetCorrectTolerance: PUBLIC PROC[context: Context, x, y: REAL] ~ { WITH context.state SELECT FROM state: State => { [[state.correctTX, state.correctTY]] _ ImagerTransform.TransformVec[[x, y], state.T]; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; Space: PUBLIC PROC[context: Context, x: REAL] ~ { <> WITH context.state SELECT FROM state: State => { v: Pair ~ ImagerTransform.TransformVec[[x, 0], state.T]; state.cpx _ state.cpx + v.x; state.cpy _ state.cpy + v.y; SELECT state.correctPass FROM 1 => { state.correctSumX _ state.correctSumX + v.x; state.correctSumY _ state.correctSumY + v.y; }; 2 => IF state.correctMaskCount > 0 THEN { Div: PROC [num, denom: REAL] RETURNS [REAL] ~ { IF denom = 0.0 THEN { IF num = 0.0 THEN RETURN [0.0] ELSE ERROR Imager.Error[$ZeroDivideInCorrectSpace] } ELSE RETURN [num/denom] }; spx: REAL ~ Div[v.x*state.correctSpaceX, state.correctSumX]; spy: REAL ~ Div[v.y*state.correctSpaceY, state.correctSumY]; state.correctSumX _ state.correctSumX - v.x; state.correctSumY _ state.correctSumY - v.y; state.correctSpaceX _ state.correctSpaceX - spx; state.correctSpaceY _ state.correctSpaceY - spy; state.cpx _ state.cpx + spx; state.cpy _ state.cpy + spy; }; ENDCASE => NULL; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; SpaceI: PUBLIC PROC [context: Context, x: INTEGER] ~ { context.Space[x]; }; Correct: PUBLIC PROC[context: Context, body: PROC] ~ { WITH context.state SELECT FROM state: State => { Length: PROC [x, y: REAL] RETURNS [REAL] ~ { <> RETURN [Real.SqRt[x*x + y*y]]; }; state.correctcpx _ state.cpx; state.correctcpy _ state.cpy; state.noImage _ 1; state.correctMaskCount _ 0; state.correctSumX _ state.correctSpaceY _ 0; state.correctPass _ 1; Imager.DoSave[context, body]; state.correctTargetX _ state.correctcpx + state.correctMX; state.correctTargetY _ state.correctcpy + state.correctMY; state.correctMaskX _ state.correctMaskY _ 0; state.correctMaskCount _ state.correctMaskCount - 1; state.correctSpaceX _ state.correctTargetX - state.cpx; state.correctSpaceY _ state.correctTargetY - state.cpy; CHECKED { IF ( Length[state.correctSpaceX, state.correctSpaceY] > state.correctShrink*Length[state.correctSumX, state.correctSumY] AND Length[state.correctcpx - state.correctTargetX, state.correctcpy - state.correctTargetY] < Length[state.correctcpx - state.cpx, state.correctcpy - state.cpy] ) THEN { state.correctMaskX _ state.correctSpaceX + state.correctShrink*state.correctSumX; state.correctMaskY _ state.correctSpaceY + state.correctShrink*state.correctSumY; state.correctSpaceX _ state.correctSpaceX - state.correctMaskX; state.correctSpaceY _ state.correctSpaceY - state.correctMaskY; }; IF state.correctSumX = 0 AND state.correctSpaceX # 0 THEN { state.correctMaskX _ state.correctSpaceX; state.correctSpaceX _ 0; }; IF state.correctSumY = 0 AND state.correctSpaceY # 0 THEN { state.correctMaskY _ state.correctSpaceY; state.correctSpaceY _ 0; }; }; state.cpx _ state.correctcpx; state.cpy _ state.correctcpy; state.noImage _ 0; state.correctPass _ 2; Imager.DoSave[context, body]; state.correctPass _ 0; IF Length[state.correctTargetX - state.cpx, state.correctTargetY - state.cpy] > Length[state.correctTX, state.correctTY] THEN ERROR Imager.Error[$UnableToProperlyAdjustMaskPositions]; state.cpx _ state.correctTargetX; state.cpy _ state.correctTargetY; }; ENDCASE => ERROR Imager.Error[$InvalidState]; }; <> <> < {>> <> <> <> <> <<};>> < ERROR Imager.Error[$Bug];>> <<};>> <<>> <> <> <<};>> <<>> <> <> <<};>> <<>> <> <> < {>> <> <<};>> < ERROR Imager.Error[$Bug];>> <<};>> <<>> END.