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.
��t��GGShapesImpl.mesa
Author: Eric Bier on June 7, 1985 5:45:52 pm PDT
Last edited by Bier on January 14, 1987 2:42:41 pm PST
Contents: Predefined shapes for use in Gargoyle (e.g. squares for control points).
Pier, November 5, 1986 10:02:27 am PST
Draws the indicated rectangle (not filled).
Imager.Move[dc];   -- move the origin to the current position
Imager.Move[dc];   -- move the origin to the current position
Imager.Trans[dc];
Imager.MaskVector[dc, [0.0, 0.0], [p2.x - p1.x, p2.y - p1.y]];
Draw a short line (1 inch) centered on point, parallel to line.
The arrowhead will fit in a box of size height by (halfWidth*2).
Ê	®��˜�Icode™K™0K™6™RK™&—K˜�šÏk	˜	Kšœ˜K˜�—šÏnœœœ8˜[Kšœ˜—K˜�Kšœœ˜Kšœ
œ˜$Kš	œ
œœ
œœ˜2šœœœ˜2Kšœ!˜!Kšœ˜Kšœ˜Kšœ ˜ Kšœ˜—šœ
œœ˜3Kšœ#˜#Kšœ#˜#Kšœ#˜#Kšœ"˜"Kšœ˜—šœœœ˜1K˜GK˜Kšœ˜—K˜�šœœœ˜1Kšœ;˜;K˜#K˜#Kšœ˜—šœœœ˜.Kšœ;˜;K˜#K˜#Kšœ˜—šœœœ˜2Kšœ;˜;K˜#K˜#Kšœ˜—šœ	œœ˜/K˜#K˜$K˜K˜"Kšœ˜K˜�—Kšœœ˜#Kšœœ˜Kšœœ˜!Kšœœ˜Kšœœ˜#Kšœœ#˜7K˜�Kšœœ'˜9Kšœœ˜1Kšœœ*˜?Kšœœ!˜7K˜�š
ž
œœœ+œœ˜dKšœ
œ˜šžœœ˜šž
œ˜Kšœ!˜!Kšœ ˜ Kšœ˜Kšœ!˜!Kšœ"˜"K˜—Kšœ'˜'Kšœ˜Kšœ'˜'Kšœ˜Kšœ!˜!Kšœ"œ˜(K˜—Kšœ#˜#K˜K˜�—šžœœœ(˜=Kšœ
œ˜šž
œœ˜šžœ˜K˜Kšœ˜K˜—šžœ˜K˜Kšœ˜K˜—Kšœ'˜'Kšœ˜Kšœ˜Kšœ˜Kšœœ˜$Kšœœ˜#K˜—Kšœ!˜!K˜K˜�—š
ž
œœœ*œœ˜fK™+šž
œœ˜šž
œ˜"Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜K˜—Kšœ'˜'Kšœ˜Kšœ!˜!Kšœ%œ˜+K˜—Kšœ!˜!K˜�K˜K˜�—šž	œœœ'˜=Kšœœ˜)šžœœ˜Kšœ#œ…˜°K˜—Kšœ"˜"K˜K˜�—šž
œœœ&œ˜FKšœœ˜,Kšœœ˜*šžœœœ˜Kšœ#œ”˜¿K˜—Kšœ#˜#K˜K˜�—šžœœ+œ˜JKšœ
œ˜šžœœ˜Kšœ*Ïc˜EKšœ˜Kšœ=™=Kšœ"˜"Kšœ?˜?K˜—Kšœ)˜)K˜K˜�—šžœœ+œ˜Išœ
œ˜šžœœ˜Kšœ*Ÿ˜EKšœ˜Kšœ=™=Kšœ"˜"Kšœ?˜?K˜"KšœG˜GK˜——Kšœ(˜(K˜K˜�—šžœœœ'˜<šž
œœ˜Kšœ%˜%Kšœ˜Kšœ/˜/K˜—Kšœ!˜!K˜K˜�—šžœœœ*œ˜Nšž
œœ˜Kšœ%˜%Kšœ˜Kšœ1˜1K˜—Kšœ!˜!K˜K˜�—šžœœœZœ˜~Kšœœ˜K˜	Kšœœœœ˜Kšœ˜K˜šž
œœ˜Kšœ˜Kšœ™Kšœ˜Kšœ˜Kšœ'˜'Kšœ>™>Kšœ?˜?K˜—Kšœ ˜ Kšœ<˜<Kšœ&˜&Kšœ*˜*Kšœ.˜.KšœG˜Gšœœ˜Kšœ%˜%Kšœ%˜%K˜!K˜—K˜K˜�—šžœœœ3˜NK™?K˜—K˜�šž
œœœ)˜@K˜šžœœ˜šž
œ˜Kšœ!˜!Kšœ>˜>K˜—Kšœ˜Kšœ˜Kšœ"œ˜(K˜—Kšœ>˜>Kšœ?˜?Kšœ#˜#K˜K˜�—KšœœœŸ˜2šžœœœ'˜:Kšœœ,œ¡˜çKšœ'˜+Kšœ˜K˜�—šž	œœœ'˜=Kšœœ,œ¥˜ëšœœ˜Kšœ&˜&K˜!K˜—Kšœ˜K˜�—šžœœœD˜bšœ˜Kšœœ,œ¯˜úKšœœœ,œ¥˜øKšœ,œ¥˜Ý—š˜Kšœœ)˜@Kšœœœ'˜FKšœK˜O—Kšœ˜K˜�—šž	œœœ<œ˜[Kšœ
˜šžœ˜!Kšœ˜KšœC˜CKšœD˜DKšœ˜K˜—Kšœ
˜
Kšœ
˜
Kšœœ˜Kšœœ˜"Kšœœœ˜Kšœ3˜3Kšœ˜K•StartOfExpansionP[context: Imager.Context, path: ImagerPath.PathProc, parity: BOOL _ FALSE]šœ9œ˜?K˜K˜�—šž	œœœœœœ˜PKšœ@™@Kšœ˜Kšœ˜K˜—K˜�Kšœ˜—�…—����&>��2`��