PathToBoxImpl.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Contents: Returns a bounding box of a Path.
Blair MacIntyre July 2, 1992 11:49 am PDT
DIRECTORY
Imager, ImagerBackdoor, ImagerBox, ImagerPath, ImagerScanConverter, PathToBox, Real, SF, Vector2;
PathToBoxImpl: CEDAR PROGRAM
IMPORTS ImagerBackdoor, ImagerBox, ImagerPath, ImagerScanConverter, Real
EXPORTS PathToBox
~ BEGIN OPEN PathToBox;
VEC: TYPE ~ Vector2.VEC;
PathToBox: PUBLIC PROC [context: Imager.Context, path: PathProc, precision: BoxPrecision ¬ device] RETURNS [box: Box] ~ {
PathBoundPoint: PROC [boxIn: Box, p: VEC] RETURNS [boxOut: Box] ~ {
width: REAL ¬ ImagerBackdoor.GetReal[context, strokeWidth];
newbox: Box ¬ [
xmin: p.x - Real.Ceiling[width/2],
xmax: p.x + Real.Ceiling[width/2],
ymin: p.y - Real.Ceiling[width/2],
ymax: p.y + Real.Ceiling[width/2]];
boxOut ¬ ImagerBox.BoundingBox[boxIn, newbox];
};
SELECT precision FROM
conic => {
p0: VEC ¬ [0, 0]; -- in path's coordinates, not transformed
first: BOOL ¬ TRUE;
ConicBoxMoveTo: PROC [p: VEC] ~ {
IF first THEN { first ¬ FALSE; box ¬ [p.x, p.y, p.x, p.y]; };
box ¬ PathBoundPoint[box, p];
p0 ¬ p;
};
ConicBoxLineTo: PROC [p1: VEC] ~ {
IF first THEN ConicBoxMoveTo[p0] ELSE box ¬ PathBoundPoint[box, p0];
box ¬ PathBoundPoint[box, p1];
p0 ¬ p1;
};
ConicBoxCurveTo: PROC [p1, p2, p3: VEC] ~ {
IF first THEN ConicBoxMoveTo[p0] ELSE box ¬ PathBoundPoint[box, p0];
box ¬ PathBoundPoint[box, p1];
box ¬ PathBoundPoint[box, p2];
box ¬ PathBoundPoint[box, p3];
p0 ¬ p3;
};
ConicBoxConicTo: PROC [p1, p2: VEC, r: REAL] ~ {
IF first THEN ConicBoxMoveTo[p0] ELSE box ¬ PathBoundPoint[box, p0];
box ¬ PathBoundPoint[box, p1];
box ¬ PathBoundPoint[box, p2];
p0 ¬ p2;
};
ConicBoxArcTo: PROC [p1, p2: VEC] ~ {
IF first THEN ConicBoxMoveTo[p0];
ImagerPath.ArcToConics[p0, p1, p2, ConicBoxConicTo];
p0 ¬ p2;
};
box ¬ [0,0,0,0];
path[moveTo: ConicBoxMoveTo, lineTo: ConicBoxLineTo, curveTo: ConicBoxCurveTo, conicTo: ConicBoxConicTo, arcTo: ConicBoxArcTo];
};
curve => {
p0: VEC ¬ [0, 0]; -- in path's coordinates, not transformed
first: BOOL ¬ TRUE;
CurveBoxMoveTo: PROC [p: VEC] ~ {
IF first THEN { first ¬ FALSE; box ¬ [p.x, p.y, p.x, p.y]; };
box ¬ PathBoundPoint[box, p];
p0 ¬ p;
};
CurveBoxLineTo: PROC [p1: VEC] ~ {
IF first THEN CurveBoxMoveTo[p0] ELSE box ¬ PathBoundPoint[box, p0];
box ¬ PathBoundPoint[box, p1];
p0 ¬ p1;
};
CurveBoxCurveTo: PROC [p1, p2, p3: VEC] ~ {
IF first THEN CurveBoxMoveTo[p0] ELSE box ¬ PathBoundPoint[box, p0];
box ¬ PathBoundPoint[box, p1];
box ¬ PathBoundPoint[box, p2];
box ¬ PathBoundPoint[box, p3];
p0 ¬ p3;
};
CurveBoxConicTo: PROC [p1, p2: VEC, r: REAL] ~ {
IF first THEN CurveBoxMoveTo[p0];
ImagerPath.ConicToCurves[p0, p1, p2, r, CurveBoxCurveTo];
p0 ¬ p2;
};
CurveBoxArcTo: PROC [p1, p2: VEC] ~ {
IF first THEN CurveBoxMoveTo[p0];
ImagerPath.ArcToConics[p0, p1, p2, CurveBoxConicTo];
p0 ¬ p2;
};
box ¬ [0,0,0,0];
path[moveTo: CurveBoxMoveTo, lineTo: CurveBoxLineTo, curveTo: CurveBoxCurveTo, conicTo: CurveBoxConicTo, arcTo: CurveBoxArcTo];
};
device => {
sfBox: SF.Box;
devicePath: ImagerScanConverter.DevicePath ¬ ImagerScanConverter.Create[];
ImagerScanConverter.SetPath[devicePath, path];
sfBox ¬ ImagerScanConverter.BoundingBox[devicePath];
box.xmin ¬ sfBox.min.f;
box.ymin ¬ sfBox.min.s;
box.xmax ¬ sfBox.max.f;
box.ymax ¬ sfBox.max.s;
};
ENDCASE;
};
END.