-- Copyright (C) 1983 by Xerox Corporation. All rights reserved. -- DisplayImplC.mesa - last edited by -- Rick 29-Nov-83 11:51:53 -- Bruce 25-Feb-83 10:35:50 DIRECTORY BitBlt USING [BitBltFlags], Display USING [paintGrayFlags], DisplayFormat USING [CircleType], DisplayOps USING [LogError], DisplayInternal USING [SpecialCircle], SpecialDisplay USING [defaultContext, LineStyle, solid, Special], Window USING [Box, BoxHandle, nullBox, Place], WindowOps USING [AbsoluteBoxHandle, Bounds, Object, ScreenBox]; DisplayImplC: PROGRAM IMPORTS DisplayInternal, DisplayOps, SpecialDisplay, WindowOps EXPORTS Display, DisplayInternal, SpecialDisplay, Window = BEGIN -- exported types Handle: TYPE = LONG POINTER TO Object; Object: PUBLIC TYPE = WindowOps.Object; -- copied types because John doesn't like them Special: TYPE = SpecialDisplay.Special; Arc: PUBLIC PROC [ window: Handle, place: Window.Place, radius: INTEGER, startSector, stopSector: CARDINAL, start, stop: Window.Place, bounds: Window.BoxHandle ¬ NIL] = { IF ~window.inTree THEN RETURN; [] ¬ SpArcInternal[ window, FALSE, place, radius, startSector, stopSector, start, stop, ALL[FALSE], bounds, SpecialDisplay.solid, Display.paintGrayFlags]}; SpArc: PUBLIC PROC [ window: Handle, place: Window.Place, radius: INTEGER, startSector, stopSector: CARDINAL, start, stop: Window.Place, bounds: Window.BoxHandle, dashes: SpecialDisplay.LineStyle, flags: BitBlt.BitBltFlags, context: Special¬SpecialDisplay.defaultContext] = { ENABLE UNWIND => NULL; filled: BOOLEAN = context.alloc # NIL; SpArcInternal[ window, filled, place, radius, startSector, stopSector, start, stop, ALL[FALSE], bounds, dashes, flags, context]}; SpArcInternal: PROC [ window: Handle, filled: BOOLEAN, place: Window.Place, radius: INTEGER, startSector, stopSector: CARDINAL, start, stop: Window.Place, circleType: DisplayFormat.CircleType, bounds: Window.BoxHandle, dashes: SpecialDisplay.LineStyle, flags: BitBlt.BitBltFlags, context: Special ¬ SpecialDisplay.defaultContext]={ box1, box2, box3: Window.Box ¬ Window.nullBox; boundsBox: WindowOps.ScreenBox = IF bounds = NIL THEN WindowOps.Bounds[window] ELSE WindowOps.AbsoluteBoxHandle[window, bounds]; IF filled THEN FillArcBoxes[ @box1, @box2, @box3, start, stop, place, radius, boundsBox.top, boundsBox.bottom] ELSE DisplayArcBoxes[ @box1, @box2, @box3, start, stop, place, radius, dashes.thickness, (startSector-1)*8+(stopSector-1)]; -- octants are now 0..7 IF box1 # Window.nullBox THEN DisplayInternal.SpecialCircle[ window: window, place: place, radius: radius, circleType: circleType, bounds: @box1, dashes: dashes, flags: flags, context: context]; IF box2 # Window.nullBox THEN DisplayInternal.SpecialCircle[ window: window, place: place, radius: radius, circleType: circleType, bounds: @box2, dashes: dashes, flags: flags, context: context]; IF box3 # Window.nullBox THEN DisplayInternal.SpecialCircle[ window: window, place: place, radius: radius, circleType: circleType, bounds: @box3, dashes: dashes, flags: flags, context: context] }; DisplayArcBoxes: PUBLIC PROC [ b1, b2, b3: Window.BoxHandle, start,stop,center:Window.Place, radius, thickness, sum: CARDINAL] = { box1, box2, box3: WindowOps.ScreenBox ¬ [left:0,right:0,top:0,bottom:0]; bigBox: WindowOps.ScreenBox ¬ [ left: center.x - radius - 1, right: center.x + radius + 1, top: center.y - radius - 1, bottom: center.y + radius + 1]; littleBox: WindowOps.ScreenBox ¬ [ left: MIN[start.x, stop.x], right: MAX[start.x, stop.x], top: MIN[start.y, stop.y], bottom: MAX[start.y, stop.y]]; IF thickness > 2 THEN { bigBox.left ¬ bigBox.left - 1; bigBox.right ¬ bigBox.right + 1; bigBox.top ¬ bigBox.top - 1; bigBox.bottom ¬ bigBox.bottom + 1; IF littleBox.left < center.x THEN littleBox.left ¬ littleBox.left - 1; IF littleBox.top < center.y THEN littleBox.top ¬ littleBox.top - 1; IF littleBox.right > center.x THEN littleBox.right ¬ littleBox.right + 1; IF littleBox.bottom > center.y THEN littleBox.bottom ¬ littleBox.bottom+1}; --sum ¬ begin*8 + end; 0 to 65, could be passed from the graphic object -- convert sum to octal to get start and stop octants -- (eg. 14 = 16 octal or start octant 1 stop octant 6) SELECT sum FROM 0 => -- both in octant 0 IF start.y > stop.y OR start.x > stop.x THEN box1 ¬ littleBox ELSE { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.top ¬ box2.bottom ¬ box3.bottom ¬ center.y; box2.right ¬ start.x; box3.left ¬ stop.x}; 1, 2, 57, 58 => { -- 0 to 1, 0 to 2 box1 ¬ box2 ¬ bigBox; box1.right ¬ box2.left ¬ start.x; box2.top ¬ stop.y}; 3, 4, 59, 60 => {-- 0 to 3, 0 to 4 box1 ¬ box2 ¬ bigBox; box1.bottom ¬ box2.top ¬ center.y; box1.right ¬ start.x; box2.right ¬ stop.x}; 9 => -- both in octant 1 IF start.y > stop.y OR start.x > stop.x THEN box1 ¬ littleBox ELSE { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.right ¬ box2.left ¬ box3.left ¬ center.x; box2.bottom ¬ start.y; box3.top ¬ stop.y}; 10 => {-- 1 to 2 box1 ¬ box2 ¬ box3 ¬ bigBox; box1.right ¬ box2.left ¬ box3.left ¬ center.x; box2.bottom ¬ start.y; box3.top ¬ stop.y}; 11, 12, 19, 20 => { box1 ¬ box2 ¬ bigBox; box1.right ¬ box2.left ¬ stop.x; box2.bottom ¬ start.y}; 13, 14, 21, 22 => {-- 1 to 5 box1 ¬ box2 ¬ bigBox; box1.right ¬ box2.left ¬ center.x; box1.bottom ¬ stop.y; box2.bottom ¬ start.y}; 18 => -- both in octant 2 IF start.y > stop.y OR start.x < stop.x THEN box1 ¬ littleBox ELSE { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.right ¬ box2.left ¬ box3.left ¬ center.x; box2.bottom ¬ start.y; box3.top ¬ stop.y}; 24, 31, 32, 39 => { box1 ¬ box2 ¬ bigBox; box1.top ¬ box2.bottom ¬ center.y; box1.left ¬ start.x; box2.left ¬ stop.x}; 27 => -- both in octant 3 IF start.y > stop.y OR start.x < stop.x THEN box1 ¬ littleBox ELSE { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.bottom ¬ box2.top ¬ box3.top ¬ center.y; box2.left ¬ start.x; box3.right ¬ stop.x}; 28 => { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.bottom ¬ box2.top ¬ box3.top ¬ center.y; box2.left ¬ start.x; box3.right ¬ stop.x}; 29, 30, 37, 38 => { box1 ¬ box2 ¬ bigBox; box1.left ¬ box2.right ¬ start.x; box2.bottom ¬ stop.y}; 36 => -- both in octant 4 IF start.y < stop.y OR start.x < stop.x THEN box1 ¬ littleBox ELSE { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.bottom ¬ box2.top ¬ box3.top ¬ center.y; box2.left ¬ start.x; box3.right ¬ stop.x}; 40, 47, 48, 55 => { box1 ¬ box2 ¬ bigBox; box1.left ¬ box2.right ¬ stop.x; box2.top ¬ start.y}; 41, 42, 49, 50 => { box1 ¬ box2 ¬ bigBox; box1.left ¬ box2.right ¬ center.x; box2.top ¬ start.y; box1.top ¬ stop.y}; 45 => -- both in octant 5 IF start.y < stop.y OR start.x < stop.x THEN box1 ¬ littleBox ELSE { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.left ¬ box2.right ¬ box3.right ¬ center.x; box2.top ¬ start.y; box3.bottom ¬ stop.y}; 46 => { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.left ¬ box2.right ¬ box3.right ¬ center.x; box2.top ¬ start.y; box3.bottom ¬ stop.y}; 54 => -- both in octant 6 IF start.y < stop.y OR start.x > stop.x THEN box1 ¬ littleBox ELSE { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.left ¬ box2.right ¬ box3.right ¬ center.x; box2.top ¬ start.y; box3.bottom ¬ stop.y}; 56 => { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.top ¬ box2.bottom ¬ box3.bottom ¬ center.y; box2.right ¬ start.x; box3.left ¬ stop.x}; 63 => -- both in octant 7 IF start.y < stop.y OR start.x > stop.x THEN box1 ¬ littleBox ELSE { box1 ¬ box2 ¬ box3 ¬ bigBox; box1.top ¬ box2.bottom ¬ box3.bottom ¬ center.y; box2.right ¬ start.x; box3.left ¬ stop.x}; 5, 61 => { box1 ¬ bigBox; box1.right ¬ start.x; box1.bottom ¬ stop.y}; 6, 7, 15 => { box1 ¬ littleBox; box1.top ¬ bigBox.top}; 23 => { box1 ¬ bigBox; box1.left ¬ stop.x; box1.bottom ¬ start.y}; 16, 17, 25 => { box1 ¬ littleBox; box1.right ¬ bigBox.right}; 33, 34 => { box1 ¬ littleBox; box1.right ¬ bigBox.right; box1.bottom ¬ bigBox.bottom}; 35, 43 => { box1 ¬ littleBox; box1.bottom ¬ bigBox.bottom}; 51, 52 => { box1 ¬ littleBox; box1.left ¬ bigBox.left; box1.bottom ¬ bigBox.bottom}; 53 => { box1 ¬ littleBox; box1.left ¬ bigBox.left}; ENDCASE => box1 ¬ littleBox; --8, 26, 44, 62 IF box1.top < box1.bottom AND box1.left < box1.right THEN b1­ ¬ [ place: [x: box1.left, y: box1.top], dims: [w: box1.right - box1.left + 1, h: box1.bottom - box1.top + 1]]; IF box2.top < box2.bottom AND box2.left < box2.right THEN b2­ ¬ [ place: [x: box2.left, y: box2.top], dims: [w: box2.right - box2.left + 1, h: box2.bottom - box2.top + 1]]; IF box3.top < box3.bottom AND box3.left < box3.right THEN b3­ ¬ [ place: [x: box3.left, y: box3.top], dims: [w: box3.right - box3.left + 1, h: box3.bottom - box3.top + 1]]}; FillArcBoxes: PUBLIC PROC [ b1, b2, b3: Window.BoxHandle, startPlace, stopPlace, centerPlace: Window.Place, screenRadius, top, bottom: INTEGER] = { left: INTEGER = centerPlace.x - screenRadius - 1; right: INTEGER = centerPlace.x + screenRadius + 1; sum: CARDINAL ¬ (SELECT TRUE FROM startPlace.x < centerPlace.x => 0, startPlace.x = centerPlace.x AND startPlace.y > centerPlace.y => 1, startPlace.x = centerPlace.x AND startPlace.y < centerPlace.y => 2, ENDCASE => 3) + (SELECT TRUE FROM stopPlace.x < centerPlace.x => 0, stopPlace.x = centerPlace.x AND stopPlace.y > centerPlace.y => 4, stopPlace.x = centerPlace.x AND stopPlace.y < centerPlace.y => 8, ENDCASE => 12); IF startPlace.y > stopPlace.y THEN sum ¬ sum + 16; SELECT sum FROM 0, 2, 4, 6 => b1­ ¬ [place: [x: left, y: startPlace.y], dims: [w: centerPlace.x - left + 1, h: stopPlace.y - startPlace.y + 1]]; 11, 13, 25, 27, 29, 31 => b1­ ¬ [place: [x: centerPlace.x, y:stopPlace.y], dims: [w: right - centerPlace.x + 1, h:startPlace.y - stopPlace.y + 1]]; 8, 10, 12, 14, 24, 28 => { b1­ ¬ [place: [x: left, y: startPlace.y], dims: [w: centerPlace.x - left + 1, h: bottom - startPlace.y + 1]]; b2­ ¬ [place: [x: centerPlace.x, y: stopPlace.y], dims: [w: right - centerPlace.x + 1, h: bottom - stopPlace.y + 1]]}; 1, 3, 5, 7, 17, 19 => { b1­ ¬ [place: [x: left, y: top], dims: [w: centerPlace.x - left + 1, h: stopPlace.y - top + 1]]; b2­ ¬ [place: [x: centerPlace.x, y: top], dims: [w: right - centerPlace.x + 1, h: startPlace.y - top + 1]]}; 15 => { b1­ ¬ [place: [x: left, y: top], dims: [w: centerPlace.x - left + 1, h: bottom - top + 1]]; b2­ ¬ [place: [x: centerPlace.x, y: top], dims: [w: right - centerPlace.x + 1, h: startPlace.y - top + 1]]; b3­ ¬ [place: [x: centerPlace.x, y: stopPlace.y], dims: [w: right - centerPlace.x + 1, h: bottom - stopPlace.y + 1]]}; 16 => { b1­ ¬ [place: [x: centerPlace.x, y: top], dims: [w: right - centerPlace.x + 1, h: bottom - top + 1]]; b2­ ¬ [place: [x: left, y: startPlace.y], dims: [w: centerPlace.x - left + 1, h: bottom - startPlace.y + 1]]; b3­ ¬ [place: [x: left, y: top], dims: [w: centerPlace.x - left + 1, h: stopPlace.y - top + 1]]}; ENDCASE => { DisplayOps.LogError[]; RETURN}; IF b1­ # Window.nullBox AND b1.dims.h = 1 AND (b2­ # Window.nullBox OR b3­ # Window.nullBox) THEN b1­ ¬ Window.nullBox; IF b2­ # Window.nullBox AND b2.dims.h = 1 AND (b1­ # Window.nullBox OR b3­ # Window.nullBox) THEN b2­ ¬ Window.nullBox; IF b3­ # Window.nullBox AND b3­.dims.h = 1 AND (b1­ # Window.nullBox OR b2­ # Window.nullBox) THEN b3­ ¬ Window.nullBox}; END.