-- Copyright (C) 1982, 1983  by Xerox Corporation. All rights reserved. 
-- DisplayOps.mesa - last edited by 
  -- Bruce	24-Feb-83 19:04:31
  -- Steve	 6-Oct-82 15:46:32
  -- Rick	28-Oct-83 15:28:17
  
DIRECTORY
  BitBlt USING [BitBltFlags],
  Display USING [Brick],
  DisplayFormat USING [CircleType],
  Inline USING [DIVMOD, LongDivMod],
  SpecialDisplay USING [defaultContext, Special],
  WindowOps USING [Handle, GetRecList, RecList, Rectangle, ScreenBox],
  Window USING [BoxHandle, Handle, Place];
  
DisplayOps: DEFINITIONS IMPORTS Inline, SpecialDisplay, WindowOps 
  SHARES WindowOps = 
  BEGIN
  
  Color: TYPE = {white, black, invert};

  FillHandle: TYPE = LONG POINTER TO FillObject;
  FillObject: TYPE = RECORD [
    link: FillHandle, 
    start, length, saveLength: CARDINAL, xs: ARRAY [0..0) OF CARDINAL];
  
  fillRec: WindowOps.Rectangle;
  
  -- window utilities
  
  HasUnder: PROC [r: WindowOps.RecList] RETURNS [BOOLEAN] = INLINE {
    RETURN[r.dst # NIL]};
     
  AbsPlace: --INTERNAL-- PROC [w: WindowOps.Handle, rel: Window.Place] 
    RETURNS [abs: Window.Place] =
    INLINE {abs.x ← rel.x + w.place.x; abs.y ← rel.y + w.place.y};

  FillList: --INTERNAL-- PROC [w: WindowOps.Handle, filled: BOOLEAN]
    RETURNS [WindowOps.RecList] = INLINE {
    IF filled THEN RETURN[@fillRec]; 
    RETURN[  -- copied from WindowOps.DisplayList
      IF w.beingDisplayed AND w.badPhosphor # NIL THEN w.badPhosphor 
      ELSE WindowOps.GetRecList[w]]};
      
  SpecialFilledCircle: PROC [
    window: Window.Handle, place: Window.Place, radius: INTEGER,
    gray: Display.Brick, flags: BitBlt.BitBltFlags,
    circleType: DisplayFormat.CircleType ← ALL[FALSE], bounds: Window.BoxHandle,
    context: SpecialDisplay.Special ← SpecialDisplay.defaultContext];

  Intersect: --INTERNAL-- PROC [r: WindowOps.RecList, b: WindowOps.ScreenBox]
    RETURNS [BOOLEAN] = INLINE {
    RETURN[
      b.left < r.box.right AND r.box.left < b.right AND b.top < r.box.bottom
        AND r.box.top < b.bottom]};

  Shade: --INTERNAL-- PROC [flags: BitBlt.BitBltFlags] RETURNS [Color] = INLINE {
    RETURN[
      SELECT flags.dstFunc FROM xor => invert, or => black, ENDCASE => white]};

  -- arithmetic utilities
   
  DIVMOD: PROC [num: INTEGER, den: CARDINAL] 
    RETURNS [quotient: INTEGER, remainder: CARDINAL] = INLINE {
    IF num < 0 THEN {
      num ← - num;
      [quotient: quotient, remainder: remainder] ← Inline.DIVMOD[num, den];
      IF remainder # 0 THEN {
        quotient ← quotient + 1; remainder ← den - remainder};
      quotient ← -quotient}
    ELSE [quotient: quotient, remainder: remainder] ← Inline.DIVMOD[num, den]};

  LongDivMod: PROC [num: LONG INTEGER, den: CARDINAL] 
    RETURNS [quotient: INTEGER, remainder: CARDINAL] = INLINE {
    IF num < 0 THEN {
      num ← - num;
      [quotient: quotient, remainder: remainder] ← Inline.LongDivMod[num, den];
      IF remainder # 0 THEN {
        quotient ← quotient + 1; remainder ← den - remainder};
      quotient ← -quotient}
    ELSE 
      [quotient: quotient, remainder: remainder] ← Inline.LongDivMod[num, den]};
  
  -- internal bugs
  
  Code: TYPE = {
    fillBoundsFault, infiniteConicDDALoop, fillStackBug, spare1, spare2, spare3};
  
  LogError: PROC [code: Code ← fillBoundsFault];  -- does a CallDebugger
  
  END.