/*
 * Data structures for Epoch 4.0 display code.
 *
 * $Revision: 1.17 $
 * $Source: /import/kaplan/stable/distrib/epoch-4.2/src/RCS/dispepoch.h,v $
 * $Date: 92/01/29 15:43:02 $
 * $Author: love $
 */

struct char_block
{
  struct char_block *next,*prev; /* Next charblock */
  struct Lisp_Style *style;	/* Style for display */
  short xpos;			/* Start pos (x) */
  short width;			/* Pixel width of character */
  char ch;			/* character at this pos */  
  int new :1;
  int changed :1;
};

struct line_header
{
  struct line_header *next,*prev; /* Next line */
  short ypos;			/* Baseline pos for line */
  short prevy;			/* Previous y position */
  short ascent,descent;		/* Max ascent,descent for line */
  short chars;			/* Number of chars on this line */
  short lwidth;			/* Line width (pixels) */
  short in_display;
  struct char_block *body;	/* Chars on this line */
  struct char_block *end;	/* Ptr to last char/dummy on this line */
  /* Flags used in redisplay process */
  int modeline :1;  
  int changed :1;
  int shifted :1;
  int new :1;
  int tabs :1;
};

struct X_font
{
  struct X_font *next;		/* Next font */
  char *font_name;		/* font name */
  VOID *x_font;			/* The XFontStruct for this font */
  short width,ascent,descent;	/* Local info on this font. */
  char variable;		/* Is font proportional or fixed */
#ifdef HAVE_GRAPHIC_ZONES
  char virtual;			/* Fake font for graphic zones ? */
#endif
};

struct redisplay_block
{
  int type;			/* type of redisplay block */  
  union
    {
      struct line_update
	{
	  struct line_header *l;	/* line containing block */
	  struct char_block *cb;	/* start of block */
	  struct char_block *end;       /* end of block */
	  char clear_line;		/* clear to end of line? */
	} line;
      struct clear_region
	{
	  int top,bottom;		/* start,end of region to clear. */
	} area;
      struct blit_region
	{
	  struct line_header *l1; /* start */
	  struct line_header *l2; /* end */
	  short old_top;
	} blit;
    } block;
  int done;
};

#define LINE 1
#define AREA 2
#define BLIT 3

#define BLOCK_DONE(x)		(display_list[x].done)
#define BLOCK_TYPE(x)  		(display_list[x].type)
#define BLOCK_LINE(x)		(display_list[x].block.line.l)
#define BLOCK_LINE_START(x)	(display_list[x].block.line.cb)
#define BLOCK_LINE_END(x)	(display_list[x].block.line.end)
#define BLOCK_LINE_CLEAR(x)	(display_list[x].block.line.clear_line)
#define BLOCK_AREA_TOP(x)	(display_list[x].block.area.top)
#define BLOCK_AREA_BOTTOM(x)	(display_list[x].block.area.bottom)
#define BLOCK_BLIT_START(x)	(display_list[x].block.blit.l1)
#define BLOCK_BLIT_END(x)	(display_list[x].block.blit.l2)
#define BLOCK_BLIT_OLD_TOP(x)	(display_list[x].block.blit.old_top)

/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Accessor functions for char_blocks and lines
 */
int line_pool();
struct line_header *get_line();
struct line_header *next_line();
void free_line();
void free_lines();
int block_pool();
struct char_block *get_block();
struct char_block *next_block();
void free_blocks();
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* Quick access to font information
 */
#define XXFONT(a) ((struct X_font *) XPNTR(a))
#define XFNAME(f) (f)->font_name
#define XFID(f) ((XFontStruct *)(f)->x_font)->fid
#define XFONT(f) (XFontStruct *)(f)->x_font
#define XFASCENT(f) (f)->ascent
#define XFDESCENT(f) (f)->descent
#define XFHEIGHT(f) ((f)->ascent + (f)->descent)
#define XFWIDTH(f) (f)->width
#define XFVARIABLE(f) (f)->variable

/* Access to line header from a window structure.
 */
#define XLINE(a) ( (struct line_header *) XPNTR(a))

/*
 * STYLE_FIELD(window,field,style) -> return field from buffer-local style if
 *				non-nil, or from screen style.
 * struct window *window
 * style = stylenorm,stylerev,stylecursor
 * field = foreground,background,cursor_foreground,cursor_background,font, etc.
 * struct buffer *b = current_buffer
 */
#define STYLE_FIELD(window,field,stylename) (\
  !STYLEP(b->style) ?\
    XSTYLE(XROOT((window)->root)->stylename)->field\
    : EQ(XSTYLE(b->style)->field,Qnil) ?\
      XSTYLE(XROOT((window)->root)->stylename)->field\
	: XSTYLE(b->style)->field)


