-- Copyright (C) 1983, 1984  by Xerox Corporation. All rights reserved. 
-- DisplayImplB.mesa - last edited by 
-- Rick	        12-Nov-83 14:44:30  
-- Bruce	15-Feb-83 10:14:37  
-- Daniels	 7-Jun-84 15:19:02  

DIRECTORY
  BitBlt USING [BitBltFlags],
  Display USING [paintGrayFlags],
  DisplayOps USING [
    AbsPlace, HasUnder, LogError, FillList, FillObject, Intersect, Shade],
  SpecialDisplay USING [DashCnt, defaultContext, LineStyle, solid, Special],
  Window USING [BoxHandle, Place],
  WindowOps USING [
    AbsoluteBoxHandle, bitmapAddress, DisplayList, GetContext, lock,
    Object, RecList, ScanLine, ScreenBox, SpecialTimesWpl];

DisplayImplB: MONITOR LOCKS WindowOps.lock
  IMPORTS DisplayOps, SpecialDisplay, WindowOps EXPORTS SpecialDisplay, Window =
  BEGIN

  -- exported types
  Handle: TYPE = LONG POINTER TO Object;
  Object: PUBLIC TYPE = WindowOps.Object;

  FillHandle: TYPE = LONG POINTER TO FillObject;
  FillObject: PUBLIC TYPE = DisplayOps.FillObject;

  -- copied types because John doesn't like them
  LineStyle: TYPE = SpecialDisplay.LineStyle;
  Special: TYPE = SpecialDisplay.Special;

  -- lines

  Positive45Line: PUBLIC ENTRY PROC [
    window: Handle, place: Window.Place, stopX: INTEGER,
    bounds: Window.BoxHandle] = {
    -- This routine intersects the bounding box of any line displayed with the
    -- bounding box of each reclist. Given this, the fact that start.y >= stop.y,
    -- and the specific type of line being delt with here it is assumed that:
    -- start.x <= r.box.right
    -- stop.x >= r.box.left
    -- start.y >= r.box.top 
    -- stop.y <= r.box.bottom or else DisplayOps.Intersect fails.
    ENABLE UNWIND => NULL;
    absBounds: WindowOps.ScreenBox = WindowOps.AbsoluteBoxHandle[window, bounds];
    -- switch to screen coords
    abs: Window.Place = DisplayOps.AbsPlace[window, place];
    absX: INTEGER = stopX + window.place.x;
    startAddress: WindowOps.ScanLine =
      WindowOps.bitmapAddress + WindowOps.SpecialTimesWpl[INTEGER[abs.y]];
    IF ~window.inTree THEN RETURN;
    FOR r: WindowOps.RecList ← WindowOps.DisplayList[window], r.link UNTIL r = NIL
      DO
      IF DisplayOps.Intersect[r, absBounds] THEN {
        bitAddress: WindowOps.ScanLine ← startAddress;
        left: INTEGER = r.box.left;
        top: INTEGER = r.box.top;
        right: INTEGER = r.box.right;
        bottom: INTEGER = r.box.bottom;
	IF top = bottom THEN LOOP;
        IF DisplayOps.HasUnder[r] THEN {
          SpP45Internal[
            window, abs, absX, absBounds, SpecialDisplay.solid,
            Display.paintGrayFlags, SpecialDisplay.defaultContext];
          RETURN};
        place ← abs;
        stopX ← absX;
        IF bottom - 1 < place.y THEN {
          place.x ← place.x + place.y - bottom + 1;
          bitAddress ← bitAddress - WindowOps.SpecialTimesWpl[INTEGER[place.y-bottom+1]];
          place.y ← bottom - 1};
        IF left > place.x THEN {
          IF left > place.y + place.x THEN LOOP;
          place.y ← place.y + place.x - left;
          bitAddress ← bitAddress - WindowOps.SpecialTimesWpl[INTEGER[left-place.x]];
          place.x ← left};
        IF top > place.y - stopX + place.x THEN stopX ← place.y + place.x - top;
        IF right < stopX THEN stopX ← right - 1;
        FOR bitIndex: INTEGER IN [place.x..stopX] DO
          bitAddress[bitIndex] ← TRUE;  -- set a bit
          bitAddress ← bitAddress - SpecialDisplay.defaultContext.wpl;
          ENDLOOP};
      ENDLOOP};

  SpPositive45Line: PUBLIC ENTRY PROC [
    window: Handle, place: Window.Place, stopX: INTEGER, bounds: Window.BoxHandle,
    dashes: LineStyle, flags: BitBlt.BitBltFlags,
    context: Special ← SpecialDisplay.defaultContext] = {
    -- This routine intersects the bounding box of any line displayed with the
    -- bounding box of each reclist. Given this, the fact that start.y >= stop.y,
    -- and the specific type of line being delt with here it is assumed that:
    -- start.x <= r.box.right
    -- stop.x >= r.box.left
    -- start.y >= r.box.top
    -- stop.y <= r.box.bottom or else DisplayOps.Intersect fails.
    ENABLE UNWIND => NULL;
    IF window.inTree THEN {
      absBounds: WindowOps.ScreenBox = WindowOps.AbsoluteBoxHandle[window,bounds];
      -- switch to screen coords
      abs: Window.Place = DisplayOps.AbsPlace[window, place];
      absX: INTEGER = stopX + window.place.x;
      SpP45Internal[window, abs, absX, absBounds, dashes, flags, context]}};

  SpP45Internal: INTERNAL PROC [
    window: Handle, abs: Window.Place, absX: INTEGER,
    absBounds: WindowOps.ScreenBox, dashes: LineStyle, flags: BitBlt.BitBltFlags,
    context: Special] = {
    dashCnt, dashSum: CARDINAL;
    filled: BOOLEAN = context.alloc # NIL;
    widths: ARRAY [0..SpecialDisplay.DashCnt) OF CARDINAL;
    inc1, inc2, inc3, inc4, inc5, inc6: CARDINAL;
    low: INTEGER = abs.y - dashes.thickness/2;
    high: INTEGER = low + dashes.thickness;
    fillcnt, fillLength: INTEGER;
    fill: FillHandle ← NIL;
    FOR i: CARDINAL IN [0..SpecialDisplay.DashCnt) DO
      widths[i] ← dashes.widths[i]*5/7; ENDLOOP;
    inc1 ← 0;
    inc2 ← widths[0];
    inc3 ← inc2 + widths[1];
    inc4 ← inc3 + widths[2];
    inc5 ← inc4 + widths[3];
    inc6 ← inc5 + widths[4];
    dashSum ← inc6 + widths[5];
    FOR r: WindowOps.RecList ← DisplayOps.FillList[window, filled], r.link 
      UNTIL r = NIL DO
      IF DisplayOps.Intersect[r, absBounds] THEN {
        ctx: Special = WindowOps.GetContext[r, context];
        left: INTEGER ← MAX[r.box.left, absBounds.left];
        top: INTEGER = MAX[r.box.top, absBounds.top];
        right: INTEGER ← MIN[r.box.right, absBounds.right];
        bottom: INTEGER = MIN[r.box.bottom, absBounds.bottom];
	IF top = bottom THEN GOTO nextRectangle;
	IF filled THEN {
	  left ← MAX[0, left];
	  right ← absBounds.right;
	  fillLength ← bottom - top;
	  fill ← ctx.alloc[window, top, fillLength];
	  fill.xs[0] ← left};
        FOR loopy: INTEGER IN [low..high) DO
          placey: INTEGER ← loopy;
          placex: INTEGER ← abs.x;
          tempX: INTEGER ← absX;
          bitAddress: WindowOps.ScanLine ←
            ctx.bmAddress + WindowOps.SpecialTimesWpl[INTEGER[placey], ctx];
          dashCnt ← 0;
          IF bottom - 1 < placey THEN {
            dashCnt ← (placey - bottom + 1) MOD dashSum;
            placex ← placex + placey - bottom + 1;
            bitAddress ←
              bitAddress-WindowOps.SpecialTimesWpl[INTEGER[placey-bottom+1],ctx];
            placey ← bottom - 1};
          IF left > placex THEN {
            dashCnt ← (left - placex + dashCnt) MOD dashSum;
            IF left > placey + placex THEN GOTO nextRectangle;
            placey ← placey + placex - left;
            bitAddress ←
              bitAddress - WindowOps.SpecialTimesWpl[INTEGER[left - placex], ctx];
            placex ← left};
          IF top > placey - tempX + placex THEN {
            IF top > placey + placex THEN GOTO nextRectangle;
            tempX ← placey + placex - top};
          IF right < tempX THEN tempX ← right - 1;
          IF tempX - placex <= 0 THEN LOOP;
          IF filled THEN fillcnt ← placey - top;
          FOR bitIndex: INTEGER IN [placex..tempX] DO
            IF filled THEN {
	      IF fillcnt ~IN [0..fillLength) THEN DisplayOps.LogError[];
	      fill.xs[fillcnt] ← bitIndex;
              fillcnt ← fillcnt - 1}
            ELSE {
              IF dashCnt IN [inc1..inc2) OR dashCnt IN [inc3..inc4)
                OR dashCnt IN [inc5..inc6) THEN {
                bitAddress[bitIndex] ←
                  (SELECT DisplayOps.Shade[flags] FROM
                     white => FALSE,
                     black => TRUE,
                     ENDCASE => ~bitAddress[bitIndex])};
              dashCnt ← (dashCnt + 1) MOD dashSum;
              bitAddress ← bitAddress - ctx.wpl};
            ENDLOOP;
          ENDLOOP;
        EXITS nextRectangle => NULL};
      ENDLOOP};

  Negative45Line: PUBLIC ENTRY PROC [
    window: Handle, place: Window.Place, stopX: INTEGER,
    bounds: Window.BoxHandle] = {
    -- This routine intersects the bounding box of any line displayed with the
    -- bounding box of each reclist.  Given this, the fact that start.y >= stop.y,
    -- and the specific type of line being delt with here it is assumed that:
    -- start.x >= r.box.left
    -- stop.x <= r.box.right
    -- start.y >= r.box.top
    -- stop.y <= r.box.bottom or else DisplayOps.Intersect fails.
    ENABLE UNWIND => NULL;
    absBounds: WindowOps.ScreenBox = WindowOps.AbsoluteBoxHandle[window, bounds];
    -- switch to screen coords
    abs: Window.Place = DisplayOps.AbsPlace[window, place];
    absX: INTEGER = stopX + window.place.x;
    startAddress: WindowOps.ScanLine =
      WindowOps.bitmapAddress + WindowOps.SpecialTimesWpl[INTEGER[abs.y]];
    IF ~window.inTree THEN RETURN;
    FOR r: WindowOps.RecList ← WindowOps.DisplayList[window], r.link UNTIL r = NIL
      DO
      IF DisplayOps.Intersect[r, absBounds] THEN {
        bitAddress: WindowOps.ScanLine ← startAddress;
        left: INTEGER = r.box.left;
        top: INTEGER = r.box.top;
        right: INTEGER = r.box.right;
        bottom: INTEGER = r.box.bottom;
	IF top = bottom THEN LOOP;
        IF DisplayOps.HasUnder[r] THEN {
          SpN45Internal[
            window, abs, absX, absBounds, SpecialDisplay.solid,
            Display.paintGrayFlags, SpecialDisplay.defaultContext];
          RETURN};
        place ← abs;
        stopX ← absX;
        IF bottom - 1 < place.y THEN {
          IF place.y > place.x + bottom - 1 THEN LOOP;
          place.x ← place.x + bottom - 1 - place.y;
          bitAddress ← bitAddress - WindowOps.SpecialTimesWpl[INTEGER[place.y-bottom+1]];
          place.y ← bottom - 1};
        IF right - 1 < place.x THEN {
          IF place.x > place.y + right - 1 THEN LOOP;
          place.y ← place.y + right - 1 - place.x;
          bitAddress ← bitAddress - WindowOps.SpecialTimesWpl[INTEGER[place.x-right+1]];
          place.x ← right - 1};
        IF top > place.y + stopX - place.x THEN stopX ← place.x - place.y + top;
        IF left > stopX THEN stopX ← left;
        FOR bitIndex: INTEGER DECREASING IN [stopX..place.x] DO
          bitAddress[bitIndex] ← TRUE;  -- set a bit
          bitAddress ← bitAddress - SpecialDisplay.defaultContext.wpl;
          ENDLOOP};
      ENDLOOP};

  SpNegative45Line: PUBLIC ENTRY PROC [
    window: Handle, place: Window.Place, stopX: INTEGER, bounds: Window.BoxHandle,
    dashes: LineStyle, flags: BitBlt.BitBltFlags,
    context: Special ← SpecialDisplay.defaultContext] = {
    -- This routine intersects the bounding box of any line displayed with the
    -- bounding box of each reclist.  Given this, the fact that start.y >= stop.y,
    -- and the specific type of line being delt with here it is assumed that:
    -- start.x >= r.box.left
    -- stop.x <= r.box.right
    -- start.y >= r.box.top
    -- stop.y <= r.box.bottom or else DisplayOps.Intersect fails.
    ENABLE UNWIND => NULL;
    IF window.inTree THEN {
      absBounds: WindowOps.ScreenBox = WindowOps.AbsoluteBoxHandle[window,bounds];
      -- switch to screen coords
      abs: Window.Place = DisplayOps.AbsPlace[window, place];
      absX: INTEGER = stopX + window.place.x;
      SpN45Internal[window, abs, absX, absBounds, dashes, flags, context]}};

  SpN45Internal: INTERNAL PROC [
    window: Handle, abs: Window.Place, absX: INTEGER,
    absBounds: WindowOps.ScreenBox, dashes: LineStyle, flags: BitBlt.BitBltFlags,
    context: Special] = {
    dashCnt, dashSum: CARDINAL;
    filled: BOOLEAN = context.alloc # NIL;
    widths: ARRAY [0..SpecialDisplay.DashCnt) OF CARDINAL;
    inc1, inc2, inc3, inc4, inc5, inc6: CARDINAL;
    low: INTEGER = abs.y - dashes.thickness/2;
    high: INTEGER = low + dashes.thickness;
    fillcnt, fillLength: INTEGER;
    fill: FillHandle ← NIL;
    FOR i: CARDINAL IN [0..SpecialDisplay.DashCnt) DO
      widths[i] ← dashes.widths[i]*5/7; ENDLOOP;
    inc1 ← 0;
    inc2 ← widths[0];
    inc3 ← inc2 + widths[1];
    inc4 ← inc3 + widths[2];
    inc5 ← inc4 + widths[3];
    inc6 ← inc5 + widths[4];
    dashSum ← inc6 + widths[5];
    FOR r: WindowOps.RecList ← DisplayOps.FillList[window, filled], r.link UNTIL r
      = NIL DO
      IF DisplayOps.Intersect[r, absBounds] THEN {
        ctx: Special = WindowOps.GetContext[r, context];
        left: INTEGER ← MAX[r.box.left, absBounds.left];
        top: INTEGER = MAX[r.box.top, absBounds.top];
        right: INTEGER ← MIN[r.box.right, absBounds.right];
        bottom: INTEGER = MIN[r.box.bottom, absBounds.bottom];
	IF top = bottom THEN GOTO nextRectangle;
	IF filled THEN {
	  left ← MAX[0, left];
	  right ← absBounds.right;
	  fillLength ← bottom - top;
          fill ← ctx.alloc[window, top, fillLength];
	  fill.xs[0] ← left};
        FOR loopy: INTEGER IN [low..high) DO
          placey: INTEGER ← loopy;
          placex: INTEGER ← abs.x;
          tempX: INTEGER ← absX;
          bitAddress: WindowOps.ScanLine ←
            ctx.bmAddress + WindowOps.SpecialTimesWpl[INTEGER[placey], ctx];
          dashCnt ← 0;
          IF bottom - 1 < placey THEN {
            dashCnt ← (placey - bottom + 1) MOD dashSum;
            IF placey > placex + bottom - 1 THEN GOTO nextRectangle;
            placex ← placex + bottom - 1 - placey;
            bitAddress ←
              bitAddress-WindowOps.SpecialTimesWpl[INTEGER[placey-bottom+1],ctx];
            placey ← bottom - 1};
          IF right - 1 < placex THEN {
            dashCnt ← (placex - right + 1 + dashCnt) MOD dashSum;
            IF placex > placey + right - 1 THEN GOTO nextRectangle;
            placey ← placey + right - 1 - placex;
            bitAddress ←
              bitAddress - WindowOps.SpecialTimesWpl[INTEGER[placex-right+1],ctx];
            placex ← right - 1};
          IF top > placey + tempX - placex THEN tempX ← placex - placey + top;
          IF left > tempX THEN tempX ← left;
          IF placex - tempX <= 0 THEN GOTO nextRectangle;
          IF filled THEN fillcnt ← placey - top;
          FOR bitIndex: INTEGER DECREASING IN [tempX..placex] DO
            IF filled THEN {
	      IF fillcnt ~IN [0..fillLength) THEN DisplayOps.LogError[];
              fill.xs[fillcnt] ← bitIndex;
              fillcnt ← fillcnt - 1}
            ELSE {
              IF dashCnt IN [inc1..inc2) OR dashCnt IN [inc3..inc4)
                OR dashCnt IN [inc5..inc6) THEN {
                bitAddress[bitIndex] ←
                  (SELECT DisplayOps.Shade[flags] FROM
                     white => FALSE,
                     black => TRUE,
                     ENDCASE => ~bitAddress[bitIndex])};
              dashCnt ← (dashCnt + 1) MOD dashSum;
              bitAddress ← bitAddress - ctx.wpl};
            ENDLOOP;
          ENDLOOP;
        EXITS nextRectangle => NULL};
      ENDLOOP};

  PositiveShallowLine: PUBLIC ENTRY PROC [
    window: Handle, start, stop: Window.Place, bounds: Window.BoxHandle] = {
    -- because it's positive and shallow, we know:
    --  start.x < stop.x
    --  start.y > stop.y
    --  stop.x - start.x > start.y - stop.y
    -- This routine intersects the bounding box of any line displayed with the
    -- bounding box of each reclist.  Given this, the fact that start.y >= stop.y,
    -- and the specific type of line being delt with here it is assumed that:
    -- start.x <= r.box.right
    -- stop.x >= r.box.left
    -- start.y >= r.box.top
    -- stop.y <= r.box.bottom or else DisplayOps.Intersect fails.
    ENABLE UNWIND => NULL;
    absBounds: WindowOps.ScreenBox = WindowOps.AbsoluteBoxHandle[window, bounds];
    -- switch to screen coords
    absStart: Window.Place = DisplayOps.AbsPlace[window, start];
    absStop: Window.Place = DisplayOps.AbsPlace[window, stop];
    startError: INTEGER = absStop.x - absStart.x;
    twox: INTEGER = startError*2;  -- positive
    twoy: CARDINAL = (absStart.y - absStop.y)*2;  -- positive
    startAddress: WindowOps.ScanLine =
      WindowOps.bitmapAddress + WindowOps.SpecialTimesWpl[INTEGER[absStart.y]];
    IF ~window.inTree THEN RETURN;
    FOR r: WindowOps.RecList ← WindowOps.DisplayList[window], r.link UNTIL r = NIL
      DO
      IF DisplayOps.Intersect[r, absBounds] THEN {
        bitAddress: WindowOps.ScanLine ← startAddress;
        left: INTEGER = r.box.left;
        top: INTEGER = r.box.top;
        right: INTEGER = r.box.right;
        bottom: INTEGER = r.box.bottom;
        error: INTEGER ← startError;
	IF top = bottom THEN LOOP;
        IF DisplayOps.HasUnder[r] THEN {
          SpPShInternal[
            window, absStart, absStop, absBounds, SpecialDisplay.solid,
            Display.paintGrayFlags, SpecialDisplay.defaultContext];
          RETURN};
        start ← absStart;
        stop ← absStop;
        IF bottom - 1 < start.y THEN {
          netError: LONG CARDINAL =
            Inline.LongMult[twox, start.y - bottom] + error;
          difx: INTEGER;
          [difx, error] ← Inline.LongDivMod[netError, twoy];
          error ← error + twox - twoy;
          start.x ← difx + start.x + 1;
          bitAddress ← bitAddress - WindowOps.SpecialTimesWpl[INTEGER[start.y-bottom+1]];
          start.y ← bottom - 1};
        IF left > start.x THEN {
          difx: NATURAL;
          netError: LONG INTEGER ← error - Inline.LongMult[twoy, left - start.x];
          start.x ← left;
          IF netError < 0 THEN {
            netError ← -netError;
            [difx, error] ← Inline.LongDivMod[netError, twox];
            IF error # 0 THEN {difx ← difx + 1; error ← twox - error};
            start.y ← start.y - difx;
            bitAddress ← bitAddress - WindowOps.SpecialTimesWpl[difx]}
          ELSE error ← Inline.LowHalf[netError]};
        IF top > stop.y THEN {
          netError: LONG CARDINAL;
          difx, errorTemp: INTEGER;
          IF start.y < top THEN LOOP;
          netError ← Inline.LongMult[twox, start.y - top] + error;
          [difx, errorTemp] ← Inline.LongDivMod[netError, twoy];
          stop.x ← difx + start.x};
        IF right - 1 < stop.x THEN stop.x ← right - 1;
        FOR bitIndex: INTEGER IN [start.x..stop.x] DO
          bitAddress[bitIndex] ← TRUE;  -- invert a bit
          error ← error - twoy;
          IF error < 0 THEN {
            bitAddress ← bitAddress - SpecialDisplay.defaultContext.wpl; error ← error + twox};
          ENDLOOP};
      ENDLOOP};

  SpPositiveShallowLine: PUBLIC ENTRY PROC [
    window: Handle, start, stop: Window.Place, bounds: Window.BoxHandle,
    dashes: LineStyle, flags: BitBlt.BitBltFlags,
    context: Special ← SpecialDisplay.defaultContext] = {
    -- because it's positive and shallow, we know:
    --  start.x < stop.x
    --  start.y > stop.y
    --  stop.x - start.x > start.y - stop.y
    -- This routine intersects the bounding box of any line displayed with the
    -- bounding box of each reclist.  Given this, the fact that start.y >= stop.y,
    -- and the specific type of line being delt with here it is assumed that:
    -- start.x <= r.box.right
    -- stop.x >= r.box.left
    -- start.y >= r.box.top
    -- stop.y <= r.box.bottom or else DisplayOps.Intersect fails.
    ENABLE UNWIND => NULL;
    IF window.inTree THEN {
      absBounds: WindowOps.ScreenBox = WindowOps.AbsoluteBoxHandle[window,bounds];
      -- switch to screen coords
      absStart: Window.Place = DisplayOps.AbsPlace[window, start];
      absStop: Window.Place = DisplayOps.AbsPlace[window, stop];
      SpPShInternal[
        window, absStart, absStop, absBounds, dashes, flags, context]}};

  SpPShInternal: INTERNAL PROC [
    window: Handle, absStart, absStop: Window.Place,
    absBounds: WindowOps.ScreenBox, dashes: LineStyle, flags: BitBlt.BitBltFlags,
    context: Special] = {
    startError: INTEGER = absStop.x - absStart.x;
    twox: INTEGER = startError*2;  -- positive
    twoy: CARDINAL = (absStart.y - absStop.y)*2;  -- positive
    dashCnt, dashSum: CARDINAL;
    filled: BOOLEAN = context.alloc # NIL;
    widths: ARRAY [0..SpecialDisplay.DashCnt) OF CARDINAL;
    inc1, inc2, inc3, inc4, inc5, inc6: CARDINAL;
    low: INTEGER = absStart.y - dashes.thickness/2;
    high: INTEGER = low + dashes.thickness;
    difY: INTEGER ← absStop.y - absStart.y;
    fill: FillHandle ← NIL;
    fillcnt, fillLength: INTEGER;
    dashstretch: CARDINAL =
      SELECT twox FROM
        > twoy*15/4 => 13,  -- 0 to 15 degrees
        > twoy*7/4 => 12,  -- 15 to 30 degrees
        ENDCASE => 11;  -- 30 to 45 degrees
    FOR i: CARDINAL IN [0..SpecialDisplay.DashCnt) DO
      widths[i] ← dashes.widths[i]*dashstretch/14; ENDLOOP;
    inc1 ← 0;
    inc2 ← widths[0];
    inc3 ← inc2 + widths[1];
    inc4 ← inc3 + widths[2];
    inc5 ← inc4 + widths[3];
    inc6 ← inc5 + widths[4];
    dashSum ← 0;
    FOR i: CARDINAL IN [0..SpecialDisplay.DashCnt) DO
      dashSum ← dashSum + widths[i]; ENDLOOP;
    FOR r: WindowOps.RecList ← DisplayOps.FillList[window, filled], r.link 
      UNTIL r = NIL DO
      IF DisplayOps.Intersect[r, absBounds] THEN {
        ctx: Special = WindowOps.GetContext[r, context];
        left: INTEGER ← MAX[r.box.left, absBounds.left];
        top: INTEGER = MAX[r.box.top, absBounds.top];
        right: INTEGER ← MIN[r.box.right, absBounds.right];
        bottom: INTEGER = MIN[r.box.bottom, absBounds.bottom];
	IF top = bottom THEN GOTO nextRectangle;
	IF filled THEN {
	  left ← MAX[0, left];
	  right ← absBounds.right;
	  fillLength ← bottom - top;
	  fill ← ctx.alloc[window, top, fillLength];
	  fill.xs[0] ← left};
        FOR loopy: INTEGER IN [low..high) DO
          startX: INTEGER ← absStart.x;
          startY: INTEGER ← loopy;
          stopX: INTEGER ← absStop.x;
          stopY: INTEGER ← startY + difY;
          error: INTEGER ← startError;
          bitAddress: WindowOps.ScanLine ←
            ctx.bmAddress + WindowOps.SpecialTimesWpl[INTEGER[startY], ctx];
          dashCnt ← 0;
          IF bottom - 1 < startY THEN {
            netError: LONG CARDINAL =
              Inline.LongMult[twox, startY - bottom] + error;
            difx: INTEGER;
            [difx, error] ← Inline.LongDivMod[netError, twoy];
            error ← error + twox - twoy;
            startX ← difx + startX + 1;
            dashCnt ← (difx + 1) MOD dashSum;
            bitAddress ←
              bitAddress-WindowOps.SpecialTimesWpl[INTEGER[startY-bottom+1],ctx];
            startY ← bottom - 1};
          IF left > startX THEN {
            difx: NATURAL;
            netError: LONG INTEGER ← error - Inline.LongMult[twoy, left - startX];
            dashCnt ← (left - startX + dashCnt) MOD dashSum;
            startX ← left;
            IF netError < 0 THEN {
              netError ← -netError;
              [difx, error] ← Inline.LongDivMod[netError, twox];
              IF error # 0 THEN {difx ← difx + 1; error ← twox - error};
              startY ← startY - difx;
              bitAddress ← bitAddress - WindowOps.SpecialTimesWpl[difx, ctx]}
            ELSE error ← Inline.LowHalf[netError]};
          IF top > stopY THEN {
            netError: LONG CARDINAL;
            difx, errorTemp: INTEGER;
            IF startY < top THEN GOTO nextRectangle;
            netError ← Inline.LongMult[twox, startY - top] + error;
            [difx, errorTemp] ← Inline.LongDivMod[netError, twoy];
            stopX ← difx + startX;
            stopY ← top};
          IF right - 1 < stopX THEN {
            IF filled THEN {
              difx: CARDINAL;
              errorTemp: INTEGER;
              netError: LONG INTEGER;
              IF right <= startX + 1 THEN GOTO nextRectangle;
              netError ← error - Inline.LongMult[twoy, right - 1 - startX];
              IF netError < 0 THEN {
                netError ← -netError;
                [difx, errorTemp] ← Inline.LongDivMod[netError, twox];
                IF errorTemp # 0 THEN difx ← difx + 1;
                stopY ← startY - difx}};
            stopX ← right - 1};
          IF startY - stopY < 0 THEN GOTO nextRectangle;
          IF filled THEN {
	    fillcnt ← startY - top;
	    fill.xs[fillcnt] ← MAX[startX, 0];
	    fill.xs[0] ← MAX[stopX, 0]};
          FOR bitIndex: INTEGER IN [startX..stopX] DO
            IF ~filled THEN {
              IF dashCnt IN [inc1..inc2) OR dashCnt IN [inc3..inc4)
                OR dashCnt IN [inc5..inc6) THEN
                bitAddress[bitIndex] ←
                  (SELECT DisplayOps.Shade[flags] FROM
                     white => FALSE,
                     black => TRUE,
                     ENDCASE => ~bitAddress[bitIndex]);
              dashCnt ← (dashCnt + 1) MOD dashSum};
            error ← error - twoy;
            IF error < 0 THEN {
              IF filled THEN {
                IF fillcnt ~IN [0..fillLength) THEN DisplayOps.LogError[];
		fill.xs[fillcnt] ← bitIndex;
		fillcnt ← fillcnt - 1}
              ELSE bitAddress ← bitAddress - ctx.wpl;
              error ← error + twox};
            ENDLOOP;
          ENDLOOP;
        EXITS nextRectangle => NULL};
      ENDLOOP};

  NegativeShallowLine: PUBLIC ENTRY PROC [
    window: Handle, start, stop: Window.Place, bounds: Window.BoxHandle] = {
    -- because it's positive and shallow, we know:
    --  start.x > stop.x
    --  start.y > stop.y
    --  start.x - stop.x > start.y - stop.y
    -- This routine intersects the bounding box of any line displayed with the
    -- bounding box of each reclist.  Given this, the fact that start.y >= stop.y,
    -- and the specific type of line being delt with here it is assumed that:
    -- start.x >= r.box.left
    -- stop.x <= r.box.right
    -- start.y >= r.box.top
    -- stop.y <= r.box.bottom or else DisplayOps.Intersect fails.
    ENABLE UNWIND => NULL;
    absBounds: WindowOps.ScreenBox = WindowOps.AbsoluteBoxHandle[window, bounds];
    -- switch to screen coords
    absStart: Window.Place = DisplayOps.AbsPlace[window, start];
    absStop: Window.Place = DisplayOps.AbsPlace[window, stop];
    startError: INTEGER = absStart.x - absStop.x;
    twox: INTEGER = startError*2;  -- positive
    twoy: CARDINAL = (absStart.y - absStop.y)*2;  -- positive
    startAddress: WindowOps.ScanLine =
      WindowOps.bitmapAddress + WindowOps.SpecialTimesWpl[INTEGER[absStart.y]];
    IF ~window.inTree THEN RETURN;
    FOR r: WindowOps.RecList ← WindowOps.DisplayList[window], r.link
      UNTIL r = NIL DO
      IF DisplayOps.Intersect[r, absBounds] THEN {
        bitAddress: WindowOps.ScanLine ← startAddress;
        left: INTEGER = r.box.left;
        top: INTEGER = r.box.top;
        right: INTEGER = r.box.right;
        bottom: INTEGER = r.box.bottom;
        error: INTEGER ← startError;
	IF top = bottom THEN LOOP;
        IF DisplayOps.HasUnder[r] THEN {
          SpNShInternal[
            window, absStart, absStop, absBounds, SpecialDisplay.solid,
            Display.paintGrayFlags, SpecialDisplay.defaultContext];
          RETURN};
        start ← absStart;
        stop ← absStop;
        IF bottom - 1 < start.y THEN {
          netError: LONG CARDINAL =
            Inline.LongMult[twox, start.y - bottom] + error;
          difx: INTEGER;
          [difx, error] ← Inline.LongDivMod[netError, twoy];
          error ← error + twox - twoy;
          start.x ← start.x - difx - 1;
          bitAddress ← bitAddress - WindowOps.SpecialTimesWpl[INTEGER[start.y-bottom+1]];
          start.y ← bottom - 1};
        IF right - 1 < start.x THEN {
          difx: NATURAL;
          netError: LONG INTEGER ←
            error - Inline.LongMult[twoy, start.x - right + 1];
          start.x ← right - 1;
          IF netError < 0 THEN {
            netError ← -netError;
            [difx, error] ← Inline.LongDivMod[netError, twox];
            IF error # 0 THEN {difx ← difx + 1; error ← twox - error};
            start.y ← start.y - difx;
            bitAddress ← bitAddress - WindowOps.SpecialTimesWpl[difx]}
          ELSE error ← Inline.LowHalf[netError]};
        IF top > stop.y THEN {
          netError: LONG CARDINAL;
          difx, errorTemp: INTEGER;
          IF start.y < top THEN LOOP;
          netError ← Inline.LongMult[twox, start.y - top] + error;
          [difx, errorTemp] ← Inline.LongDivMod[netError, twoy];
          stop.x ← start.x - difx};
        IF left > stop.x THEN stop.x ← left;
        FOR bitIndex: INTEGER DECREASING IN [stop.x..start.x] DO
          bitAddress[bitIndex] ← TRUE;  -- set a bit
          error ← error - twoy;
          IF error < 0 THEN {
            bitAddress ← bitAddress - SpecialDisplay.defaultContext.wpl; error ← error + twox};
          ENDLOOP};
      ENDLOOP};

  SpNegativeShallowLine: PUBLIC ENTRY PROC [
    window: Handle, start, stop: Window.Place, bounds: Window.BoxHandle,
    dashes: LineStyle, flags: BitBlt.BitBltFlags,
    context: Special ← SpecialDisplay.defaultContext] = {
    -- because it's positive and shallow, we know:
    --  start.x > stop.x
    --  start.y > stop.y
    --  start.x - stop.x > start.y - stop.y
    -- This routine intersects the bounding box of any line displayed with the
    -- bounding box of each reclist.  Given this, the fact that start.y >= stop.y,
    -- and the specific type of line being delt with here it is assumed that:
    -- start.x >= r.box.left
    -- stop.x <= r.box.right
    -- start.y >= r.box.top
    -- stop.y <= r.box.bottom or else DisplayOps.Intersect fails.
    ENABLE UNWIND => NULL;
    IF window.inTree THEN {
      absBounds: WindowOps.ScreenBox = WindowOps.AbsoluteBoxHandle[window,bounds];
      -- switch to screen coords
      absStart: Window.Place = DisplayOps.AbsPlace[window, start];
      absStop: Window.Place = DisplayOps.AbsPlace[window, stop];
      SpNShInternal[
        window, absStart, absStop, absBounds, dashes, flags, context]}};

  SpNShInternal: INTERNAL PROC [
    window: Handle, absStart, absStop: Window.Place,
    absBounds: WindowOps.ScreenBox, dashes: LineStyle, flags: BitBlt.BitBltFlags,
    context: Special] = {
    startError: INTEGER = absStart.x - absStop.x;
    twox: INTEGER = startError*2;  -- positive
    twoy: CARDINAL = (absStart.y - absStop.y)*2;  -- positive
    dashCnt, dashSum: CARDINAL;
    filled: BOOLEAN = context.alloc # NIL;
    widths: ARRAY [0..SpecialDisplay.DashCnt) OF CARDINAL;
    inc1, inc2, inc3, inc4, inc5, inc6: CARDINAL;
    low: INTEGER = absStart.y - dashes.thickness/2;
    high: INTEGER = low + dashes.thickness;
    difY: INTEGER ← absStop.y - absStart.y;
    fill: FillHandle ← NIL;
    fillcnt, fillLength: INTEGER;
    dashstretch: CARDINAL =
      SELECT twox FROM
        > twoy*15/4 => 13,  -- 0 to 15 degrees
        > twoy*7/4 => 12,  -- 15 to 30 degrees
        ENDCASE => 11;  -- 30 to 45 degrees
    FOR i: CARDINAL IN [0..SpecialDisplay.DashCnt) DO
      widths[i] ← dashes.widths[i]*dashstretch/14; ENDLOOP;
    inc1 ← 0;
    inc2 ← widths[0];
    inc3 ← inc2 + widths[1];
    inc4 ← inc3 + widths[2];
    inc5 ← inc4 + widths[3];
    inc6 ← inc5 + widths[4];
    dashSum ← 0;
    FOR i: CARDINAL IN [0..SpecialDisplay.DashCnt) DO
      dashSum ← dashSum + widths[i]; ENDLOOP;
    FOR r: WindowOps.RecList ← DisplayOps.FillList[window, filled], r.link 
      UNTIL r = NIL DO
      IF DisplayOps.Intersect[r, absBounds] THEN {
        ctx: Special = WindowOps.GetContext[r, context];
        left: INTEGER ← MAX[r.box.left, absBounds.left];
        top: INTEGER = MAX[r.box.top, absBounds.top];
        right: INTEGER ← MIN[r.box.right, absBounds.right];
        bottom: INTEGER = MIN[r.box.bottom, absBounds.bottom];
	IF top = bottom THEN GOTO nextRectangle;
	IF filled THEN {
	  left ← MAX[0, left];
	  right ← absBounds.right;
	  fillLength ← bottom - top;
          fill ← ctx.alloc[window, top, fillLength];
	  fill.xs[0] ← left};
        FOR loopy: INTEGER IN [low..high) DO
          startX: INTEGER ← absStart.x;
          startY: INTEGER ← loopy;
          stopX: INTEGER ← absStop.x;
          stopY: INTEGER ← startY + difY;
          error: INTEGER ← startError;
          bitAddress: WindowOps.ScanLine ←
            ctx.bmAddress + WindowOps.SpecialTimesWpl[INTEGER[startY], ctx];
          dashCnt ← 0;
          IF bottom - 1 < startY THEN {
            netError: LONG CARDINAL =
              Inline.LongMult[twox, startY - bottom] + error;
            difx: INTEGER;
            [difx, error] ← Inline.LongDivMod[netError, twoy];
            error ← error + twox - twoy;
            startX ← startX - difx - 1;
            dashCnt ← (difx + 1) MOD dashSum;
            bitAddress ←
              bitAddress-WindowOps.SpecialTimesWpl[INTEGER[startY-bottom+1],ctx];
            startY ← bottom - 1};
          IF right - 1 < startX THEN {
            difx: NATURAL;
            netError: LONG INTEGER ←
              error - Inline.LongMult[twoy, startX - right + 1];
            dashCnt ← (startX - right + 1 + dashCnt) MOD dashSum;
            startX ← right - 1;
            IF netError < 0 THEN {
              netError ← -netError;
              [difx, error] ← Inline.LongDivMod[netError, twox];
              IF error # 0 THEN {difx ← difx + 1; error ← twox - error};
              startY ← startY - difx;
              bitAddress ← bitAddress - WindowOps.SpecialTimesWpl[difx, ctx]}
            ELSE error ← Inline.LowHalf[netError]};
          IF top > stopY THEN {
            netError: LONG CARDINAL;
            difx, errorTemp: INTEGER;
            IF startY < top THEN GOTO nextRectangle;
            netError ← Inline.LongMult[twox, startY - top] + error;
            [difx, errorTemp] ← Inline.LongDivMod[netError, twoy];
            stopX ← startX - difx;
            stopY ← top};
          IF left > stopX THEN {
            IF filled THEN {
              difx: CARDINAL;
              errorTemp: INTEGER;
              netError: LONG INTEGER;
              IF startX <= left THEN GOTO nextRectangle;
              netError ← error - Inline.LongMult[twoy, startX - left];
              IF netError < 0 THEN {
                netError ← -netError;
                [difx, errorTemp] ← Inline.LongDivMod[netError, twox];
                IF errorTemp # 0 THEN difx ← difx + 1;
                stopY ← startY - difx}};
            stopX ← left};
          IF startY - stopY < 0 THEN GOTO nextRectangle;
          IF filled THEN {
            fillcnt ← startY - top;
	    fill.xs[fillcnt] ← MAX[startX, 0];
	    fill.xs[0] ← MAX[stopX, 0]};
          FOR bitIndex: INTEGER DECREASING IN [stopX..startX] DO
            IF ~filled THEN {
              IF dashCnt IN [inc1..inc2) OR dashCnt IN [inc3..inc4)
                OR dashCnt IN [inc5..inc6) THEN
                bitAddress[bitIndex] ←
                  (SELECT DisplayOps.Shade[flags] FROM
                     white => FALSE,
                     black => TRUE,
                     ENDCASE => ~bitAddress[bitIndex]);
              dashCnt ← (dashCnt + 1) MOD dashSum};
            error ← error - twoy;
            IF error < 0 THEN {
              IF filled THEN {
	        IF fillcnt ~IN [0..fillLength) THEN DisplayOps.LogError[];
	        fill.xs[fillcnt] ← bitIndex;
                fillcnt ← fillcnt - 1}
              ELSE bitAddress ← bitAddress - ctx.wpl;
              error ← error + twox};
            ENDLOOP;
          ENDLOOP;
        EXITS nextRectangle => NULL};
      ENDLOOP};

  END.