IPImagerOpsImpl.mesa
Last edited by:
Doug Wyatt, July 7, 1983 11:51 am
DIRECTORY
CGClipper USING [Bounds, IsBox],
CGDevice USING [Ref],
CGContext USING [Ref],
Graphics USING [black, Context, GetBounds, SetColor],
GraphicsBasic USING [Box],
IPBasic USING [Any, Integer, State, Vector],
IPBitmapOutput USING [New],
IPConvert USING [RealToAny, IntegerToAny, VectorToAny, AnyToReal, AnyToInteger, AnyToVector],
IPErrors USING [Bug, MasterError],
IPExec USING [DoSimpleBody],
IPImagerOps USING [ConcatT, MakeGray, SetXRel],
IPImager,
IPImagerBasic,
IPOutput USING [Size],
IPScan USING [Allocate, PushPath],
IPStack,
IPState USING [State, StateRep],
IPTransform USING [Scale, Translate, Tv],
Real USING [RoundC];
IPImagerOpsImpl: CEDAR PROGRAM
IMPORTS CGClipper, Graphics, IPBitmapOutput, IPConvert, IPExec, IPErrors, IPImagerOps, IPScan, IPStack, IPTransform, Real
EXPORTS IPImagerOps, IPBasic
= BEGIN OPEN IPImager, IPImagerBasic, IPBasic;
State: TYPE = IPState.State;
StateRep: PUBLIC TYPE = IPState.StateRep;
Initialization
Init: PUBLIC PROC[self: State] = {
imager: Imager = NEW[IPImager.ImagerRep ← [
vars: NIL, path: NIL, output: NIL, context: NIL, font: NIL]];
vars: Vars = NEW[IPImager.VarsRep ← [link: NIL,
p: NIL, np: NIL, T: NIL, showVec: NIL, color: NIL, fontList: NIL]];
vars.p ← NEW[IPImager.PersistentVarsRep ← [
cpx: 0, cpy: 0,
correctMX: 0, correctMY: 0,
correctMaskCount: 0,
correctMaskX: 0, correctMaskY: 0,
correctSumX: 0, correctSumY: 0,
correctSpaceX: 0, correctSpaceY: 0,
correctcpx: 0, correctcpy: 0,
correctTargetX: 0, correctTargetY: 0
]];
vars.np ← NEW[IPImager.NonPersistentVarsRep ← [
priorityImportant: 0,
mediumXSize: 0, mediumYSize: 0,
fieldXMin: 0, fieldYMin: 0,
fieldXMax: 0, fieldYMax: 0,
strokeWidth: 0,
strokeEnd: 0,
noImage: 0,
underlineStart: 0,
amplifySpace: 1.0,
correctPass: 0,
correctShrink: 0.5,
correctTX: 0, correctTY: 0
]];
vars.T ← IPTransform.Scale[1];
vars.color ← IPImagerOps.MakeGray[1];
imager.vars ← vars;
self.imager ← imager;
};
Save: PUBLIC PROC[self: State, all: BOOL] = {
imager: Imager = self.imager;
old: Vars = imager.vars;
new: Vars = NEW[VarsRep ←
[link: NIL, p: NIL, np: NIL, T: NIL, showVec: NIL, color: NIL, fontList: NIL]];
new.p ← IF all THEN NEW[PersistentVarsRep ← old.p^] ELSE old.p;
new.np ← NEW[NonPersistentVarsRep ← old.np^];
new.TNEW[TransformationRep ← old.T^];
new.showVec ← old.showVec;
new.color ← old.color;
new.fontList ← old.fontList;
new.link ← old;
imager.vars ← new;
};
Restore: PUBLIC PROC[self: State] = {
imager: Imager = self.imager;
imager.vars ← imager.vars.link;
imager.font ← NIL;
};
scale: REAL ← 1;
tx, ty: REAL ← 0;
SetTFromContext: PROC[imager: Imager, context: Graphics.Context] = {
T: Transformation = imager.vars.T;
ref: CGContext.Ref = NARROW[context.data];
T.a ← ref.matrix.m.a;
T.b ← ref.matrix.m.c;
T.c ← ref.matrix.m.e;
T.d ← ref.matrix.m.b;
T.e ← ref.matrix.m.d;
T.f ← ref.matrix.m.f;
T.code ← 10;
};
SetContext: PUBLIC PROC[self: State, context: Graphics.Context] = {
imager: Imager = self.imager;
imager.context ← context;
IF context#NIL THEN {
ref: CGContext.Ref = NARROW[context.data];
box: GraphicsBasic.Box = Graphics.GetBounds[context];
fullHeight: REAL = 11.0*72.0; -- height of a full page
SetTFromContext[imager, context];
IPImagerOps.ConcatT[self, IPTransform.Translate[0, box.ymax-fullHeight]];
IPImagerOps.ConcatT[self, IPTransform.Scale[72*scale]]; -- "inches"
IPImagerOps.ConcatT[self, IPTransform.Translate[-tx, -ty]];
IPImagerOps.ConcatT[self, IPTransform.Scale[1/0.0254]]; -- meters
Graphics.SetColor[context, Graphics.black];
IF ref.haveRaster THEN {
device: CGDevice.Ref = ref.device;
dbox: GraphicsBasic.Box = device.GetBounds[device];
size: IPOutput.Size = [x: Real.RoundC[dbox.xmax], y: Real.RoundC[dbox.ymax]];
imager.output ← IPBitmapOutput.New[ref.dbase, ref.drast, size];
}
ELSE ERROR;
IF ref.clipper.IsBox[] THEN {
cbox: GraphicsBasic.Box = ref.clipper.Bounds[];
Gen: PROC[move: PROC[Pair], line: PROC[Pair], curve: PROC[Pair, Pair, Pair]] = {
move[[cbox.xmin, cbox.ymin]]; line[[cbox.xmax, cbox.ymin]];
line[[cbox.xmax, cbox.ymax]]; line[[cbox.xmin, cbox.ymax]];
};
imager.path ← IPScan.Allocate[];
IPScan.PushPath[imager.path, Gen];
}
ELSE ERROR;
};
};
Stack operations
TransformationToAny: PROC[x: Transformation] RETURNS[Any] = {
RETURN[[type: transformation, ref: x]];
};
ColorToAny: PROC[x: Color] RETURNS[Any] = {
RETURN[[type: color, ref: x]];
};
AnyToTransformation: PROC[x: Any] RETURNS[Transformation] = {
IF x.type=transformation THEN RETURN[NARROW[x.ref]]
ELSE ERROR IPErrors.MasterError[WrongType];
};
AnyToColor: PROC[x: Any] RETURNS[Color] = {
IF x.type=color THEN RETURN[NARROW[x.ref]]
ELSE ERROR IPErrors.MasterError[WrongType];
};
PushPair: PUBLIC PROC[self: State, p: Pair] = {
IPStack.PushReal[self, p.x]; IPStack.PushReal[self, p.y];
};
PushTransformation: PUBLIC PROC[self: State, x: Transformation] = {
IPStack.PushAny[self, [type: transformation, ref: x]];
};
PushColor: PUBLIC PROC[self: State, x: Color] = {
IPStack.PushAny[self, [type: color, ref: x]];
};
PushPixelArray: PUBLIC PROC[self: State, x: PixelArray] = {
IPStack.PushAny[self, [type: pixelArray, ref: x]];
};
PushTrajectory: PUBLIC PROC[self: State, x: Trajectory] = {
IPStack.PushAny[self, [type: trajectory, ref: x]];
};
PushOutline: PUBLIC PROC[self: State, x: Outline] = {
IPStack.PushAny[self, [type: outline, ref: x]];
};
PopPair: PUBLIC PROC[self: State] RETURNS[p: Pair] = {
p.y ← IPStack.PopReal[self]; p.x ← IPStack.PopReal[self];
};
PopTransformation: PUBLIC PROC[self: State] RETURNS[Transformation] = {
x: Any = IPStack.PopAny[self];
IF x.type=transformation THEN RETURN[NARROW[x.ref]]
ELSE ERROR IPErrors.MasterError[WrongType];
};
PopColor: PUBLIC PROC[self: State] RETURNS[Color] = {
x: Any = IPStack.PopAny[self];
IF x.type=color THEN RETURN[NARROW[x.ref]]
ELSE ERROR IPErrors.MasterError[WrongType];
};
PopPixelArray: PUBLIC PROC[self: State] RETURNS[PixelArray] = {
x: Any = IPStack.PopAny[self];
IF x.type=pixelArray THEN RETURN[NARROW[x.ref]]
ELSE ERROR IPErrors.MasterError[WrongType];
};
PopTrajectory: PUBLIC PROC[self: State] RETURNS[Trajectory] = {
x: Any = IPStack.PopAny[self];
IF x.type=trajectory THEN RETURN[NARROW[x.ref]]
ELSE ERROR IPErrors.MasterError[WrongType];
};
PopOutline: PUBLIC PROC[self: State] RETURNS[Outline] = {
x: Any = IPStack.PopAny[self];
IF x.type=outline THEN RETURN[NARROW[x.ref]]
ELSE ERROR IPErrors.MasterError[WrongType];
};
4.2 Imager state
IGet: PUBLIC PROC[self: State, n: Integer] RETURNS[Any] = {
IF n>22 THEN ERROR IPErrors.MasterError[BoundsFault]
ELSE {
index: [0..22] = n;
imager: Imager = self.imager;
vars: Vars = imager.vars;
SELECT index FROM
0 => RETURN[IPConvert.RealToAny[vars.p.cpx]];
1 => RETURN[IPConvert.RealToAny[vars.p.cpy]];
2 => RETURN[IPConvert.RealToAny[vars.p.correctMX]];
3 => RETURN[IPConvert.RealToAny[vars.p.correctMY]];
4 => RETURN[TransformationToAny[GetT[vars]]];
5 => RETURN[IPConvert.IntegerToAny[vars.np.priorityImportant]];
6 => RETURN[IPConvert.RealToAny[vars.np.mediumXSize]];
7 => RETURN[IPConvert.RealToAny[vars.np.mediumYSize]];
8 => RETURN[IPConvert.RealToAny[vars.np.fieldXMin]];
9 => RETURN[IPConvert.RealToAny[vars.np.fieldYMin]];
10 => RETURN[IPConvert.RealToAny[vars.np.fieldXMax]];
11 => RETURN[IPConvert.RealToAny[vars.np.fieldYMax]];
12 => RETURN[IPConvert.VectorToAny[vars.showVec]];
13 => RETURN[ColorToAny[vars.color]];
14 => RETURN[IPConvert.IntegerToAny[vars.np.noImage]];
15 => RETURN[IPConvert.RealToAny[vars.np.strokeWidth]];
16 => RETURN[IPConvert.IntegerToAny[vars.np.strokeEnd]];
17 => RETURN[IPConvert.RealToAny[vars.np.underlineStart]];
18 => RETURN[IPConvert.RealToAny[vars.np.amplifySpace]];
19 => RETURN[IPConvert.IntegerToAny[vars.np.correctPass]];
20 => RETURN[IPConvert.RealToAny[vars.np.correctShrink]];
21 => RETURN[IPConvert.RealToAny[vars.np.correctTX]];
22 => RETURN[IPConvert.RealToAny[vars.np.correctTY]];
ENDCASE => ERROR IPErrors.Bug;
};
};
ISet: PUBLIC PROC[self: State, x: Any, n: Integer] = {
IF n>22 THEN ERROR IPErrors.MasterError[BoundsFault]
ELSE {
index: [0..22] = n;
imager: Imager = self.imager;
vars: Vars = imager.vars;
SELECT index FROM
0 => vars.p.cpx ← IPConvert.AnyToReal[x];
1 => vars.p.cpy ← IPConvert.AnyToReal[x];
2 => vars.p.correctMX ← IPConvert.AnyToReal[x];
3 => vars.p.correctMY ← IPConvert.AnyToReal[x];
4 => { SetT[vars, AnyToTransformation[x]]; vars.fontList ← NIL; imager.font ← NIL };
5 => vars.np.priorityImportant ← IPConvert.AnyToInteger[x];
6 => vars.np.mediumXSize ← IPConvert.AnyToReal[x];
7 => vars.np.mediumYSize ← IPConvert.AnyToReal[x];
8 => vars.np.fieldXMin ← IPConvert.AnyToReal[x];
9 => vars.np.fieldYMin ← IPConvert.AnyToReal[x];
10 => vars.np.fieldXMax ← IPConvert.AnyToReal[x];
11 => vars.np.fieldYMax ← IPConvert.AnyToReal[x];
12 => { vars.showVec ← IPConvert.AnyToVector[x]; imager.font ← NIL };
13 => vars.color ← AnyToColor[x];
14 => vars.np.noImage ← IPConvert.AnyToInteger[x];
15 => vars.np.strokeWidth ← IPConvert.AnyToReal[x];
16 => vars.np.strokeEnd ← IPConvert.AnyToInteger[x];
17 => vars.np.underlineStart ← IPConvert.AnyToReal[x];
18 => vars.np.amplifySpace ← IPConvert.AnyToReal[x];
19 => vars.np.correctPass ← IPConvert.AnyToInteger[x];
20 => vars.np.correctShrink ← IPConvert.AnyToReal[x];
21 => vars.np.correctTX ← IPConvert.AnyToReal[x];
22 => vars.np.correctTY ← IPConvert.AnyToReal[x];
ENDCASE => ERROR IPErrors.Bug;
};
};
GetT: PROC[vars: Vars] RETURNS[Transformation] = {
RETURN[NEW[TransformationRep ← vars.T^]];
};
SetT: PROC[vars: Vars, m: Transformation] = {
vars.T^ ← m^;
};
SetMedium: PUBLIC PROC[self: State,
m: Vector, pageNumber: Integer, duplex: BOOL, xImageShift: REAL] = {
};
4.3.5 Device coordinate system
See IPTransformImpl
4.4.3 Transformation operators
See IPTransformImpl
4.4.4 Applying transformations
See IPTransformImpl
4.4.5 The current transformation
See IPTransformImpl
4.4.6 Instancing
See IPShowImpl
4.5 Current position operators
See IPShowImpl
4.6 Pixel arrays
See IPColorImpl
4.7 Color
See IPColorImpl
4.8.1 Geometry: trajectories and outlines
See IPMaskImpl
4.8.2 Filled outlines and strokes
See IPMaskImpl
4.8.3 Sampled masks
See IPMaskImpl
4.9 Character operators
See IPShowImpl
4.10 Spacing correction
CorrectMask: PUBLIC PROC[self: State] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
p: PersistentVars = vars.p;
SELECT vars.np.correctPass FROM
1 => {
p.correctMaskCount ← p.correctMaskCount+1;
};
2 => {
spx: REAL = p.correctMaskX/p.correctMaskCount;
spy: REAL = p.correctMaskY/p.correctMaskCount;
p.correctMaskX ← p.correctMaskX-spx;
p.correctMaskY ← p.correctMaskY-spy;
p.cpx ← p.cpx+spx; p.cpy ← p.cpy+spy;
p.correctMaskCount ← p.correctMaskCount-1;
};
ENDCASE;
};
CorrectSpace: PUBLIC PROC[self: State, v: Pair] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
p: PersistentVars = vars.p;
d: Pair = IPTransform.Tv[vars.T, v];
SELECT vars.np.correctPass FROM
1 => {
p.correctSumX ← p.correctSumX+d.x;
p.correctSumY ← p.correctSumY+d.y;
};
2 => {
IF p.correctSumX#0 THEN {
spx: REAL = d.x*p.correctSpaceX/p.correctSumX;
p.correctSpaceX ← p.correctSpaceX-spx;
p.cpx ← p.cpx+spx;
};
IF p.correctSumY#0 THEN {
spy: REAL = d.y*p.correctSpaceY/p.correctSumY;
p.correctSpaceY ← p.correctSpaceY-spy;
p.cpy ← p.cpy+spy;
};
p.correctSumX ← p.correctSumX-d.x;
p.correctSumY ← p.correctSumY-d.y;
};
ENDCASE;
};
Correct: PUBLIC PROC[self: State] = {
IPExec.DoSimpleBody[self, save]; -- fix this
};
SetCorrectMeasure: PUBLIC PROC[self: State, v: Pair] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
p: PersistentVars = vars.p;
w: Pair = IPTransform.Tv[vars.T, v];
[p.correctMX, p.correctMY] ← w;
};
SetCorrectTolerance: PUBLIC PROC[self: State, v: Pair] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
np: NonPersistentVars = vars.np;
w: Pair = IPTransform.Tv[vars.T, v];
[np.correctTX, np.correctTY] ← w;
};
Space: PUBLIC PROC[self: State, x: REAL] = {
IPImagerOps.SetXRel[self, x];
CorrectSpace[self, [x, 0]];
};
END.