static char *SccsId = "@(#)gln.c 4.3 (TU-Delft) 04/16/93";
/**********************************************************

Name/Version      : makegln/4.3

Language          : C
Operating system  : UNIX SYSTEM V
Host machine      : HP9000

Author            : N.P. van der Meijs
Creation date     : 15-Mar-1988
Modified by       :
Modification date :


        Delft University of Technology
        Department of Electrical Engineering
        Network Theory Section
        Mekelweg 4 - P.O.Box 5031
        2600 GA DELFT
        The Netherlands

        Phone : 015 - 786234

        COPYRIGHT (C) 1988. All rights reserved.
**********************************************************/
#include "config.h"
#include <stdio.h>
#include "aux/aux.h"
#include "makegln.h"

/*  How to read next mnemonics.
    Two characters, first is for left of scanline, second for right.
	B means blank
	S means solid
	D means solid below current y, blank above
	U means solid above current y, blank below

    Examples:
		  s|s
        SU means  -+-
		  s|b

		  s|s
        UU means  -+-
		  b|b
	    
*/

#define BB   0
#define BD  01		/* begin stop edge  */
#define BU  02		/* begin start edge */
#define BS  03
#define DB  04
#define DD  05
#define DU  06
#define DS  07
#define UB 010
#define UD 011
#define UU 012
#define US 013
#define SB 014
#define SD 015
#define SU 016
#define SS 017


#ifdef DEBUG
static char * codes[] = {
    /* BB */ "void",
    /* BD */ "begin stop edge",
    /* BU */ "begin start edge",
    /* BS */ "void",
    /* DB */ "end stop edge",
    /* DD */ "void",
    /* DU */ "end stop, begin start",
    /* DS */ "end stop edge",
    /* UB */ "end start edge",
    /* UD */ "end start, begin stop",
    /* UU */ "void",
    /* US */ "end start edge",
    /* SB */ "void",
    /* SD */ "begin stop edge",
    /* SU */ "begin start edge",
    /* SS */ "void"
};
#endif DEBUG

void glnUpdate (edge, x)
edge_t * edge;
coor_t   x;
{
    register unsigned code;
    edge_t * newEdge;
    edge_t * createEdge ();
    static int nw = 0, ne = 0,
               sw = 0, se = 0;

#ifdef ASSERT
    static int prevX = -INF;
    ASSERT (x == prevX || (nw == 0 && ne == 0 && sw == 0 && se == 0));
    prevX = x;
#endif ASSERT

    if (edge -> xl < x) nw += edge -> signLeft;
    if (edge -> xr > x) ne += edge -> sign;

    ASSERT (nw >= 0);
    ASSERT (ne >= 0);

#ifndef DEBUG
    if (nw == ne && sw == se) {
	se = sw = nw;
	ASSERT (edge -> signLeft == edge -> sign);
	return;
    }
#endif DEBUG

    if (se) code  =  01; else code = 0;
    if (ne) code |=  02;
    if (sw) code |=  04;
    if (nw) code |= 010;

#ifdef DEBUG
    if (DEBUG) {
	printEdge ("evalCode", edge);
	fprintf (stderr, "nw: %d ne: %d sw: %d se: %d code: 0%o (%s)\n",
	    nw, ne, sw, se, code, codes[code]);
    }
#endif DEBUG

    switch (code) {
        case BD:		/* begin stop edge  	 */
        case BU:		/* begin start edge 	 */
        case SD:		/* begin stop edge 	 */
        case SU:		/* begin start edge 	 */
	    newEdge = createEdge (x, Y (edge, x), 0, 0, edge -> slope, 0);
	    selectForOutput (newEdge);
	    edge -> next = newEdge;
	    break;
        case DB:		/* end stop edge 	 */
        case DS:		/* end stop edge 	 */
        case UB:		/* end start edge 	 */
        case US:		/* end start edge 	 */
	    ASSERT (edge -> next);
	    edge -> next -> xr = x;
	    edge -> next -> yr = Y (edge, x);
	    readyForOutput (edge -> next);
	    break;
        case DU:		/* end stop, begin start */
        case UD:		/* end start, begin stop */
	    ASSERT (edge -> next);
	    edge -> next -> xr = x;
	    edge -> next -> yr = Y (edge, x);
	    readyForOutput (edge -> next);
	    newEdge = createEdge (x, Y (edge, x), 0, 0, edge -> slope, 0);
	    selectForOutput (newEdge);
	    edge -> next = newEdge;
	    break;
#ifndef DEBUG
        case BB:		/* void 		 */
        case BS:		/* void 		 */
        case DD:		/* void 		 */
        case UU:		/* void 		 */
        case SB:		/* void 		 */
        case SS:		/* void 		 */
	   break;
	default: 
	    say ("evalCode: bad code: 0%o", code);
#endif DEBUG
    }

    sw = nw, se = ne;
    edge -> signLeft = edge -> sign;
}
