<> <> <> <> <> DIRECTORY Draw2d, GGBasicTypes, GGCaret, GGInterfaceTypes, GGLines, GGModelTypes, GGShapes, GGVector, Imager, ImagerBackdoor, ImagerTransformation, Real; GGShapesImpl: CEDAR PROGRAM IMPORTS Draw2d, GGLines, GGVector, Imager, ImagerBackdoor, Real EXPORTS GGShapes = BEGIN bitmapSize: INTEGER = 16; bitmapRange: TYPE = [0..bitmapSize); bitmapArray: TYPE = ARRAY bitmapRange OF CARDINAL; anchorBits: REF bitmapArray _ NEW[bitmapArray _ [ 1700B, 140603B, 177777B, 177777B, 177777B, 140603B, 600B, 600B, 600B, 600B, 100601B,140603B, 160607B, 177777B, 77776B, 37774B ]]; anchorBits2: REF bitmapArray _ NEW[bitmapArray _ [ 176077B, 163147B, 170017B, 134035B, 117771B, 146063B, 044022B, 004020B, 004020B, 044022B, 146063B, 117771B, 134035B, 170017B, 163147B, 176077B ]]; caretBits: REF bitmapArray _ NEW[bitmapArray _ [ 030000B, 030000B, 030000B, 044000B, 044000B, 102000B, 102000B, 102000B, 0, 0, 0, 0, 0, 0, 0, 0 ]]; jointBits: REF bitmapArray _ NEW[bitmapArray _ [ 176000B, 102000B, 132000B, 132000B, 102000B, 176000B, 0, 0, 125252B, 125252B, 125252B, 125252B, 125252B, 125252B, 125252B, 125252B ]]; cpBits: REF bitmapArray _ NEW[bitmapArray _ [ 176000B, 102000B, 102000B, 102000B, 102000B, 176000B, 0, 0, 125252B, 125252B, 125252B, 125252B, 125252B, 125252B, 125252B, 125252B ]]; normalBits: REF bitmapArray _ NEW[bitmapArray _ [ 176000B, 176000B, 176000B, 176000B, 176000B, 176000B, 0, 0, 125252B, 125252B, 125252B, 125252B, 125252B, 125252B, 125252B, 125252B ]]; hotBits: REF bitmapArray _ NEW[bitmapArray _ [ 177700B, 100100B, 100100B, 100100B, 100100B, 100100B, 100100B, 100100B, 100100B, 177700B, 0, 0, 125252B, 125252B, 125252B, 125252B ]]; Circle: TYPE = GGBasicTypes.Circle; Line: TYPE = GGBasicTypes.Line; Point: TYPE = GGBasicTypes.Point; Ray: TYPE = GGBasicTypes.Ray; Vector: TYPE = GGBasicTypes.Vector; SelectionClass: TYPE = GGInterfaceTypes.SelectionClass; jointSize: INTEGER = Real.RoundI[GGModelTypes.jointSize]; halfJointSize: REAL = GGModelTypes.halfJointSize; hotJointSize: INTEGER = Real.RoundI[GGModelTypes.hotJointSize]; halfHotJointSize: REAL = GGModelTypes.halfHotJointSize; DrawSquare: PUBLIC PROC [dc: Imager.Context, center: Point, side: REAL, strokeWidth: REAL _ 1.0] = { halfSide: REAL _ side/2.0; DoDrawSquare: PROC = { SquarePath: Imager.PathProc = { moveTo[[- halfSide, - halfSide]]; lineTo[[- halfSide, halfSide]]; lineTo[[ halfSide, halfSide]]; lineTo[[ halfSide, - halfSide]]; lineTo[[- halfSide, - halfSide]]; }; Imager.SetXY[dc, [center.x, center.y]]; Imager.Trans[dc]; Imager.SetStrokeWidth[dc, strokeWidth]; Imager.SetStrokeEnd[dc, round]; Imager.SetStrokeJoint[dc, round]; Imager.MaskStroke[dc, SquarePath, TRUE]; }; Imager.DoSaveAll[dc, DoDrawSquare]; }; DrawPlus: PUBLIC PROC [dc: Imager.Context, center: Point] = { halfSide: REAL = 5.0; DoDrawPlus: PROC = { Horiz: Imager.PathProc = { moveTo[[-halfSide, 0.0]]; lineTo[[halfSide, 0.0]]; }; Vert: Imager.PathProc = { moveTo[[0.0, -halfSide]]; lineTo[[0.0, halfSide]]; }; Imager.SetXY[dc, [center.x, center.y]]; Imager.Trans[dc]; Imager.SetStrokeWidth[dc, 2.0]; Imager.SetStrokeEnd[dc, round]; Imager.MaskStroke[dc, Horiz, FALSE]; Imager.MaskStroke[dc, Vert, FALSE]; }; Imager.DoSaveAll[dc, DoDrawPlus]; }; DrawRectangle: PUBLIC PROC [dc: Imager.Context, loX, loY, hiX, hiY: REAL, strokeWidth: REAL _ 1.0] = { <> DoDrawRect: PROC = { RectanglePath: Imager.PathProc = { moveTo[[loX, loY]]; lineTo[[loX, hiY]]; lineTo[[ hiX, hiY]]; lineTo[[ hiX, loY]]; lineTo[[loX, loY]]; }; Imager.SetStrokeWidth[dc, strokeWidth]; Imager.SetStrokeEnd[dc, round]; Imager.SetStrokeJoint[dc, round]; Imager.MaskStroke[dc, RectanglePath, TRUE]; }; Imager.DoSaveAll[dc, DoDrawRect]; }; DrawCaret: PUBLIC PROC [dc: Imager.Context, point: Point] = { halfWidth: REAL = GGCaret.caretWidth/2.0; DoDrawCaret: PROC = { Imager.MaskBits[context: dc, base: LOOPHOLE[caretBits], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: 8, fSize: 6 , tx: Real.RoundI[point.x-halfWidth], ty: Real.RoundI[point.y] ]; }; Imager.DoSaveAll[dc, DoDrawCaret]; }; DrawAnchor: PUBLIC PROC [dc: Imager.Context, point: Point] = TRUSTED { halfHeight: REAL = GGCaret.anchorHeight/2.0; halfWidth: REAL = GGCaret.anchorWidth/2.0; DoDrawAnchor: PROC = TRUSTED { Imager.MaskBits[context: dc, base: LOOPHOLE[anchorBits2], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: 16, fSize: 16 , tx: Real.RoundI[point.x-halfWidth], ty: Real.RoundI[point.y+halfHeight] ]; }; Imager.DoSaveAll[dc, DoDrawAnchor]; }; DrawFilledSquare: PROC [dc: Imager.Context, center: Point, side: REAL] = { halfSide: REAL _ side/2.0; DoDrawFilledSquare: PROC = { Imager.SetXY[dc, [center.x, center.y]]; -- set the current position Imager.Trans[dc]; <> Imager.SetColor[dc, Imager.black]; Imager.MaskRectangle[dc, [- halfSide, - halfSide, side, side]]; }; Imager.DoSaveAll[dc, DoDrawFilledSquare]; }; DrawEmptySquare: PROC [dc: Imager.Context, center: Point, side: REAL] = { halfSide: REAL _ side/2.0; DoDrawEmptySquare: PROC = { Imager.SetXY[dc, [center.x, center.y]]; -- set the current position Imager.Trans[dc]; <> Imager.SetColor[dc, Imager.black]; Imager.MaskRectangle[dc, [- halfSide, - halfSide, side, side]]; Imager.SetColor[dc, Imager.white]; Imager.MaskRectangle[dc, [- halfSide+1, - halfSide+1, side-2, side-2]]; }; Imager.DoSaveAll[dc, DoDrawEmptySquare]; }; DrawSpot: PUBLIC PROC [dc: Imager.Context, point: Point] = { DoDrawSpot: PROC = { Imager.SetXY[dc, [point.x, point.y]]; Imager.Trans[dc]; Imager.MaskRectangle[dc, [0.0, 0.0, 1.0, 1.0]]; }; Imager.DoSaveAll[dc, DoDrawSpot]; }; DrawFilledRect: PUBLIC PROC [dc: Imager.Context, point: Point, side: REAL] = { DoDrawRect: PROC = { Imager.SetXY[dc, [point.x, point.y]]; Imager.Trans[dc]; Imager.MaskRectangle[dc, [0.0, 0.0, side, side]]; }; Imager.DoSaveAll[dc, DoDrawRect]; }; DrawLine: PUBLIC PROC [dc: Imager.Context, line: Line, clippedBy: ImagerTransformation.Rectangle, strokeWidth: REAL _ 1.0] = { count: NAT; ray: Ray; params: ARRAY[1..2] OF REAL; p1, p2, basePoint: Point; direction: Vector; DoDrawLine: PROC = { Imager.SetXY[dc, [p1.x, p1.y]]; <> Imager.Move[dc]; Imager.SetStrokeEnd[dc, round]; Imager.SetStrokeWidth[dc, strokeWidth]; <> Draw2d.Line[dc, [0.0, 0.0], [p2.x - p1.x, p2.y - p1.y], solid]; }; p1 _ [clippedBy.x, clippedBy.y]; p2 _ [clippedBy.x + clippedBy.w, clippedBy.y + clippedBy.h]; basePoint _ GGLines.PointOnLine[line]; direction _ GGLines.DirectionOfLine[line]; ray _ GGLines.CreateRay[basePoint, direction]; [count, params] _ GGLines.LineRayMeetsBox[ray, p1.x, p1.y, p2.x, p2.y]; IF count = 2 THEN { p1 _ GGLines.EvalRay[ray, params[1]]; p2 _ GGLines.EvalRay[ray, params[2]]; Imager.DoSaveAll[dc, DoDrawLine]; }; }; DrawLittleLine: PUBLIC PROC [dc: Imager.Context, line: Line, point: Point] = { <> }; DrawCircle: PUBLIC PROC [dc: Imager.Context, circle: Circle] = { leftSide, rightSide: Point; DoDrawCircle: PROC = { CirclePath: Imager.PathProc = { moveTo[[leftSide.x, leftSide.y]]; arcTo[[rightSide.x, rightSide.y], [ leftSide.x, leftSide.y]]; }; Imager.SetStrokeWidth[dc, 1.0]; Imager.SetStrokeEnd[dc, round]; Imager.MaskStroke[dc, CirclePath, TRUE]; }; leftSide _ [circle.origin.x - circle.radius, circle.origin.y]; rightSide _ [circle.origin.x + circle.radius, circle.origin.y]; Imager.DoSaveAll[dc, DoDrawCircle]; }; useBitmaps: BOOL _ FALSE; -- KAP. October 13, 1986 DrawCP: PUBLIC PROC [dc: Imager.Context, point: Point] = { IF useBitmaps THEN ImagerBackdoor.DrawBits[context: dc, base: LOOPHOLE[cpBits], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: jointSize, fSize: jointSize, tx: Real.RoundI[point.x-halfJointSize], ty: Real.RoundI[point.y+halfJointSize] ] ELSE DrawEmptySquare[dc, point, jointSize]; }; DrawJoint: PUBLIC PROC [dc: Imager.Context, point: Point] = { IF useBitmaps THEN ImagerBackdoor.DrawBits[context: dc, base: LOOPHOLE[jointBits], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: jointSize, fSize: jointSize , tx: Real.RoundI[point.x-halfJointSize], ty: Real.RoundI[point.y+halfJointSize] ] ELSE { DrawEmptySquare[dc, point, jointSize]; DrawFilledSquare[dc, point, 2.0]; }; }; DrawSelectedJoint: PUBLIC PROC [dc: Imager.Context, point: Point, selectClass: SelectionClass] = { IF useBitmaps THEN IF selectClass=hot THEN ImagerBackdoor.DrawBits[context: dc, base: LOOPHOLE[hotBits], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: hotJointSize, fSize: hotJointSize , tx: Real.RoundI[point.x-halfHotJointSize], ty: Real.RoundI[point.y+halfHotJointSize] ] ELSE IF selectClass=normal THEN ImagerBackdoor.DrawBits[context: dc, base: LOOPHOLE[normalBits], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: jointSize, fSize: jointSize, tx: Real.RoundI[point.x-halfJointSize], ty: Real.RoundI[point.y+halfJointSize] ] ELSE ImagerBackdoor.DrawBits[context: dc, base: LOOPHOLE[jointBits], wordsPerLine: 1, sMin: 0, fMin: 0, sSize: jointSize, fSize: jointSize , tx: Real.RoundI[point.x-halfJointSize], ty: Real.RoundI[point.y+halfJointSize] ] ELSE IF selectClass=hot THEN DrawEmptySquare[dc, point, hotJointSize] ELSE IF selectClass=normal THEN DrawFilledSquare[dc, point, jointSize] ELSE {DrawEmptySquare[dc, point, jointSize]; DrawFilledSquare[dc, point, 2.0]}; }; DrawArrow: PUBLIC PROC [dc: Imager.Context, tip: Point, base: Point, strokeWidth: REAL] = { OPEN GGVector; DrawArrowAux: Imager.PathProc = { moveTo[tip]; lineTo[Sub[tip, Add[Scale[axis, height], Scale[perp, halfWidth]]]]; lineTo[Sub[tip, Add[Scale[axis, height], Scale[perp, -halfWidth]]]]; lineTo[tip]; }; axis: Vector; perp: Vector; height: REAL _ strokeWidth+5.0; halfWidth: REAL _ strokeWidth+3.0; IF tip = base THEN RETURN; axis _ GGVector.Normalize[GGVector.Sub[tip, base]]; perp _ [axis.y, -axis.x]; Imager.MaskFill[context: dc, path: DrawArrowAux, parity: FALSE] }; ArrowSize: PUBLIC PROC [strokeWidth: REAL] RETURNS [height, halfWidth: REAL] = { <> height _ strokeWidth+5.0; halfWidth _ strokeWidth+3.0; }; END.