IPMaskImpl.mesa
Last edited by:
Doug Wyatt, April 26, 1983 2:12 pm
DIRECTORY
CGArea, CGClipper, CGContext, CGDevice, CGReducer,
Graphics USING [Box, SetColor],
IPBasic USING [Integer],
IPCubic USING [Flat, Split],
IPErrors USING [AppearanceWarning],
IPGeometry USING [MapOutline, MapTrajectory],
IPImager USING [Imager, Vars],
IPImagerOps USING [GetCP, SetXY, Trans],
IPImagerBasic USING [Bezier, ConstantColor, Outline, Pair, PixelArray, StrokeEnds, Trajectory, Transformation],
IPOutput USING [Show],
IPScan USING [PopPath, PushPath, ScanConvert],
IPState USING [State, StateRep],
IPStroke USING [GenerateStroke],
IPTransform USING [Transform, TransformVec];
IPMaskImpl: CEDAR PROGRAM
IMPORTS CGArea, CGClipper, CGReducer, Graphics, IPCubic, IPErrors, IPGeometry, IPImagerOps, IPOutput, IPScan, IPStroke, IPTransform
EXPORTS IPImagerOps, IPBasic
= BEGIN OPEN IPImagerBasic, IPBasic;
State: TYPE = IPState.State;
StateRep: PUBLIC TYPE = IPState.StateRep; -- export to IPBasic
Imager: TYPE = IPImager.Imager;
Vars: TYPE = IPImager.Vars;
SetColor: PROC[imager: Imager] = INLINE {
icolor: ConstantColor = NARROW[imager.vars.color];
Graphics.SetColor[imager.context, [r: icolor.r/256, g: icolor.g/256, b: icolor.b/256]];
};
useScanConverter: BOOLTRUE;
CGMaskFill: PROC[imager: Imager, o: Outline] = {
vars: Vars = imager.vars;
T: Transformation = vars.T;
d: CGContext.Ref = NARROW[imager.context.data];
reducer: CGReducer.Ref = d.reducer;
area: CGArea.Ref = d.area;
device: CGDevice.Ref = d.device;
lp: Pair;
started: BOOLFALSE;
Move: PROC[v: Pair] = {
IF started THEN Close[] ELSE started ← TRUE;
Line[v];
};
Line: PROC[v: Pair] = {
IF NOT started THEN ERROR;
CGReducer.Vertex[reducer, [v.x, v.y]]; lp ← v;
};
Curve: PROC[v1, v2, v3: Pair] = {
eps: REAL = 1.5;
maxdepth: NAT = 10;
Divide: PROC[b: Bezier, depth: NAT ← 0] = {
IF depth>=maxdepth OR IPCubic.Flat[b, eps] THEN Line[b.b3]
ELSE { b1, b2: Bezier; [b1, b2] ← IPCubic.Split[b];
Divide[b1, depth+1]; Divide[b2, depth+1] };
};
Divide[[lp, v1, v2, v3]];
};
Close: PROC = { CGReducer.Close[reducer] };
SetColor[imager];
CGClipper.Load[d.clipper, reducer];
IPGeometry.MapOutline[o, vars.T, Move, Line, Curve];
IF started THEN Close[];
CGReducer.Generate[reducer, area];
IF NOT CGArea.Empty[area] THEN device.Show[device, area, d.src, NIL];
};
IPMaskFill: PROC[imager: Imager, o: Outline] = {
vars: Vars = imager.vars;
T: Transformation = vars.T;
Gen: PROC[move: PROC[Pair], line: PROC[Pair], curve: PROC[Pair, Pair, Pair]] = {
IPGeometry.MapOutline[o, T, move, line, curve];
};
Out: PROC[rect: PROC[x, y, w, h: INTEGER]] = {
IPScan.ScanConvert[imager.path, rect];
};
IPScan.PushPath[imager.path, Gen];
imager.output.Show[vars.color, Out];
IPScan.PopPath[imager.path];
};
MaskFill: PUBLIC PROC[self: State, o: Outline] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
IF vars.np.noImage=0 THEN {
IF useScanConverter THEN IPMaskFill[imager, o]
ELSE CGMaskFill[imager, o];
};
};
MaskRectangle: PUBLIC PROC[self: State, x, y, w, h: REAL] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
IF vars.np.noImage=0 THEN {
-- imager.procs.MaskRectangle[imager, x, y, w, h]; --
T: Transformation = vars.T;
SetColor[imager];
IF T.code<10 THEN {
d: CGContext.Ref = NARROW[imager.context.data];
box: Graphics.Box;
p: Pair = IPTransform.Transform[T, [x, y]];
v: Pair = IPTransform.TransformVec[T, [w, h]];
IF v.x<0 THEN { box.xmin ← p.x+v.x; box.xmax ← p.x }
ELSE { box.xmin ← p.x; box.xmax ← p.x+v.x };
IF v.y<0 THEN { box.ymin ← p.y+v.y; box.ymax ← p.y }
ELSE { box.ymin ← p.y; box.ymax ← p.y+v.y };
CGClipper.GenerateBox[d.clipper, box, d.reducer, d.area];
IF NOT CGArea.Empty[d.area] THEN d.device.Show[d.device, d.area, d.src, NIL];
}
ELSE {
Gen: PROC[move: PROC[Pair], line: PROC[Pair], curve: PROC[Pair, Pair, Pair]] = {
move[IPTransform.Transform[T, [x, y]]];
line[IPTransform.Transform[T, [x+w, y]]];
line[IPTransform.Transform[T, [x+w, y+h]]];
line[IPTransform.Transform[T, [x, y+h]]];
};
Out: PROC[rect: PROC[x, y, w, h: INTEGER]] = {
IPScan.ScanConvert[imager.path, rect];
};
IPScan.PushPath[imager.path, Gen];
imager.output.Show[vars.color, Out];
IPScan.PopPath[imager.path];
};
};
};
GenStroke: PROC[imager: Imager,
gen: PROC[move: PROC[Pair], line: PROC[Pair], curve: PROC[Pair, Pair, Pair]],
closed: BOOLFALSE] = {
vars: Vars = imager.vars;
ends: StrokeEnds = (SELECT vars.np.strokeEnd FROM
0 => square, 1 => butt, 2 => round, ENDCASE => square);
d: CGContext.Ref = NARROW[imager.context.data];
reducer: CGReducer.Ref = d.reducer;
area: CGArea.Ref = d.area;
device: CGDevice.Ref = d.device;
started: BOOLFALSE;
Move: PROC[v: Pair] = {
IF started THEN Close[] ELSE started ← TRUE;
Line[v];
};
Line: PROC[v: Pair] = {
IF NOT started THEN ERROR;
CGReducer.Vertex[reducer, [v.x, v.y]];
};
Curve: PROC[v1, v2, v3: Pair] = {
ERROR;
};
Close: PROC = { CGReducer.Close[reducer] };
SetColor[imager];
CGClipper.Load[d.clipper, reducer];
IPStroke.GenerateStroke[gen, vars.T, vars.np.strokeWidth, closed, ends,
Move, Line, Curve];
IF started THEN Close[];
CGReducer.Generate[reducer, area];
IF NOT CGArea.Empty[area] THEN device.Show[device, area, d.src, NIL];
};
MaskStroke: PUBLIC PROC[self: State, t: Trajectory, closed: BOOLFALSE] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
IF vars.np.noImage=0 THEN {
Gen: PROC[move: PROC[Pair], line: PROC[Pair], curve: PROC[Pair, Pair, Pair]] = {
IPGeometry.MapTrajectory[t, NIL, move, line, curve] };
GenStroke[imager, Gen, closed];
};
};
MaskVector: PUBLIC PROC[self: State, p1, p2: Pair] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
IF vars.np.noImage=0 THEN {
Gen: PROC[move: PROC[Pair], line: PROC[Pair], curve: PROC[Pair, Pair, Pair]] = {
move[p1]; line[p2] };
GenStroke[imager, Gen];
};
};
MaskTrapezoidX: PUBLIC PROC[self: State, x1, y1, x2, x3, y3, x4: REAL] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
IF vars.np.noImage=0 THEN
SIGNAL IPErrors.AppearanceWarning[Unimplemented];
};
MaskTrapezoidY: PUBLIC PROC[self: State, x1, y1, y2, x3, y3, y4: REAL] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
IF vars.np.noImage=0 THEN
SIGNAL IPErrors.AppearanceWarning[Unimplemented];
};
StartUnderline: PUBLIC PROC[self: State] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
p: Pair = IPImagerOps.GetCP[self];
vars.np.underlineStart ← p.x;
};
MaskUnderline: PUBLIC PROC[self: State, dy, h: REAL] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
IF vars.np.noImage=0 THEN {
cpx: REAL = vars.p.cpx; cpy: REAL = vars.p.cpy; -- save cp and translation
tc: REAL = vars.T.c; tf: REAL = vars.T.f;
p: Pair = IPImagerOps.GetCP[self]; -- current position, master coordinates
x: REAL = vars.np.underlineStart; -- x of rectangle
y: REAL = p.y-dy-h; -- y of rectangle
w: REAL = p.x-x; -- width of rectangle
IPImagerOps.SetXY[self, [x, y]]; IPImagerOps.Trans[self];
MaskRectangle[self, 0, 0, w, h];
vars.p.cpx ← cpx; vars.p.cpy ← cpy; -- restore cp and translation
vars.T.c ← tc; vars.T.f ← tf;
};
};
MaskPixel: PUBLIC PROC[self: State, pa: PixelArray] = {
imager: Imager = self.imager;
vars: Vars = imager.vars;
IF vars.np.noImage=0 THEN
SIGNAL IPErrors.AppearanceWarning[Unimplemented];
};
END.