G2dOutlineImpl.mesa
Copyright Ó 1987, 1992 by Xerox Corporation. All rights reserved.
Loosely based on Michael Plass's /Ivy/Plass/Overnight/RefitImpl.mesa.
Bloomenthal, July 2, 1992 5:16 pm PDT
Michael Plass, September 19, 1989 9:56:25 am PDT
DIRECTORY G2dOutline, Imager, ImagerBackdoor, ImagerColor, ImagerDevice, ImagerFont, ImagerPath, ImagerPrivate, ImagerRaster, ImagerTransformation, Rope, SF, TextNode, TiogaAccess, TiogaImager, Vector2;
G2dOutlineImpl: CEDAR PROGRAM
IMPORTS Imager, ImagerDevice, ImagerBackdoor, ImagerPath, ImagerRaster, TiogaAccess, TiogaImager
EXPORTS G2dOutline
~ BEGIN
Types and Constants
TransformProc:  TYPE ~ G2dOutline.TransformProc;
Context:  TYPE ~ Imager.Context;
Color:  TYPE ~ ImagerColor.Color;
Device:    TYPE ~ ImagerDevice.Device;
Font:  TYPE ~ ImagerFont.Font;
PathProc:  TYPE ~ ImagerPath.PathProc;
Outline:  TYPE ~ ImagerPath.Outline;
Transformation: TYPE ~ ImagerTransformation.Transformation;
ROPE:  TYPE ~ Rope.ROPE;
Reader:     TYPE ~ TiogaAccess.Reader;
FormattedNodes: TYPE ~ TiogaImager.FormattedNodes;
VEC:  TYPE ~ Vector2.VEC;
Procedures to Manipulate Imager Outlines
[Artwork node; type 'Artwork on' to command tool]
TransformSelected: PUBLIC PROC [
reader: Reader,
action: TransformProc,
context: Context,
epsilon: REAL ¬ 0.05,
clientData: REF ANY ¬ NIL]
~ {
IF reader # NIL THEN {
loc: TextNode.Location ¬ [NARROW[TiogaAccess.GetLocation[reader].node], 0];
IF loc.node # NIL THEN {
nodes: FormattedNodes ¬ TiogaImager.FormatNodes[loc, [1000, 1000]];
IF nodes.box # NIL THEN {
transformContext: Context ¬ MakeTransformContext[action, context, clientData];
TiogaImager.Render[nodes.box, transformContext, [0, 0]];
};
};
};
};
TransformRope: PUBLIC PROC [
text: ROPE,
action: TransformProc,
context: Context,
x, y: REAL ¬ 0.0,
font: Font ¬ NIL,
color: Color ¬ NIL,
epsilon: REAL ¬ 0.05,
clientData: REF ANY ¬ NIL]
~ {
transformContext: Context ¬ MakeTransformContext[action, context, clientData];
Imager.SetXY[transformContext, [x, y]];
IF font # NIL THEN Imager.SetFont[transformContext, font];
IF color # NIL THEN Imager.SetColor[transformContext, color];
Imager.ShowRope[transformContext, text];
};
Getting an Imager Context
TransformData: TYPE ~ RECORD [
action:     TransformProc,
clientContext:   Context,
clientData:    REF ANY
];
MakeTransformContext: PUBLIC PROC [
action: TransformProc,
clientContext: Context,
clientData: REF ANY]
RETURNS [Context]
~ {
d: REF TransformData ¬ NEW[TransformData ¬ [action, clientContext, clientData]];
RETURN[ImagerRaster.Create[class: transformClass, deviceClass: deviceClass, deviceParm: deviceParm, data: d, pixelUnits: TRUE]];
Imager.ScaleT[c, 1.0]; -- to increase resolution?
};
NullMaskBoxes: PROC [device: Device, bounds: SF.Box, boxes: SF.BoxGenerator] ~ {};
NullSetColor: PROC [device: Device, color: Color, viewToDevice: Transformation]~{};
deviceClass: ImagerDevice.DeviceClass ~ NEW[ImagerDevice.DeviceClassRep ¬[SetColor: NullSetColor, MaskBoxes: NullMaskBoxes]];
deviceParm: ImagerDevice.DeviceParm ~ ImagerDevice.MakeDeviceParm[
class: deviceClass,
sSize: 1,
fSize: 1,
scanMode: [slow: down, fast: right],
surfaceUnitsPerInch: [1, 1],
surfaceUnitsPerPixel: 1,
fontCache: NIL
];
transformClass: ImagerPrivate.Class ¬ MakeTransformClass[];
MakeTransformClass: PROC RETURNS [class: ImagerPrivate.Class] ~ {
class ¬ ImagerRaster.CreateClass[type: $Transform];
class.MaskFill ¬ TransformPath;
class.MaskStroke ¬ TransformMaskStroke;
};
Transforming
TransformMaskStroke: PROC [context: Context, path: PathProc, closed: BOOL] ~ {
TransformPath[context, path, FALSE];
};
TransformPath: PROC [context: Context, path: PathProc, oddWrap: BOOL] ~ {
d: REF TransformData ¬ NARROW[ImagerRaster.GetDevice[context].data];
matrix: Transformation ¬ ImagerBackdoor.GetT[context];
in: Outline ¬ ImagerPath.OutlineFromPath[path, oddWrap, matrix];
out: Outline ¬ DoOutline[in, d.action, d.clientData];
Imager.MaskFillOutline[d.clientContext, out];
};
DoOutline: PROC [in: Outline, action: TransformProc, clientData: REF ANY]
RETURNS [out: Outline]
~ {
Path: PathProc ~ {ImagerPath.MapOutline[in, moveTo, lineTo, curveTo, conicTo, arcTo]};
Close: PROC ~ {
IF trajectory # NIL AND fp # lp THEN Line[fp];
trajectories ¬ CONS[trajectory, trajectories];
trajectory ¬ NIL;
};
Move: PROC [p: VEC] ~ {
IF trajectory # NIL THEN Close[];
fp ¬ lp ¬ p;
trajectory ¬ ImagerPath.MoveTo[action[p, clientData]];
};
Line: PROC [p1: VEC] ~ {
IF lp # p1 THEN {
lp ¬ p1;
trajectory ¬ ImagerPath.LineTo[trajectory, action[p1, clientData]];
};
};
Curve: PROC [p1, p2, p3: VEC] ~ {
lp ¬ p3;
trajectory ¬ ImagerPath.CurveTo[
trajectory, action[p1, clientData], action[p2, clientData], action[p3, clientData]];
};
fp, lp: VEC ¬ [0, 0];
trajectory: ImagerPath.Trajectory ¬ NIL;
trajectories: ImagerPath.TrajectoryList ¬ NIL;
ImagerPath.Transform[path: Path, moveTo: Move, lineTo: Line, curveTo: Curve];
IF trajectory # NIL THEN Close[];
out ¬ NEW[ImagerPath.OutlineRep[in.size]];
out.oddWrap ¬ in.oddWrap;
FOR i: NAT IN [0..out.size) DO
out[i] ¬ trajectories.first;
trajectories ¬ trajectories.rest;
ENDLOOP;
};
END.