/****
 *
 * Copyright (c) 1988 by Sun Microsystems, Inc.
 * @(#)sh_draw.h 22.1 89/08/10 Copyright 1988 Sun Micro
 *
 * Drawing / Path Construction operators. If SH_DRAW_FUNC is defined,
 * these are all based on the "Draw" operator and are implemented
 * by function dispatch thru the CONTEXT. If SH_DRAW_FUNC is NOT defined,
 * they are implemented as macros.
 *
 * Draw(ctx, p)			draw from POINT
 * Draw_B2D(ctx, x, y)		draw B2D coordinates
 * Draw_B3D(ctx, x, y, z)	draw B3D coordinates
 * Draw_B3H(ctx, x, y, z, w)	draw B3D coordinates
 * Draw_F2D(ctx, x, y)		draw F2D coordinates
 * Draw_F3D(ctx, x, y, z)	draw F3D coordinates
 * Draw_F3H(ctx, x, y, z, w)	draw F3D coordinates
 * Curve(ctx, type, order)	set curve type and order
 * Color(ctx, c)		set foreground color
 * Close(ctx)			close current area/path
 *
 ****/
#ifndef	_SH_DRAW
#include "sh_CTX.h"

#define Draw(CTX, p) do {	                      			\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        *PPTR++ = *((PATH_POINT *) (p));				\
	(CTX)->ctx_buf_ptr = PPTR;					\
        if (PPTR >= (CTX)->ctx_buf_end) Extend_Context(CTX);		\
        } while(0)

#define Draw_B2D(CTX, T, X, Y) do {					\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        PPTR->b.t = (T) | PT_BIN2D;					\
	PPTR->b.x = (X); (PPTR++)->b.y = (Y);				\
	(CTX)->ctx_buf_ptr = PPTR;					\
        if (PPTR >= (CTX)->ctx_buf_end) Extend_Context(CTX);		\
        } while(0)

#define Draw_B2H(CTX, T, X, Y, W) do {					\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        if (PPTR + 2 >= (CTX)->ctx_buf_end)				\
	  { Extend_Context(CTX); PPTR = (CTX)->ctx_buf_ptr; }		\
        PPTR->b.t = (T) | PT_BIN2H;					\
	PPTR->b.x = (X); (PPTR++)->b.y = (Y);				\
	PPTR->b.t = PT_W; (PPTR++)->b.x = (W);				\
	(CTX)->ctx_buf_ptr = PPTR;					\
        } while (0)

#define Draw_B3D(CTX, T, X, Y, Z) do {					\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        PPTR->b.t = (T) | PT_BIN3D; PPTR->b.x = (X);			\
	PPTR->b.y = (Y); (PPTR++)->b.z = (Z);				\
	(CTX)->ctx_buf_ptr = PPTR;					\
        if (PPTR >= (CTX)->ctx_buf_end) Extend_Context(CTX);		\
        } while (0)

#define Draw_B3H(CTX, T, X, Y, Z, W) do {				\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        if (PPTR + 2 >= (CTX)->ctx_buf_end)				\
	  { Extend_Context(CTX); PPTR = (CTX)->ctx_buf_ptr; }		\
        PPTR->b.t = (T) | PT_BIN3H; PPTR->b.x = (X);			\
	PPTR->b.y = (Y); (PPTR++)->b.z = (Z);				\
	PPTR->b.t = PT_W; (PPTR++)->b.x = (W);				\
	(CTX)->ctx_buf_ptr = PPTR;					\
        } while (0)

#define Draw_F2D(CTX, T, X, Y) do {					\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        PPTR->f.t = (T) | PT_FLT2D;					\
	PPTR->f.x = (X); (PPTR++)->f.y = (Y);				\
	(CTX)->ctx_buf_ptr = PPTR;					\
        if (PPTR >= (CTX)->ctx_buf_end) Extend_Context(CTX);		\
        } while (0)

#define Draw_F2H(CTX, T, X, Y, W) do {					\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        if (PPTR + 2 >= (CTX)->ctx_buf_end)				\
	  { Extend_Context(CTX); PPTR = (CTX)->ctx_buf_ptr; }		\
        PPTR->f.t = (T) | PT_FLT2H;					\
	PPTR->f.x = (X); (PPTR++)->f.y = (Y);				\
	PPTR->f.t = PT_W; (PPTR++)->f.x = (W);				\
	(CTX)->ctx_buf_ptr = PPTR;					\
        } while (0)

