CDDefaultProcsImpl.mesa (part of ChipNDale)
Copyright © 1985, 1986 by Xerox Corporation. All rights reserved.
by Ch. Jacobi, May 22, 1985 3:35:49 pm PDT
last edited by Ch. Jacobi, March 25, 1986 1:46:40 pm PST
DIRECTORY
Atom,
Basics,
CD,
CDBasics,
CDDefaultProcs,
CDDirectory,
CDOrient,
Imager,
ImagerBackdoor,
ImagerManhattan,
ImagerMaskCapture,
ImagerPrivate,
ImagerTransformation,
Rope;
CDDefaultProcsImpl:
CEDAR
PROGRAM
IMPORTS Atom, --Basics,-- CD, CDBasics, CDDirectory, CDOrient, Imager, --ImagerBackdoor,-- ImagerManhattan, ImagerMaskCapture, ImagerPrivate, ImagerTransformation, Rope
EXPORTS CDDefaultProcs
SHARES CD =
BEGIN
OPEN CD;
--Object class implementors business
--ObjectClass
QuickDrawMe:
PUBLIC
PROC [inst: Instance, pos: Position, orient: Orientation, pr:
REF DrawInformation] =
BEGIN
IF inst.ob.class.drawMe#DrawMe
THEN
inst.ob.class.drawMe[inst, pos, orient, pr]
ELSE {
ob1: CD.Object = CDDirectory.Expand[inst.ob].new;
IF ob1#
NIL
THEN {
pseudoInst:
CD.Instance =
NEW[
CD.InstanceRep
← [ob: ob1, properties: inst.properties, location: pos, selected: FALSE]];
ob1.class.quickDrawMe[pseudoInst, pos, orient, pr];
pseudoInst.ob ← NIL;
pseudoInst.properties ← NIL;
}
ELSE pr.drawRect[CDOrient.RectAt[pos, inst.ob.size, orient], CD.shadeLayer, pr]
}
END;
DrawMe:
PUBLIC PROC [inst: Instance, pos: Position, orient: Orientation, pr:
REF DrawInformation] =
BEGIN
IF inst.ob.class.quickDrawMe#QuickDrawMe
THEN
inst.ob.class.quickDrawMe[inst, pos, orient, pr]
ELSE {
ob1: CD.Object = CDDirectory.Expand[inst.ob].new;
IF ob1#
NIL
THEN {
pseudoInst:
CD.Instance =
NEW[
CD.InstanceRep
← [ob: ob1, properties: inst.properties, location: pos, selected: FALSE]];
ob1.class.drawMe[pseudoInst, pos, orient, pr];
pseudoInst.ob ← NIL;
pseudoInst.properties ← NIL;
}
ELSE pr.drawRect[CDOrient.RectAt[pos, inst.ob.size, orient], CD.shadeLayer, pr]
}
END;
ShowMeSelected:
PUBLIC
PROC [inst: Instance, pos: Position, orient: Orientation, pr:
REF DrawInformation] =
BEGIN
pr.drawOutLine[
CDOrient.MapRect[itemInCell: CD.InterestRect[inst.ob], cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos],
CD.selectionLayer,
pr
]
END;
ShowMeSelectedWithExpand:
PUBLIC
PROC [inst: Instance, pos: Position, orient: Orientation, pr:
REF DrawInformation] =
BEGIN
ob1: CD.Object = CDDirectory.Expand[inst.ob].new;
IF ob1=
NIL
THEN pr.drawOutLine[
CDOrient.MapRect[itemInCell: CD.InterestRect[inst.ob], cellSize: inst.ob.size, cellInstOrient: orient, cellInstPos: pos],
CD.selectionLayer,
pr]
ELSE ob1.class.showMeSelected[
inst:
NEW [
CD.InstanceRep ← [ob: ob1,
location: inst.location,
orientation: inst.orientation,
selected: inst.selected
]],
pos: pos,
orient: orient,
pr: pr];
END;
HitInside:
PUBLIC PROC [ob: Object, hitRect: Rect]
RETURNS [
BOOL] =
BEGIN
RETURN [CDBasics.Intersect[CD.InterestRect[ob], hitRect] ]
END;
InterestRect:
PUBLIC PROC [ob: Object]
RETURNS [Rect] =
BEGIN
RETURN [CDBasics.RectAt[[0, 0], ob.size]]
END;
InterestRectWithExpand:
PUBLIC
PROC [ob: Object]
RETURNS [Rect] =
BEGIN
ob1: CD.Object = CDDirectory.Expand[ob].new;
IF ob1#NIL THEN RETURN [CD.InterestRect[ob1]]
ELSE RETURN [CDBasics.RectAt[[0, 0], ob.size]];
END;
InternalRead:
PUBLIC PROC []
RETURNS [Object] =
BEGIN
ERROR
END;
Describe:
PUBLIC PROC [me: Object]
RETURNS [Rope.
ROPE] =
BEGIN
Desc:
PROC [class:
CD.ObjectClass]
RETURNS [Rope.
ROPE] =
INLINE BEGIN
RETURN [
IF class.description=NIL THEN Atom.GetPName[class.objectType]
ELSE class.description
]
END;
IF me.class.inDirectory
THEN {
n: Rope.ROPE = CDDirectory.Name[me];
IF ~Rope.IsEmpty[n] THEN RETURN [Rope.Cat[Desc[me.class], " ", n]]
};
RETURN [Desc[me.class]]
END;
DescribeInstance:
PUBLIC PROC [ap: Instance]
RETURNS [Rope.
ROPE] =
BEGIN
RETURN [ap.ob.class.describe[ap.ob]]
END;
Origin:
PUBLIC PROC [ob: Object]
RETURNS [Position] =
BEGIN
RETURN [CDBasics.BaseOfRect[ob.class.interestRect[ob]]]
END;
--DrawProcs
DrawChild:
PUBLIC PROC [inst: Instance, pos: Position, orient: Orientation, pr:
REF DrawInformation] =
BEGIN
inst.ob.class.drawMe[inst, pos, orient, pr]
END;
DrawRect:
PUBLIC PROC [r: Rect, l: Layer, pr: DrawRef] =
BEGIN
DrawRectInContext:
PROC [context: Imager.Context, ob:
CD.Object, layer:
CD.Layer] =
BEGIN
Imager.MaskBox[context, [xmin: r.x1, xmax: r.x2, ymin: r.y1, ymax: r.y2]];
END;
pr.drawContext[pr, DrawRectInContext, NIL, [0, 0], 0, l]
END;
DrawOutLine:
PUBLIC PROC [r: Rect, l: Layer, pr: DrawRef] =
BEGIN
END;
DrawComment:
PUBLIC PROC [r: Rect, comment: Rope.
ROPE, pr: DrawRef] =
BEGIN
END;
--version with bitmaps
DrawContext: PUBLIC PROC [pr: DrawRef, proc: DrawContextLayerProc, ob: Object, pos: Position, orient: Orientation, layer: Layer] =
--calls proc which may use context; mode and color are set to layer's need
--call is suppressed if layer does not need drawing; this is default.
--on recursive calls, the context may or may not include previous transformations
BEGIN
ActionWithContext: PROC [] =
BEGIN
IF ob#NIL THEN {
Imager.TranslateT[pr.deviceContext, [pos.x, pos.y]];
CDOrient.OrientateContext[pr.deviceContext, ob.size, orient];
};
Imager.SetColor[pr.deviceContext, pr.contextFilter[layer]];
proc[pr.deviceContext, ob, layer];
END;
IF pr.contextFilter#NIL AND pr.contextFilter[layer]#NIL THEN {
IF pr.deviceContext#NIL THEN Imager.DoSave[pr.deviceContext, ActionWithContext]
ELSE IF ob#NIL THEN {
--if ob is nil we don't know the size for the bitmap nor the clip region
clip: CD.Rect ~ CDOrient.DeMapRect[itemInWorld: pr.interestClip, cellSize: ob.size, cellInstOrient: orient, cellInstPos: pos].itemInCell; --in object coordinates
inter: CD.Rect ~ CDBasics.Intersection[CDBasics.RectAt[[0, 0], ob.size], clip];
IF CDBasics.NonEmpty[inter] THEN {
DrawToBitmapContext: PROC [] = {
proc[context, ob, layer];
};
CapturePixel: PROC [x, y: INT] = INLINE {
r: CD.Rect ← CDOrient.MapRect[itemInCell: [x1: x, y1: y, x2: x+1, y2: y+1], cellSize: ob.size, cellInstOrient: orient, cellInstPos: pos];
r ← CDBasics.Intersection[r, pr.interestClip];
IF CDBasics.NonEmpty[r] THEN pr.drawRect[r, layer, pr];
};
CaptureBitmap: PROC [bitmap: ImagerBackdoor.Bitmap, off: CD.Position] =
BEGIN
FOR y: CARDINAL IN [0..bitmap.height) DO
FOR x: CARDINAL IN [0..bitmap.width) DO
TRUSTED {
bitsRef: LONG POINTER TO CARDINAL
← LOOPHOLE[bitmap.base, LONG POINTER TO CARDINAL]
+ LONG[y]*bitmap.wordsPerLine
+ LONG[x/Basics.bitsPerWord];
IF Basics.BITAND[8000h, Basics.BITSHIFT[bitsRef^, x MOD Basics.bitsPerWord]]#0 THEN
CapturePixel[off.x+x, off.y+bitmap.height-y-1]
}
ENDLOOP;
ENDLOOP;
END;
bitmap: ImagerBackdoor.Bitmap ← ImagerBackdoor.NewBitmap[width: inter.x2-inter.x1, height: inter.y2-inter.y1];
context: Imager.Context ← ImagerBackdoor.BitmapContext[bitmap];
Imager.SetColor[context, Imager.white];
Imager.MaskRectangleI[context, 0, 0, bitmap.width, bitmap.height];
Imager.TranslateT[context, [-inter.x1, -inter.y1]];
Imager.SetColor[context, Imager.black];
Imager.DoSave[context, DrawToBitmapContext];
CaptureBitmap[bitmap, CDBasics.BaseOfRect[inter]];
bitmap ← NIL;
context ← NIL;
};
};
};
END;
DrawContext:
PUBLIC
PROC [pr: DrawRef, proc: DrawContextLayerProc, ob: Object, pos: Position, orient: Orientation, layer: Layer] =
--calls proc which may use context; mode and color are set to layer's need
--call is suppressed if layer does not need drawing; this is default.
--on recursive calls, the context may or may not include previous transformations
BEGIN
ActionWithContext:
PROC [] =
BEGIN
IF ob#
NIL
THEN {
Imager.TranslateT[pr.deviceContext, [pos.x, pos.y]];
CDOrient.OrientateContext[pr.deviceContext, ob.size, orient];
};
Imager.SetColor[pr.deviceContext, pr.contextColors[layer]];
proc[pr.deviceContext, ob, layer];
END;
IF pr.deviceContext#
NIL
THEN {
IF pr.contextColors[layer]#NIL THEN Imager.DoSave[pr.deviceContext, ActionWithContext]
}
ELSE
IF pr.contextFilter#
NIL
AND pr.contextFilter[layer]
THEN {
IF ob#
NIL
THEN {
--if ob is nil we don't know the size for the bitmap nor the clip region
clip: CD.Rect ~ CDOrient.DeMapRect[itemInWorld: pr.interestClip, cellSize: ob.size, cellInstOrient: orient, cellInstPos: pos].itemInCell; --in object coordinates
inter: CD.Rect ~ CDBasics.Intersection[CDBasics.RectAt[[0, 0], ob.size], clip];
IF CDBasics.NonEmpty[inter]
THEN {
Operator:
PROC [context: Imager.Context] = {
Imager.SetStrokeWidth[context, 1];
Imager.SetStrokeEnd[context, round];
Imager.SetStrokeJoint[context, round];
ImagerPrivate.SetStrokeDashes[context, NIL];
Imager.ClipRectangle[context, [x: inter.x1, y: inter.y1, w: inter.x2-inter.x1, h: inter.y2-inter.y1]];
proc[context, ob, layer ! ImagerMaskCapture.Cant => --RESUME--REJECT];
};
man: ImagerMaskCapture.Manhattan;
man ← ImagerMaskCapture.CaptureManhattan[Operator, ImagerTransformation.Scale[1]];
FOR m: ImagerMaskCapture.Manhattan ← man, m.rest
UNTIL m=
NIL
DO
r:
CD.Rect ← CDOrient.MapRect[
itemInCell: [x1: m.first.sMin, y1: m.first.fMin, x2: m.first.sMin+m.first.sSize, y2: m.first.fMin+m.first.fSize],
cellSize: ob.size,
cellInstOrient: orient,
cellInstPos: pos];
r ← CDBasics.Intersection[r, pr.interestClip];
IF CDBasics.NonEmpty[r] THEN pr.drawRect[r, layer, pr];
ENDLOOP;
ImagerManhattan.Destroy[man];
};
};
};
END;
IgnoreGround:
PUBLIC PROC [pr: DrawRef, pushedOut:
BOOL] =
BEGIN
END;
IgnorePriority:
PUBLIC PROC [pr: DrawRef] =
BEGIN
END;
END.