-- 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.