#define Draw_F3D(CTX, T, X, Y, Z) do {					\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        PPTR->f.t = (T) | PT_FLT3D; PPTR->f.x = (X);			\
	PPTR->f.y = (Y); (PPTR++)->f.z = (Z);				\
	(CTX)->ctx_buf_ptr = PPTR;					\
        if (PPTR >= (CTX)->ctx_buf_end) Extend_Context(CTX);		\
        } while (0)

#define Draw_F3H(CTX, T, X, Y, Z, W) do {				\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        if (PPTR + 2 >= (CTX)->ctx_buf_end)				\
	  { Extend_Context(CTX); PPTR = (CTX)->ctx_buf_ptr; }		\
        PPTR->f.t = (T) | PT_FLT3H; 					\
	PPTR->f.x = (X);						\
	PPTR->f.y = (Y); (PPTR++)->f.z = (Z);				\
	PPTR->f.t = PT_W; (PPTR++)->f.x = (W);				\
	(CTX)->ctx_buf_ptr = PPTR;					\
        } while (0)

#define Draw_I2D(CTX, T, X, Y) do {					\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        PPTR->b.t = (T) | PT_BIN2D; PPTR->b.x = fracti(X);		\
	(PPTR++)->b.y = fracti(Y);					\
	(CTX)->ctx_buf_ptr = PPTR;					\
        if (PPTR >= (CTX)->ctx_buf_end) Extend_Context(CTX);		\
        } while (0)

#define Draw_I2H(CTX, T, X, Y, W) do {					\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        if (PPTR + 2 >= (CTX)->ctx_buf_end) Extend_Context(CTX);	\
        PPTR->b.t = (T) | PT_BIN2H;					\
	PPTR->b.x = fracti(X); (PPTR++)->b.y = fracti(Y);		\
	PPTR->b.t = PT_W; (PPTR++)->b.x = fracti(W);			\
	(CTX)->ctx_buf_ptr = PPTR;					\
        } while (0)

#define Draw_I3D(CTX, T, X, Y, Z) do {					\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        PPTR->b.t = (T) | PT_BIN3D; PPTR->b.x = fracti(X);		\
	PPTR->b.y = fracti(Y); (PPTR++)->b.z = fracti(Z);		\
	(CTX)->ctx_buf_ptr = PPTR;					\
        if (PPTR >= (CTX)->ctx_buf_end) Extend_Context(CTX);		\
        } while (0)

#define Draw_I3H(CTX, T, X, Y, Z, W) do {				\
register POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        PPTR->b.t = (T) | PT_BIN3H; PPTR->b.x = fracti(X);		\
	PPTR->b.y = fracti(Y); (PPTR++)->b.z = fracti(Z);		\
	PPTR->b.t = PT_W; (PPTR++)->b.x = fracti(W);			\
	(CTX)->ctx_buf_ptr = PPTR;					\
        if (PPTR >= (POINT *) (CTX)->ctx_buf_end)			\
           Extend_Context(CTX);						\
	} while (0)

#define CloseSubpath(CTX) do {						\
	((CTX)->ctx_buf_ptr++)->b.t = PATH_CLOSE_SUB;			\
	(CTX)->CTX_PATH->path_flags |= PATH_HAS_CLOSE;			\
        if ((CTX)->ctx_buf_ptr >= (CTX)->ctx_buf_end)			\
           Extend_Context(CTX);						\
	} while (0)

#define Close(CTX) do {							\
	((CTX)->ctx_buf_ptr++)->b.t = PATH_CLOSE;			\
	(CTX)->CTX_PATH->path_flags |= PATH_HAS_CLOSE;			\
        if ((CTX)->ctx_buf_ptr >= (CTX)->ctx_buf_end)			\
           Extend_Context(CTX);						\
	} while (0)

#define Curve(CTX, F, O) do {						\
register PATH_POINT *PPTR = (CTX)->ctx_buf_ptr;				\
        PPTR->b.t = PATH_CURVE;						\
        ((PATH_ITEM_CURVE *) PPTR)->form = F;				\
        ((PATH_ITEM_CURVE *) PPTR)->order = O;				\
	(CTX)->ctx_buf_ptr = PPTR + 1;					\
        if (PPTR >= (CTX)->ctx_buf_end) Extend_Context(CTX);		\
	} while (0)

#define Color(CTX, COL) do {						\
register COLOR *PPTR = (COLOR *) (CTX)->ctx_buf_ptr;			\
	*((COLOR *) PPTR) = *((COLOR *) COL);				\
	if (++((CTX)->ctx_buf_ptr) >= (CTX)->ctx_buf_end)		\
	   Extend_Context(CTX);						\
	} while (0)


#define	_SH_DRAW
#endif	/* _SH_DRAW */
