DIRECTORY Atom, CD, CDBasics, CDBasicsInline, CDDefaultProcs, CDDirectory, CDProperties, D2Orient, Imager, ImagerManhattan, ImagerMaskCapture, ImagerTransformation, Real, Rope, TokenIO; CDDefaultProcsImpl: CEDAR PROGRAM IMPORTS Atom, CD, CDBasics, CDBasicsInline, CDDirectory, CDProperties, Imager, ImagerManhattan, ImagerMaskCapture, ImagerTransformation, Real EXPORTS CDDefaultProcs SHARES CD = BEGIN OPEN CD; QuickDrawMe: PUBLIC PROC [pr: REF DrawInformation, ob: CD.Object, trans: Transformation, readOnlyInstProps: PropList] = { IF ob.class.drawMe#DrawMe THEN ob.class.drawMe[pr, ob, trans, readOnlyInstProps] ELSE { ob1: CD.Object = CDDirectory.Expand1[ob].new; IF ob1#NIL THEN ob1.class.quickDrawMe[pr, ob1, trans, readOnlyInstProps] ELSE pr.drawRect[pr, CDBasics.MapRect[ob.bbox, trans], CD.shadeLayer] } }; DrawMe: PUBLIC PROC [pr: REF DrawInformation, ob: CD.Object, trans: Transformation, readOnlyInstProps: PropList] = { IF ob.class.quickDrawMe#QuickDrawMe THEN ob.class.quickDrawMe[pr, ob, trans, readOnlyInstProps] ELSE { ob1: CD.Object = CDDirectory.Expand1[ob].new; IF ob1#NIL THEN ob1.class.drawMe[pr, ob1, trans, readOnlyInstProps] ELSE pr.drawRect[pr, CDBasics.MapRect[ob.bbox, trans], CD.shadeLayer] } }; ShowMeSelected: PUBLIC PROC [pr: REF DrawInformation, ob: CD.Object, trans: Transformation, readOnlyInstProps: PropList] = { pr.drawOutLine[pr, CDBasics.MapRect[CD.InterestRect[ob], trans], CD.selectionLayer] }; ShowMeSelectedWithExpand: PUBLIC PROC [pr: REF DrawInformation, ob: CD.Object, trans: Transformation, readOnlyInstProps: PropList] = { ob1: CD.Object = CDDirectory.Expand1[ob].new; IF ob1=NIL THEN pr.drawOutLine[pr, CDBasics.MapRect[CD.InterestRect[ob], trans], CD.selectionLayer] ELSE ob1.class.showMeSelected[pr, ob1, trans, readOnlyInstProps]; }; HitInside: PUBLIC PROC [ob: Object, hitRect: Rect] RETURNS [BOOL] = { RETURN [CDBasics.Intersect[CD.InterestRect[ob], hitRect] ] }; InterestRect: PUBLIC PROC [ob: Object] RETURNS [Rect] = { RETURN [ob.bbox] }; InterestRectWithExpand: PUBLIC PROC [ob: Object] RETURNS [Rect] = { ob1: CD.Object = CDDirectory.Expand1[ob].new; RETURN [(IF ob1#NIL THEN CD.InterestRect[ob1] ELSE ob.bbox)] }; InternalRead: PUBLIC PROC [h: TokenIO.Handle, key: ATOM] RETURNS [Object] = { ERROR }; Describe: PUBLIC PROC [ob: Object, readOnlyInstProps: PropList, verbosity: NAT] RETURNS [Rope.ROPE] = { RETURN [ IF ob.class.description=NIL THEN Atom.GetPName[ob.class.objectType] ELSE ob.class.description ]; }; DrawChild: PUBLIC PROC [pr: REF DrawInformation, ob: CD.Object, trans: Transformation, readOnlyInstProps: PropList] = { ob.class.drawMe[pr, ob, trans, readOnlyInstProps] }; IgnoreChild: PUBLIC PROC [pr: REF DrawInformation, ob: CD.Object, trans: Transformation, readOnlyInstProps: PropList] = { }; DrawChildSel: PUBLIC PROC [pr: REF DrawInformation, ob: CD.Object, trans: Transformation, readOnlyInstProps: PropList] = { ob.class.showMeSelected[pr, ob, trans, readOnlyInstProps] }; DrawRect: PUBLIC PROC [pr: DrawRef, r: Rect, l: Layer] = { DrawRectInContext: PROC [context: Imager.Context, ob: CD.Object, layer: CD.Layer] = { Imager.MaskBox[context, [xmin: r.x1, xmax: r.x2, ymin: r.y1, ymax: r.y2]]; }; pr.drawContext[pr, DrawRectInContext, NIL, [[0, 0], original], l] }; IgnoreRect: PUBLIC PROC [pr: DrawRef, r: Rect, l: Layer] = { }; ContextOutLine: PUBLIC PROC [pr: DrawRef, r: Rect, l: Layer] = { ActionWithContext: PROC [] = { Imager.SetColor[pr.deviceContext, pr.contextColors[l]]; Imager.MaskVector[pr.deviceContext, [r.x1, r.y1], [r.x2, r.y1]]; Imager.MaskVector[pr.deviceContext, [r.x2, r.y1], [r.x2, r.y2]]; Imager.MaskVector[pr.deviceContext, [r.x2, r.y2], [r.x1, r.y2]]; Imager.MaskVector[pr.deviceContext, [r.x1, r.y2], [r.x1, r.y1]]; }; IF pr.deviceContext#NIL THEN { IF pr.contextColors[l]#NIL THEN Imager.DoSave[pr.deviceContext, ActionWithContext] } }; DrawComment: PUBLIC PROC [pr: DrawRef, r: Rect, comment: Rope.ROPE] = { }; TransContext: PROC [cont: Imager.Context, trans: Transformation] = INLINE { Imager.TranslateT[cont, [trans.off.x, trans.off.y]]; IF CDBasics.IncludesMirrorX[trans.orient] THEN Imager.Scale2T[cont, [-1, 1]]; SELECT CDBasics.ConcentrateOnRotate90[trans.orient] FROM original => NULL; rotate90 => Imager.RotateT[cont, 90]; rotate180 => Imager.RotateT[cont, 180]; rotate270 => Imager.RotateT[cont, 270]; ENDCASE => ERROR; }; DrawContext: PUBLIC PROC [pr: DrawRef, proc: DrawContextLayerProc, ob: Object, trans: Transformation, layer: Layer] = { ActionWithContext: PROC [] = { IF ob#NIL THEN TransContext[pr.deviceContext, trans]; Imager.SetColor[pr.deviceContext, pr.contextColors[layer]]; proc[pr.deviceContext, ob, layer]; }; 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 { clip: CD.Rect ~ CDBasics.DeMapRect[pr.interestClip, trans].itemInCell; --in object coordinates inter: CD.Rect ~ CDBasics.Intersection[ob.bbox, clip]; IF CDBasics.NonEmpty[inter] THEN { Operator: PROC [context: Imager.Context] = { Imager.SetAmplifySpace[context, 1]; Imager.SetStrokeWidth[context, 1]; Imager.SetStrokeEnd[context, round]; Imager.SetStrokeJoint[context, round]; 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 => REJECT]; }; man: ImagerManhattan.Polygon; man _ ImagerMaskCapture.CaptureManhattan[Operator, CDBasics.ImagerTransform[[orient: rotate90]]]; FOR m: ImagerManhattan.Polygon _ man, m.rest UNTIL m=NIL DO r: CD.Rect _ CDBasics.MapRect[[x1: m.first.min.f, y1: -m.first.max.s, x2: m.first.max.f, y2: -m.first.min.s], trans]; r _ CDBasics.Intersection[r, pr.interestClip]; IF CDBasics.NonEmpty[r] THEN pr.drawRect[pr, r, layer]; ENDLOOP; ImagerManhattan.Destroy[man]; }; }; }; }; IgnoreGround: PUBLIC PROC [pr: DrawRef, pushedOut: BOOL] = { }; IgnorePriority: PUBLIC PROC [pr: DrawRef] = { }; DrawExtension: TYPE = RECORD [ dDrawRect: CD.DrawRectProc, dOrigin: CD.Position, scale: REAL ]; ExtendedDrawContext: PROC [pr: DrawRef, proc: DrawContextLayerProc, ob: Object, trans: Transformation, layer: Layer] = { WITH CDProperties.GetPRefProp[pr.properties, $ExtendedDrawContext] SELECT FROM de: REF DrawExtension => { IF pr.contextFilter#NIL AND pr.contextFilter[layer] THEN { IF ob#NIL THEN { clip: CD.Rect ~ CDBasics.DeMapRect[pr.interestClip, trans].itemInCell; --in ob coords inter: CD.Rect ~ CDBasics.Intersection[ob.bbox, clip]; IF CDBasics.NonEmpty[inter] THEN { Operator: PROC [context: Imager.Context] = { Imager.SetAmplifySpace[context, 1]; Imager.SetStrokeWidth[context, 1]; Imager.SetStrokeEnd[context, round]; Imager.SetStrokeJoint[context, round]; 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 => REJECT]; }; t: CD.Transformation = [ off: [ Real.Round[de.scale*(trans.off.x-de.dOrigin.x)], Real.Round[de.scale*(trans.off.y-de.dOrigin.y)]], orient: trans.orient]; man: ImagerManhattan.Polygon; man _ ImagerMaskCapture.CaptureManhattan[Operator, ImagerTransformation.PreScale[CDBasics.ImagerTransform[[orient: rotate90]], de.scale]]; --rotation: see simple case why FOR m: ImagerManhattan.Polygon _ man, m.rest UNTIL m=NIL DO r: CD.Rect _ [x1: m.first.min.f, y1: -m.first.max.s, x2: m.first.max.f, y2: -m.first.min.s]; IF CDBasics.NonEmpty[r] THEN { de.dDrawRect[pr, CDBasicsInline.MapRect[r, t], layer]; } ENDLOOP; ImagerManhattan.Destroy[man]; }; }; }; }; ENDCASE => ERROR }; ConvertContextsToDeviceRects: PUBLIC PROC [pr: CD.DrawRef, dDrawRect: CD.DrawRectProc, dOrigin: CD.Position_[0, 0], scale: REAL_1] = { de: REF DrawExtension _ NEW[DrawExtension_[ dDrawRect: dDrawRect, dOrigin: dOrigin, scale: scale ]]; IF pr.deviceContext#NIL THEN ERROR; CDProperties.PutPRefProp[pr.properties, $ExtendedDrawContext, de]; pr.drawContext _ ExtendedDrawContext }; END. ΔCDDefaultProcsImpl.mesa (part of ChipNDale) Copyright c 1985, 1987 by Xerox Corporation. All rights reserved. Created by Ch. Jacobi, May 22, 1985 3:35:49 pm PDT Last edited by: Christian Jacobi, February 23, 1987 1:17:36 pm PST --ObjectClass --DrawProcs --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 ActionWithContext: PROC [] = { IF ob#NIL THEN { Imager.TranslateT[pr.deviceContext, [pos.x, pos.y]]; OrientateContext[pr.deviceContext, ob.size, orient]; }; Imager.SetColor[pr.deviceContext, pr.contextFilter[layer]]; proc[pr.deviceContext, ob, layer]; }; 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 ~ CDBasics.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 _ CDBasics.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] = { 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; }; 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; }; }; }; }; --or Imager.ConcatT[cont, CDBasicsInline.ImagerTransform[trans]] --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 --if ob is nil we don't know the size for the bitmap nor the clip region --rotated so that mask capture will returned horizontal patches bottom up --instead of vertical patches. Using horizontal bands for corner stitching, and, --using corner stitchings maximal east west property, this gave an improvement --factor (in the one experimenmt I made) of about 50 (fifty!) --undo rotation! don't use --[x1: m.first.min.s, y1: m.first.min.f, x2: m.first.max.s, y2: m.first.max.f] --undo rotation! don't use --[x1: m.first.min.s, y1: m.first.min.f, x2: m.first.max.s, y2: m.first.max.f] --we do the translation on the rectangles instead in the Operator because --that would exceed the range where ImagerMaskCapture works correctly. Κ ˜codešœ,™,Kšœ Οmœ7™BKšœ2™2K™BK˜—šΟk ˜ Kšœž˜Kšž˜Kšœ ˜ Kšœ˜Kšœ˜Kšœ ˜ Kšœ ˜ Kšœ ˜ Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜Kšœ˜—K˜šΟnœžœžœ˜"Kšžœžœ}˜Kšžœ˜Kšžœžœ˜ —Kšž˜Kšžœžœ˜ K˜Kšœ ™ K˜š Ÿ œžœžœžœžœ@˜yKšžœžœ2˜Pšžœ˜Kšœžœ&˜-Kšžœžœžœ9˜HKšžœ3žœ ˜EK˜—Kšœ˜K˜—šŸœž œžœžœ@˜tšžœ"žœ˜)Kšœ6˜6—šžœ˜Kšœžœ&˜-Kšžœžœžœ4˜CKšžœ3žœ ˜EK˜—Kšœ˜K˜—š Ÿœžœžœžœžœ@˜|Kšœ$žœžœ˜SKšœ˜K˜—š Ÿœžœžœžœžœ@˜†Kšœžœ&˜-šžœžœžœ˜Kšœ$žœžœ˜S—šžœ˜Kšœ<˜<—Kšœ˜K˜—šŸ œž œžœžœ˜EKšžœžœ˜:Kšœ˜K˜—šŸ œž œžœ ˜9Kšžœ ˜Kšœ˜K˜—šŸœžœžœžœ ˜CKšœžœ&˜-Kš žœžœžœžœžœžœ ˜Kšžœžœžœ3™Ošžœžœžœžœ™K™IKšœžœ‚Οc™‘KšœžœF™Ošžœžœ™"K™šŸœžœ™ Kšœ™Kšœ™—K™šŸ œžœžœžœ™)Kšœžœ„™‰Kšœ.™.Kšžœžœ™7K™—K™šŸ œžœ&žœ™Išžœžœžœž™(šžœžœžœžœ™(šžœ™ š œ žœžœžœžœ™"Kš œžœžœžœžœžœ™1Kšœžœ™Kšœžœ™—š žœžœžœ žœžœ™TKšœ.™.—Kšœ™—Kšžœ™—Kšžœ™—Kšœ™—K™Kšœn™nKšœ?™?Kšœ'™'KšœB™BKšœ3™3Kšœ'™'Kšœ,™,Kšœ2™2Kšœ žœ™ Kšœ žœ™K™—K™—K™—Kšœ™K™—šŸ œžœ1žœ˜KKšœ4˜4Kšžœ(žœ˜Mšžœ.žœ˜9Kšœ žœ˜Kšœ&˜&Kšœ'˜'Kšœ'˜'Kšžœžœ˜—Kšœ@™@Kšœ˜K˜K˜—šŸ œžœžœ_˜wKšœJ™JKšœE™EKšœQ™QK˜šŸœžœ˜Kšžœžœžœ'˜5Kšœ;˜;Kšœ"˜"Kšœ˜—K˜šžœžœž˜Kšžœžœžœ2˜VK˜—š žœžœžœžœžœ˜?šžœžœžœ˜K™IK˜Kšœžœ? ˜^Kšœžœ-˜6šžœžœ˜"K˜šŸœžœ˜,Kšœ#˜#Kšœ"˜"Kšœ$˜$Kšœ&˜&Kšœf˜fKšœ4žœ˜