DIRECTORY GGBasicTypes, Imager, ImagerPath, ImagerTransformation, IO, Rope; GGSegmentTypes: CEDAR DEFINITIONS = BEGIN StrokeEnd: TYPE = Imager.StrokeEnd; -- TYPE = {square, butt, round} StrokeJoint: TYPE = Imager.StrokeJoint; -- TYPE = {miter, bevel, round} BitVector: TYPE = GGBasicTypes.BitVector; BoundBox: TYPE = GGBasicTypes.BoundBox; Circle: TYPE = GGBasicTypes.Circle; Line: TYPE = GGBasicTypes.Line; Point: TYPE = GGBasicTypes.Point; SequenceOfReal: TYPE = GGBasicTypes.SequenceOfReal; Vector: TYPE = GGBasicTypes.Vector; Joint: TYPE = REF JointObj; JointObj: TYPE = RECORD [ point: Point, TselectedInFull: SelectedObjectData, -- T is for "temporary" touchItem: TouchItem ]; Segment: TYPE = REF SegmentObj; SegmentObj: TYPE = RECORD [ class: SegmentClass, looks: Rope.ROPE, -- may be used later for the style machinery strokeWidth: REAL _ 1.0, strokeEnd: StrokeEnd _ round, dashed: BOOL _ FALSE, pattern: SequenceOfReal, offset: REAL _ 0.0, length: REAL _ -1.0, -- dashed stroke properties color: Imager.Color, lo, hi: Point, hiTan, loTan: Point _ [0,0], --[0,0] is the undefined value for the tangents. TselectedInFull: SelectedObjectData, -- T is for "temporary" bBox: BoundBox, touchItemList: LIST OF TouchItem, data: REF ANY, props: LIST OF REF ANY ]; SegmentClass: TYPE = REF SegmentClassObj; SegmentClassObj: TYPE = RECORD [ type: ATOM, boundBox: BoundBoxProc, tightBox: TightBoxProc, copyData: CopyDataProc, reverse: ReverseProc, -- peculiar to segments buildPath: BuildPathProc, buildPathTransform: BuildPathTransformProc, transform: TransformProc, endPointMoved: EndPointMovedProc, -- peculiar to segments controlPointMoved: ControlPointMovedProc, -- peculiar to segments describe: DescribeProc, fileOut: FileOutProc, fileIn: FileInProc, controlPointFieldSet: ControlPointFieldSetProc, controlPointFieldGet: ControlPointFieldGetProc, controlPointGet: ControlPointGetProc, controlPointCount: ControlPointCountProc, closestPoint: ClosestPointProc, closestControlPoint: ClosestControlPointProc, closestPointAndTangent: ClosestPointAndTangentProc, lineIntersection: LineIntersectionProc, circleIntersection: CircleIntersectionProc, asSimpleCurve: AsSimpleCurveProc, addJoint: AddJointProc, setStrokeWidth: SetStrokeWidthProc -- needed for bounding box updates ]; BoundBoxProc: TYPE = PROC [seg: Segment] RETURNS [bBox: BoundBox]; TightBoxProc: TYPE = PROC [seg: Segment] RETURNS [bBox: BoundBox]; CopyDataProc: TYPE = PROC [seg: Segment] RETURNS [data: REF ANY]; ReverseProc: TYPE = PROC [seg: Segment]; BuildPathProc: TYPE = PROC [seg: Segment, lineTo: ImagerPath.LineToProc, curveTo: ImagerPath.CurveToProc, conicTo: ImagerPath.ConicToProc, arcTo: ImagerPath.ArcToProc]; BuildPathTransformProc: TYPE = PROC [seg: Segment, transform: ImagerTransformation.Transformation, entire, lo, hi: BOOL, controlPoints: BitVector, lineTo: ImagerPath.LineToProc, curveTo: ImagerPath.CurveToProc, conicTo: ImagerPath.ConicToProc, arcTo: ImagerPath.ArcToProc]; TransformProc: TYPE = PROC [seg: Segment, transform: ImagerTransformation.Transformation]; EndPointMovedProc: TYPE = PROC [seg: Segment, lo: BOOL, newPoint: Point]; ControlPointMovedProc: TYPE = PROC [seg: Segment, transform: ImagerTransformation.Transformation, controlPointNum: NAT]; FileOutProc: TYPE = PROC [seg: Segment, f: IO.STREAM]; FileInProc: TYPE = PROC [f: IO.STREAM, loPoint, hiPoint: Point, version: REAL] RETURNS [seg: Segment]; DescribeProc: TYPE = PROC [seg: Segment, self, lo, hi: BOOL, cps: BitVector] RETURNS [rope: Rope.ROPE]; ControlPointFieldSetProc: TYPE = PROC [seg: Segment, controlPointNum: NAT, selected: BOOL, selectClass: SelectionClass]; ControlPointFieldGetProc: TYPE = PROC [seg: Segment, controlPointNum: NAT, selectClass: SelectionClass] RETURNS [selected: BOOL]; ControlPointGetProc: TYPE = PROC [seg: Segment, controlPointNum: NAT] RETURNS [point: Point]; ControlPointCountProc: TYPE = PROC [seg: Segment] RETURNS [controlPointCount: NAT]; ClosestPointProc: TYPE = PROC [seg: Segment, testPoint: Point, tolerance: REAL] RETURNS [point: Point, success: BOOL]; ClosestControlPointProc: TYPE = PROC [seg: Segment, testPoint: Point, tolerance: REAL] RETURNS [point: Point, controlPointNum: NAT, success: BOOL]; ClosestPointAndTangentProc: TYPE = PROC [seg: Segment, testPoint: Point, tolerance: REAL] RETURNS [point: Point, tangent: Vector, success: BOOL]; LineIntersectionProc: TYPE = PROC [seg: Segment, line: Line] RETURNS [points: LIST OF Point, pointCount: NAT]; CircleIntersectionProc: TYPE = PROC [seg: Segment, circle: Circle] RETURNS [points: LIST OF Point, pointCount: NAT]; AsSimpleCurveProc: TYPE = PROC [seg: Segment, point: Point] RETURNS [simpleCurve: REF ANY]; AddJointProc: TYPE = PROC [seg: Segment, pos: Point] RETURNS [seg1, seg2: Segment]; SetStrokeWidthProc: TYPE = PROC [seg: Segment, strokeWidth: REAL]; TouchGroup: TYPE = REF TouchGroupObj; TouchGroupObj: TYPE = RECORD [ list: LIST OF TouchItem, point: Point, updated: BOOL _ FALSE ]; TouchingPartType: TYPE = {joint, segment}; TouchItem: TYPE = REF TouchItemObj; TouchItemObj: TYPE = RECORD [ group: TouchGroup, traj: REF ANY, touchingPartType: TouchingPartType, joint: Joint, seg: Segment, segPoint: Point ]; SelectionClass: TYPE = {normal, hot, active}; SelectedObjectData: TYPE = RECORD [ normal: BOOL _ FALSE, hot: BOOL _ FALSE, active: BOOL _ FALSE ]; END. GGSegmentTypes.mesa Copyright c 1986 by Xerox Corporation. All rights reserved. Last edited by Bier on May 28, 1986 4:34:19 pm PDT Contents: Segments are parts of Trajectories, which are part of Outlines. Outline is a class of Slice. Segments include straight line segments, arcs, Bezier splines, conics, and so on. Each class of segment must know how to draw itself, how to change shape when its control points are moved, and how to compute its nearest point to a given test point. Fundamentals Drawing Transforming Textual Description Parts Part Generators Hit Testing Editing don't need class specific Set/Get of strokeEnd, strokeJoint, dashes, or colors Fundamentals Returns the geometric bounds for this segment. Allows extra space for control points, for control point size, for joint size and for stroke width. Returns the geometric bounds for this segment. Does NOT allow extra space for control points, for control point size, for joint size and for stroke width. Copies the data in the "data" field of seg. This data is class-dependent. The "lo" end and "hi" end have switched roles. Update data structures as necessary. Drawing Assume that the Imager's current point is at your lower joint. Call the procedures given to draw yourself (moveTo is left out -- you shouldn't need it). BuildPathTransformProc is to BuildPathProc what MaskStrokeTransformProc is to MaskStrokeProc. This is for rubberbanding filled areas. Transforming Apply the given transformation to all internal data of the segment. It is now in a new position, orientation, scaling, or skewing. Textual Description Describe yourself onto f. Make a new segment of this class. The segments endpoints are loPoint and hiPoint. Parts Part Generators Returns position of designated control point Returns total number of control points in segment Hit Testing Used for hit testing. Find the nearest point on seg to testPoint. If the nearest point is farther away than tolerance units, this procedure may opt to return success = FALSE. If a valid point is returned, then success = TRUE. Used for hit testing. Find the nearest control point of seg to testPoint. If the nearest point is farther away than tolerance units, this procedure may opt to return success = FALSE. If a valid point is returned, then success = TRUE. If there are no control points, success = FALSE. Used for hit testing. Find the nearest point on seg to testPoint and the tangent vector (towards hi end of segment) at that point. If the nearest point is farther away than tolerance units, this procedure may opt to return success = FALSE. If a valid point and tangent are returned, then success = TRUE. If you can be expressed easily as a straight Edge, a circular Arc, a Conic, or a Bezier piece, then return an Edge, Arc, Conic, or Bezier. Otherwise, return NIL. If you are made of several such pieces, return the one nearest to point. Editing Returns a new run which represents the old segment with a new joint edited in Changes the stroke width of the segment (and updates its bounding box). Touching: ΚΪ˜J˜codešœ™Kšœ<™Kšœ˜Kšœ˜K˜—Kšœ œœ ˜šœ œœ˜K˜Kšœ œŸ,˜>Kšœ œ˜Kšœ˜Kšœœœ˜Kšœ˜Kšœœ˜Kšœœ Ÿ˜0Kšœ˜K˜KšœŸ0˜MKšœ%Ÿ˜