/**************************************************************************/
/*  FILE:  REDRAW.C		PROGRAM TITLE: DeskSET II Alpha Version   */
/*  Date Created: 12/15/87						  */ 
/*  Last Modified: 11/16/88						  */
/*									  */
/*  Description: REDRAW ROUTINES					  */
/*  Routines: 	o  do_redraw()	  - Event Redraw Routine		  */
/*		o  text_draw()    - Txt Window Redraw Routine		  */
/*		o  prev_draw()	  - Preview Window Redraw Routine	  */
/*		o  pdraw_fit()    - Draw Preview Background (size to fit) */
/*		o  pdraw_scale()  - Draw Preview Background (any scale)   */
/*		o  rc_equal()	  - Equal Rectangle Check		  */
/*		o  send_redraw()  - Self Redraw Routine			  */
/*		o  set_clip()	  - Set Clip Rectangle			  */
/*		o  clear_window() - Clear Text and Preview Windows        */
/*		o  redraw_images()- Redraw Images Routines		  */
/*		o  zoom_setup()   - Closes/Opens Preview Buffer		  */
/*		o  do_blit()	  - Performs blit from Preview to Screen  */
/*		o  mclip()	  - set clip in preview buffer		  */
/*		o  scan_clip()    - set clip in scan buffer		  */
/*		o  redraw_laser() - Redraw Laser Buffer at curr_page      */
/*		o  do_update_text()- update text ptrs for vgtext	  */
/*		o  graphic_setup() - Display or hide graphic images	  */
/*		o  force_preview() - Redraw preview window - immediate    */
/*		o  force_blit_redraw() - Another force redraw message     */
/*		o  recalc_txtptrs()- Recalc txt ptrs for dotext 	  */
/*		o  recalc_rtext()  - Only recalc 1 articles reg. textptrs */
/*		o  clear_preview() - Clear preview window		  */
/* 		o  update_preview_blit() - Update blit rectangles         */
/*		o  update_size_fit() - Update window params in size to fit*/
/*		o  init_rulers()   - Initialize h and v rulers  	  */
/*		o  init_hrulers()  - Initialize horizontal rulers	  */
/*		o  init_vrulers()  - Initialize vertical rulers		  */
/*		o  init_hinches()  - Initialize h ruler to inches	  */
/*		o  init_hpicas()   - Initialize h ruler to picas	  */
/*		o  init_hcents()   - Initialize h ruler to centimeters    */
/*		o  init_vinches()  - Initialize v ruler to inches	  */
/*		o  init_vpicas()   - Initialize v ruler to picas	  */
/*		o  init_vcents()   - Initialize v ruler to centimeters    */
/*		o  show_rulers()   - Show rulers on screen 		  */
/*		o  do_grids()	   - Display grids on screen		  */
/*		o  put_mpix()	   - Put grid pixel in memory buffer      */
/*		o  calc_size_fit() - Calc size of page for STF and PADJCNT*/
/*		o  redraw_alt()	   - Redraw Handler for PADJCNT		  */
/**************************************************************************/


/**************************************************************************/
/* INCLUDE FILES							  */
/**************************************************************************/
#include <obdefs.h>
#include "define.h"
#include "gemdefs.h"
#include "deskset2.h"
#include <osbind.h>
#include "defs.h"
#include "dbase.h"
#include "alert.h"

/**************************************************************************/
/* DEFINES								  */
/**************************************************************************/
#define max(x,y)   (((x) > (y)) ? (x) :  (y))	/* Max function	          */
#define	min(x,y)   (((x) < (y)) ? (x) :  (y))	/* Min function		  */


/**************************************************************************/
/* EXTERNALS								  */
/**************************************************************************/
extern int gl_apid;				/* gl_apid used for redraw*/

extern int txt_handle;				/* text window handle     */
extern int prev_handle;				/* preview window handle  */
extern int dummy;				/* dummy, you dummy...    */

extern GRECT dpwork;				/* work area of window    */
extern GRECT pwork;				/* preview window wrk area*/
extern GRECT twork;				/* txt window work area   */

extern int phandle;				/* printer handle         */
extern int mhandle;				/* preview buffer handle  */
extern int shandle;                             /* screen handle          */

extern int view_size;				/* Current Viewing Size   */

extern int hpage_size;				/* Horiz Page Width -MU   */
extern int vpage_size;				/* Vert. Page Width - MU  */
extern FDB page_MFDB;				/* Preview Buffer MFDB    */
extern GRECT page_area; 			/* Preview BUffer GRECT   */
extern long location;				/* Screen MFDB		  */

extern int ptsin[];				/* PTSIN array for data   */
extern int intout[];

extern long get_fregion();			/* get first region	  */
extern long get_nregion();			/* get next region        */
extern long getf_aregion();			/* get first article reg..*/
extern long getn_aregion();			/* get next article region*/
extern long getf_article();
extern long getn_article();
extern long get_regart();

extern curr_page;				/* current page		  */

extern int rect_in_mu[];;			/* x1,y1,x2,y2 variables  */
extern int mode_flag;				/* current fill mode      */
extern int msg_buff[];				/* evnt_multi buffer      */

extern unsigned long scanptr;			/* Ptr to Scan Buffer     */
extern unsigned long page_ptr;			/* Ptr to Preview Buffer  */
extern unsigned long pageim;			/* Ptr to Laser Buffer    */
extern int mxres,myres;				/* Preview Buffer rez     */
extern int mode_change;				/* Flag - just change     */
						/* fill type????  0 no    */
						/*		  1 yes   */
extern unsigned long prev_bytes;		/* #bytes in preview buf  */
extern unsigned long laser_bytes;
extern unsigned long scan_bytes;

extern int scan_xres;				/* scan buffer xres	  */
extern int scan_yres;				/* scan buffer yres	  */

extern int  zdevice;				/* index into xdpi/ydpi   */
extern int  pxy[];				/* tmp array		  */

extern char *do_handjreg();			/* Do jim's scan routine  */
extern char *get_arttxt();			
extern char *get_txtptr();
extern int  SH;					/* Line space for scanner */

extern int ptsarray[];				/* Interface to DBASE.C   */
extern unsigned long gl_region_ptr;		/* txt region pointer...  */
extern int cur_primitive;			/* current primitive RCS  */
extern int image_status;			/* Image Display? or not..*/

extern struct txtattr gltxtattr;		/* global text attrib     */
extern int glgrattr[];				/* global graphic attrib  */

extern int sdevm;

extern int xruler_offset;
extern int yruler_offset;
extern int ruler_flag;
extern int unit_type;
extern int splane;
extern unsigned long scanptr;
extern int newx,newy;
extern int xold_mark,yold_mark;
extern int xor_handle;
extern char *get_lcmem();
extern int rule_handle;
extern int deferhj;
extern int show_grids;
extern int hgridspace;
extern int vgridspace;

extern long pagebytes;

extern int print_flag;

extern	int	TWrfmod;			/* TWindow refresh mode	*/
extern	long	TWart_ptr;			/* TW current article	*/

extern PAGE *curpage;
extern long curregion;


extern PAGE *pagehd;
extern PAGE *left_tmplate;
extern PAGE *right_tmplate;
extern int tmplate_flag;
extern int temp_page;
extern PAGE *tpagehd;
extern PAGE *tcurpage;
extern int displ_tmpl_flag;
extern int disp_pos;				/* template-FRONT or BACK   */
extern int disp_type;				/* templ type-BOTH,LEFT,RITE*/

extern ARTICLE *rtarthd;
extern ARTICLE *ltarthd;
extern ARTICLE *arthd;

extern int TYF_Gx0;
extern int TYF_Gy0;
extern int TYF_Gx1;
extern int TYF_Gy1;
extern int TYF_Gtype;
extern char *TYF_Gfile;
/**************************************************************************/
/* GLOBAL VARIABLES							  */
/**************************************************************************/
int pagew;					/* Current Page width and */
int pageh;					/* height in pixels for   */
						/* reference purposes only*/
int opwidth;					/* Old page width pixels  */
int opheight;					/* Old page ht - pixels   */

int clip_area[4];				/* Global Clipping rect.  */

unsigned long region_ptr;			/* Ptr to current region  */

int  opcode;					/* opcode of poly type    */
int  count;					/* number of vertices     */
int  wmode;					/* writing mode		  */

int txoffset,tyoffset;				/* tmp xoffset and yoffset*/
int prev_size;					/* preview size		  */
int blit_flag;					/* to blit or not to blit */
int xwidth,ywidth;				/* Calc screen width/ht   */

char *txtptr;					/* Text Pointer...        */
GRECT page;					/* GRECT of page area?    */
int force_draw_flag;				/* Force a redraw on Prev.*/
int blit_area[8];
int aclear[4];					/* preview clear_window rect*/
int aclear2[4];

int *hrbuffer;
int *vrbuffer;
FDB hrule_mfdb;
FDB vrule_mfdb;
int vhalf,hhalf;
int hlen,vlen;
int x_eighths,y_eighths;

int ruler_hasmem;

char pixtbl[] = {0x80,
		 0x40,
		 0x20,
		 0x10,
		 0x08,
		 0x04,
		 0x02,
		 0x01};

int alt_offset;


long newscreen;
long realscreen;
int alerted;

/**************************************************************************/
/* Function:    do_redraw()						  */
/* Description: Event Driven Redraw Routine				  */
/**************************************************************************/
do_redraw(msg)
register int msg[];
{
   register int whandle;
   GRECT t1,t2;
   int pxy[4];

   gsx_moff();
   whandle = msg[3];
   t2.g_x  = msg[4];
   t2.g_y  = msg[5];
   t2.g_w  = msg[6];
   t2.g_h  = msg[7];

   if(whandle == txt_handle)
   {
      if (!TWart_ptr || TWrfmod == 2)		/* force full TW area	*/
      {
	  t2.g_x = twork.g_x;
	  t2.g_y = twork.g_y;
	  t2.g_w = twork.g_w;
	  t2.g_h = twork.g_h;
      }
      if (TWart_ptr)
      {
	  clrcursor();
	  hilicheck(0);
	  review(TWrfmod);
      }

   }
   wind_get(whandle,WF_FIRSTXYWH,&t1.g_x,&t1.g_y,&t1.g_w,&t1.g_h);
   while(t1.g_w && t1.g_h)
   {
      if(rc_intersect(&t2,&t1))
      {
         set_clip(TRUE,&t1);
	 grect_to_array(&t1,pxy);		/* experimental */
	 vs_clip(rule_handle,1,pxy);

         if(whandle ==  txt_handle)
	 {
            txt_draw(&t1);
	    set_clip(FALSE,&t1);
         }
         else
            if(whandle == prev_handle) 
	         prev_draw();
      }
      wind_get(whandle,WF_NEXTXYWH,&t1.g_x,&t1.g_y,&t1.g_w,&t1.g_h);
   }

   if (whandle == txt_handle && TWart_ptr)
   {
	endreview(0);
	cursor();
	if (TWrfmod <= 2) TWrfmod = 3;
   }

   vs_clip(rule_handle,0,pxy);
   check_region_ptr();
   gsx_mon();
}



/**************************************************************************/
/* Function:    txt_draw()						  */
/* Description: Redraw Txt Window					  */
/**************************************************************************/
txt_draw(rect)
GRECT *rect;
{
   clrTW(rect);
   if (TWart_ptr) new_screen();
}



/**************************************************************************/
/* Function:    prev_draw()						  */
/* Description: Redraw Preview Window					  */
/**************************************************************************/
prev_draw()
{
   blit_flag = TRUE;
   if(force_draw_flag)
   {
       blit_flag = FALSE;
       force_draw_flag = FALSE;
   }
   clear_preview();
   if(view_size == PADJCNT)
		redraw_alt();
   else
   		redraw_images();
}




/**************************************************************************/
/* Function:    pdraw_fit()						  */
/* Description: Calculate screen page width and height			  */
/**************************************************************************/
pdraw_fit(item)
int item;
{
	if(ruler_flag)
	     mutoscrn(648,576,&xruler_offset,&yruler_offset,1);
	else
	     xruler_offset = yruler_offset = 0;
	dpwork.g_x = pwork.g_x + xruler_offset;
	dpwork.g_y = pwork.g_y + yruler_offset;
	dpwork.g_w = pwork.g_w - xruler_offset;
	dpwork.g_h = pwork.g_h - yruler_offset;
	calc_size_fit(item);
}


/**************************************************************************/
/* Function:    pdraw_scale()						  */
/* Description: Draw the preview background page (any scale)		  */
/**************************************************************************/
pdraw_scale()
{
      txoffset = page_area.g_x;
      tyoffset = page_area.g_y;

      zdevice  = SCREEN;
      pagew = hmutopix(hpage_size);		/* can make this a variable */
      pageh = vmutopix(vpage_size);		/* for later...		    */

      scale(&pagew,&pageh,&txoffset,&tyoffset,0);

      pxy[0] = pwork.g_x + hmutopix(txoffset);
      pxy[1] = pwork.g_y + vmutopix(tyoffset); 
      xwidth = pxy[2] = pxy[0] + pagew - 1;
      ywidth = pxy[3] = pxy[1] + pageh - 1;
}

/**************************************************************************/
/* Function:    rc_equal()						  */
/* Description: check if 2 rectangles are equal				  */
/**************************************************************************/
rc_equal(p1,p2)
register GRECT *p1,*p2;
{
    if((p1->g_x != p2->g_x) ||
       (p1->g_y != p2->g_y) ||
       (p1->g_w != p2->g_w) ||
       (p1->g_h != p2->g_h))
       return(FALSE);
    return(TRUE);
}



/**************************************************************************/
/* Function:    send_redraw()						  */
/* Description: Perform a self-redraw					  */
/**************************************************************************/
send_redraw(wh)
int wh;
{
    msg_buff[0] = WM_REDRAW;
    msg_buff[1] = gl_apid;
    msg_buff[2] = 0;
    msg_buff[3] = wh;
    msg_buff[4] = pwork.g_x;
    msg_buff[5] = pwork.g_y;
    msg_buff[6] = pwork.g_w;
    msg_buff[7] = pwork.g_h;
    appl_write(gl_apid,16,msg_buff);
}



/**************************************************************************/
/* Function:    set_clip()						  */
/* Description: Set a clipping Rectangle				  */
/* INPUT: clip_flag o 0 - Clip Off  1 - Clip On				  */
/*        area      0 Area to Clip					  */
/**************************************************************************/
set_clip(clip_flag,area)
int clip_flag;
GRECT *area;
{
     int pxy[4];

     grect_to_array(area,pxy);
     vs_clip(shandle,clip_flag,pxy);
}



/**************************************************************************/
/* Function:    clear_window()						  */
/* Description: Clears the window  - Text Window  to white		  */
/*				   - Preview Window to Dithered.          */
/* INPUT: whandle - handle of window				          */
/*	  pattern - interior pattern					  */
/*	  style   - style type.						  */
/**************************************************************************/
clear_window(whandle,pattern,style)
int whandle;
int pattern;
int style;
{
    int pxy[4];

    vsf_interior(shandle,pattern);
    vsf_style(shandle,style);
    vsf_perimeter(shandle,0);
    if(whandle == prev_handle)
    {
         aclear[0] = dpwork.g_x + pagew;	/* clears right of page */
	 aclear[1] = pwork.g_y;
         aclear[2] = aclear[0] + pwork.g_w - 1;
         aclear[3] = aclear[1] + pwork.g_h - 1;

         aclear2[0] = pwork.g_x;		/* clears below of page */
	 aclear2[1] = dpwork.g_y + pageh;
         aclear2[2] = aclear2[0] + pwork.g_w - 1;
	 aclear2[3] = aclear2[1] + pwork.g_h - 1;
    }
    else
    {
       grect_to_array(&twork,pxy);
       vr_recfl(shandle,pxy);
    }    
}


/**************************************************************************/
/*	Clean up all rectangles of regions that have been re H&J ed       */
/*	from the current article.  Start with the given region which was  */
/*	the first one h&jed and clean up all other regions on the         */
/* 	same page.							  */
/**************************************************************************/
page_cleanup(rptr)
long rptr;
{
   register long region_ptr;
   int rect[4];
   int page;
   long tmpregion;

   region_ptr = getf_aregion(&rect[0],&rect[1],
			     &rect[2],&rect[3],&page);

   while(region_ptr != rptr && region_ptr)
      region_ptr = getn_aregion(&rect[0],&rect[1],
			        &rect[2],&rect[3],&page);	

   while(region_ptr)
   {
      if(page == curr_page)
      {
         tmpregion = curregion;
         redraw_area(region_ptr,rect,0);
         curregion = tmpregion;
      }
      region_ptr = getn_aregion(&rect[0],&rect[1],
      			        &rect[2],&rect[3],&page);	

   }
   do_blit();   
}


redr_regarea(rptr,bltflag)
register long rptr;
int bltflag;
{
   int rect[4];
   int dummy;

   find_boundary(rptr,&rect[0],&rect[1],&rect[2],&rect[3],&dummy,&dummy);
   redraw_area(rptr,rect,bltflag);
}

/**************************************************************************/
/* Function:	redraw_area()						  */
/* Description	Redraw loop for polygons, ellipses etc...		  */
/**************************************************************************/
redraw_area(rptr,murect,bltflag)
   register REGION *rptr;
   register int murect[];
   int bltflag;
{
   int g_flag;				/* graphic region? */
   int rgrect[4];
   int tgrect[4];
   int rpxy[4];
   int tpxy[4];
   int murec1[4];
   int pts;

   int xoffset,yoffset;

   if(!rptr)
   {
	pts = 36;
	xoffset = pts * 18;
	yoffset = pts * 16;
   }	
   else
   {
	pts = rptr->grattr[1];
        if(pts && (rptr->grattr[2] & 0x8000))
        {
	   xoffset = pts * 18;
	   yoffset = pts * 16;
        }
        else
	{
	   xoffset = 162; /* offsets are in machine units */
	   yoffset = 144; /* an eighth of an inch each way*/
			  /* based on 1296 and 1152 mus   */
	}
   }

   murect[0] -= xoffset;
   murect[1] -= yoffset;
   murect[2] += xoffset;
   murect[3] += yoffset;


   GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);

   mutopage(murect[0],murect[1],&rpxy[0],&rpxy[1],1);
   mutopage(murect[2],murect[3],&rpxy[2],&rpxy[3],1);
#if NEVER
   rpxy[0] -= 2;		/* With solid fills perimeter is on */
   rpxy[1] -= 2;		/* so when erasing with hollow fill */
   rpxy[2] += 2;		/* we must ......		    */
   rpxy[3] += 2;		/* Adjust for perimeter being off   */
#endif
   rpxy[0] = max(0,rpxy[0]);
   rpxy[1] = max(0,rpxy[1]);
   rpxy[2] = min(pagew - 1,rpxy[2]);
   rpxy[3] = min(pageh - 1,rpxy[3]);

   vs_clip(mhandle,1,rpxy);
   write_white(mhandle);
   v_bar(mhandle,rpxy);
   write_black(mhandle);

   rgrect[0] = rpxy[0];
   rgrect[1] = rpxy[1];
   rgrect[2] = rpxy[2] - rpxy[0] + 1;
   rgrect[3] = rpxy[3] - rpxy[1] + 1;

   if(show_grids)	/* moved it here cjg */
	do_grids(1,murect[0],murect[1],murect[2],murect[3]);

   display_template(1,rgrect);
   
   region_ptr = get_fregion(curr_page,
	&murec1[0],&murec1[1],
	&murec1[2],&murec1[3],&g_flag);
   while(region_ptr)
   {
        mutopage(murec1[0],murec1[1],&tpxy[0],&tpxy[1]);
        mutopage(murec1[2],murec1[3],&tpxy[2],&tpxy[3]);
	
	tgrect[0] = tpxy[0];
        tgrect[1] = tpxy[1];
        tgrect[2] = tpxy[2] - tpxy[0] + 1;
        tgrect[3] = tpxy[3] - tpxy[1] + 1;
	
	if(rc_intersect(rgrect,tgrect))
	{
	   if(g_flag)
               get_grattr(region_ptr,glgrattr);

           if(g_flag || !mode_flag)
           {
               opcode = get_fprimitive(region_ptr,&count,&wmode);
               while(opcode != -1)
               {
                   switch(opcode)
                   {
        	       case 3:
	               case 4:
	               case 0: redraw_polygon(count,wmode,g_flag);
                               break;

		       case 1: redraw_ellipse(wmode,g_flag);
		               break;

		       case 2: graphic_setup();
  		               break;
	            }
                    opcode = get_nprimitive(&count,&wmode);
               }
	   }
           if(mode_flag && !g_flag)
	   {
	      if(txtptr = get_txtptr(region_ptr))
              {
	          if(*txtptr)
		  {
	             open_region(region_ptr);
                     do_clipregout(tgrect[0],tgrect[1],
			tgrect[2] + tgrect[0] - 1,
			tgrect[3] + tgrect[1] - 1);
                  }
	      }
           }
	}
	region_ptr = get_nregion(&murec1[0],&murec1[1],
 			           &murec1[2],&murec1[3],&g_flag);
   }

   display_template(2,rgrect);
   do_numbers(rgrect,0);

   if(bltflag)
   {
      mclip();
      do_blit();
   }
}


/**************************************************************************/
/* Function:	redraw_images()						  */
/* Description	Redraw loop for polygons, ellipses etc...		  */
/**************************************************************************/
redraw_images()
{
   int endflag;
   int g_flag;				/* graphic region? */

   if((!blit_flag) || mode_change)
   {
      clrmem(page_ptr,pagebytes);

      if(show_grids)
	do_grids(0,0,0,0,0);

        display_template(1,0L);
        region_ptr = get_fregion(curr_page,
			&rect_in_mu[0],&rect_in_mu[1],
			&rect_in_mu[2],&rect_in_mu[3],&g_flag);
        while(region_ptr)
        {
             mclip();
             if(!g_flag)
                 get_txtattr(region_ptr,&gltxtattr);
	     else 
		 get_grattr(region_ptr,glgrattr);
	     if(g_flag || !mode_flag)
	     {
                opcode = get_fprimitive(region_ptr,&count,&wmode);
                while(opcode != -1)
                {
                   switch(opcode)
                   {
        	       case 3:
	               case 4:
	               case 0: redraw_polygon(count,wmode,g_flag);
                               break;

		       case 1: redraw_ellipse(wmode,g_flag);
		               break;

		       case 2: graphic_setup();
  		               break;
	            }
                    opcode = get_nprimitive(&count,&wmode);
                 }
	     }
             if(mode_flag && !g_flag)
	     {
	        if(txtptr = get_txtptr(region_ptr))
                {
		   if(*txtptr)
		   {
	             get_buffvars(region_ptr);
		     open_region(region_ptr);
                     do_regoutput(txtptr,&endflag);
                     put_buffvars(region_ptr);
		   }
                }
	        GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);
             }

	  region_ptr = get_nregion(&rect_in_mu[0],&rect_in_mu[1],
 			           &rect_in_mu[2],&rect_in_mu[3],&g_flag);
      }
      mode_change = FALSE;
      display_template(2,0L);
      do_numbers(0L,0);
   }
   do_blit();			/* Either blit now or redraw,then blit*/
}

/**************************************************************************/
/* Function:	zoom_setup()						  */
/* Description	Closes/Open Preview Buffer with new sizes		  */
/**************************************************************************/
zoom_setup()
{
      opwidth  = pwork.g_w;
      opheight = pwork.g_h;
      mxres    = pagew;
      myres    = pageh;

      if((view_size == PSIZE) || (view_size == PADJCNT))
	   mxres = ((mxres + 15)/16)*16;
      GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);
      page_MFDB.fd_w = mxres; 
      page_MFDB.fd_h = myres;
      page_MFDB.fd_wdwidth = (mxres + 15)/16;
}



/**************************************************************************/
/* Function:	do_blit()						  */
/* Description:	Blit GRECT from preview buffer to screen		  */
/**************************************************************************/
do_blit()
{
        int color[2];
        color[0] = 1;
        color[1] = 0;
        mutopage(page_area.g_x,page_area.g_y,&page.g_x,&page.g_y,1);
        grect_to_array(&page,blit_area);
	gsx_moff();
	vrt_cpyfm(shandle,1,blit_area,&page_MFDB,&location,color);
	if(ruler_flag)
	   show_rulers();
        gsx_mon();
}

/**************************************************************************/
/* Function:	mclip()							  */
/* Description: set clipping rectangle in preview buffer		  */
/**************************************************************************/
mclip()
{
   int pxy[4];

   pxy[0] = pxy[1] = 0;  
   pxy[3] = pageh - 1;

   if(view_size == PADJCNT)
   {
     pxy[0] = ((curr_page % 2) ? (pagew/2):(0));
     pxy[2] = ((curr_page % 2) ? (pagew - 1) : (pagew/2));
   }
   else
     pxy[2] = pagew - 1;

   vs_clip(mhandle,1,pxy);
}



/**************************************************************************/
/* Function:	scan_clip()							  */
/* Description: set clipping rectangle in scan buffer		   	  */
/**************************************************************************/
scan_clip()
{
   int pxy[4];
  
   pxy[0] = pxy[1] = 0;
   pxy[2] = scan_xres - 1;
   pxy[3] = scan_yres - 1;
   vs_clip(mhandle,1,pxy);
}



/**************************************************************************/
/* Function:	redraw_laser()						  */
/* Description	Redraw loop for polygons, ellipses etc...		  */
/*		Redraw Loop for playing back to the laser printer...	  */
/**************************************************************************/
redraw_laser(pagenum)
int pagenum;
{
   int status;
   int prev_flag;
   int endflag;
   int g_flag;					/* graphic region? */
   int temp;

   endflag = 0;
   g_flag  = FALSE;
   prev_flag = mode_flag;
   mode_flag = TRUE;
   temp = sdevm;
   sdevm = 3;				/* Laser printer CS 4/12 */
   display_template(1,0L);

       region_ptr = get_fregion(pagenum,
			    &rect_in_mu[0],&rect_in_mu[1],
			    &rect_in_mu[2],&rect_in_mu[3],&g_flag);
       while(region_ptr)
       {
           if(!g_flag)
               get_txtattr(region_ptr,&gltxtattr);
           else
               get_grattr(region_ptr,glgrattr);
	   if(g_flag || !mode_flag)
	   {
               opcode = get_fprimitive(region_ptr,&count,&wmode);
               while(opcode != -1)
               {
                  switch(opcode)
                  {
		    case 3:
		    case 4:
		    case 0:  redraw_polygon(count,wmode,g_flag);
		             break;
		    case 1:  redraw_ellipse(wmode,g_flag);
		 	     break;
		    case 2:  insert_graphic();
			     break;
                  }
                  opcode = get_nprimitive(&count,&wmode);
               }
	   }
           if(!g_flag)
           {
              if(txtptr = get_txtptr(region_ptr))
              {
		 if(*txtptr)
		 {
	            get_buffvars(region_ptr);
		    open_region(region_ptr);
                    do_regoutput(txtptr,&endflag);         
                    put_buffvars(region_ptr);
		 }
              }
  	      GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);
         } 				/* if(graphics && g_flag) etc... */
         region_ptr = get_nregion(&rect_in_mu[0],&rect_in_mu[1],
   			          &rect_in_mu[2],&rect_in_mu[3],&g_flag);


   }				/* while(region_ptr 		 */
   display_template(2,0L);
   do_numbers(0L,0);
   GDv_updwk(phandle,&pageim,1,&status); 
   v_clrwk(phandle);
   mode_flag = prev_flag;
   sdevm = temp;
}


/**************************************************************************/
/* Function:	redraw_tdo()						  */
/* Description	Redraw loop for polygons, ellipses etc...		  */
/*		Redraw Loop for playing back to the tdo file... 	  */
/**************************************************************************/
redraw_tdo(pagenum)
int pagenum;
{
   int prev_flag;
   int endflag;
   int g_flag;					/* graphic region? */

   endflag = 0;
   g_flag  = FALSE;
   prev_flag = mode_flag;
   mode_flag = TRUE;

   
   tdo_template(1);

       region_ptr = get_fregion(pagenum,
			    &rect_in_mu[0],&rect_in_mu[1],
			    &rect_in_mu[2],&rect_in_mu[3],&g_flag);
       while(region_ptr)
       {
           if(!g_flag)
               get_txtattr(region_ptr,&gltxtattr);
           else
               get_grattr(region_ptr,glgrattr);
	   if(g_flag)
	   {
               opcode = get_fprimitive(region_ptr,&count,&wmode);
               while(opcode != -1)
               {
		  switch(opcode)
                  {
		    case 3:
		    case 4:
		    case 0:
		    case 1:
	   		     calc_prim(opcode,&TYF_Gx0,&TYF_Gy0,
					&TYF_Gx1,&TYF_Gy1,count);
			     TYF_Gtype = 5;
			     insGR_TYF(opcode,count,glgrattr);
		 	     break;
		    case 2:  TYF_Gfile = (char *)&ptsarray[5];
			     TYF_Gx0 = ptsarray[0];
			     TYF_Gy0 = ptsarray[1];
			     TYF_Gx1 = ptsarray[2];
			     TYF_Gy1 = ptsarray[3];
			     switch(ptsarray[4])
			     {
				case 0:
				   TYF_Gtype = 2;
				   break;
				case 1:
				   TYF_Gtype = 3;
				   break;
				case 2:
				   TYF_Gtype = 1;
				   break;
			        case 3:
				   TYF_Gtype = 4;
				   break;
			     }
			     insGR_TYF(opcode,count,glgrattr);
			     break;
                  }
                  opcode = get_nprimitive(&count,&wmode);
               }
	   }
           if(!g_flag)
           {
              if(txtptr = get_txtptr(region_ptr))
              {
		 if(*txtptr)
		 {
	            get_buffvars(region_ptr);
		    open_region(region_ptr);
                    do_tdoout(txtptr,&endflag);         
		 }
              }
         } 				/* if(graphics && g_flag) etc... */
         region_ptr = get_nregion(&rect_in_mu[0],&rect_in_mu[1],
   			          &rect_in_mu[2],&rect_in_mu[3],&g_flag);


   }				/* while(region_ptr 		 */
   tdo_template(2);
   do_numbers(0L,1);
   newPge_TYF();
   mode_flag = prev_flag;
}

/**************************************************************************/
/*  Function:  do_update_text()						  */
/*  Description: update text pointers					  */
/**************************************************************************/
do_update_text()
{
   int prev_flag;
   int dflag;
   char *txtptr;
   char *endptr;
   int g_flag;
   int page;

   if(deferhj)			/* Don't recalc text if h&j deferred */
	return;
   prev_flag = mode_flag;
   mode_flag = TRUE;
   g_flag = FALSE;

   region_ptr = getf_aregion(&rect_in_mu[0],&rect_in_mu[1],
			     &rect_in_mu[2],&rect_in_mu[3],&page);

   while(region_ptr)
   {
      free_scanrects(region_ptr);

      region_ptr = getn_aregion(&rect_in_mu[0],&rect_in_mu[1],
			        &rect_in_mu[2],&rect_in_mu[3],&page);	
   }

   GDvq_extnd(mhandle,0,intout,scan_xres,scan_yres,&scanptr);
   scan_clip();
   txtptr = get_arttxt();

   region_ptr = getf_aregion(&rect_in_mu[0],&rect_in_mu[1],
			     &rect_in_mu[2],&rect_in_mu[3],&page);
   while(region_ptr)
   {
      clrmem(scanptr,scan_bytes);
      put_txtptr(region_ptr,txtptr);
      get_txtattr(region_ptr,&gltxtattr);

      opcode = get_fprimitive(region_ptr,&count,&wmode);
      while(opcode != -1)
      {
	     switch(opcode)
	     {
	        case 0:
                   redraw_polygon(count,wmode,g_flag);
		   break;
		case 1:
                   redraw_ellipse(wmode,g_flag);
		   break;

		case 2:	   /* deliberately skip...*/
		case 3:
		case 4:
			   break;
	     }
             opcode = get_nprimitive(&count,&wmode);
      }
      if(!g_flag && txtptr)
      {
	 chk_repel(region_ptr,rect_in_mu);
         zdevice = SCANNER;
         SH = vmutopix((int)gltxtattr.lnsp);
         get_buffvars(region_ptr);
	 open_region(region_ptr);
         endptr = do_handjreg(txtptr,&dflag,1,rect_in_mu);
         put_buffvars(region_ptr);
      } 

      if(dflag || (endptr == -1L))
      {
	  mode_flag = prev_flag;
          GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);
          return;
      }

      if(!g_flag && txtptr)
           txtptr = endptr;

      region_ptr = getn_aregion(&rect_in_mu[0],&rect_in_mu[1],
			        &rect_in_mu[2],&rect_in_mu[3],&page);
   }
   mode_flag = prev_flag;
   free_repbuffs();
   GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);
}

page_redraw(rptr)
long rptr;
{
long tmp;

   tmp = get_regart(rptr);
   if(tmp)				/* If region is linked		*/
   {
        open_article(tmp);
        if(deferhj || view_size == PADJCNT)
        {
	   do_artcleanup(rptr,0);	/* Re h and j but don't redraw */
	   force_preview();		/* redraw entire page	       */
        }
        else
	   do_artcleanup(rptr,1);	/* Re h and j and re output	*/
   }
   else
   {					/* Just cleanup region area	*/
        if(view_size == PADJCNT)
	{       
	   force_preview();
        }
	else
	   redr_regarea(rptr,1);
   }
}

/**************************************************************************/
/*  Function:  do_artcleanup()						  */
/*  Description: update text pointers 			         	  */
/*		     cleanup page if "redraw_flag" flag is true		  */
/**************************************************************************/
do_artcleanup(rptr,redraw_flag)
long rptr;		/* First region that needs updating		  */
int redraw_flag;
{
   int prev_flag;
   int dflag;
   char *txtptr;
   char *endptr;
   int g_flag;
   int page;
   int rect_in_mu[4];
   long dummy;

   if(deferhj)			/* Don't recalc text if h&j deferred */
	return;

   graf_mouse(2,&dummy);
   prev_flag = mode_flag;
   mode_flag = TRUE;
   g_flag = FALSE;
   
   region_ptr = getf_aregion(&rect_in_mu[0],&rect_in_mu[1],
			     &rect_in_mu[2],&rect_in_mu[3],&page);

   while(region_ptr != rptr && region_ptr)
   {
      region_ptr = getn_aregion(&rect_in_mu[0],&rect_in_mu[1],
			        &rect_in_mu[2],&rect_in_mu[3],&page);	
   }

   while(region_ptr)
   {
      free_scanrects(region_ptr);
      region_ptr = getn_aregion(&rect_in_mu[0],&rect_in_mu[1],
			        &rect_in_mu[2],&rect_in_mu[3],&page);	
   }

   GDvq_extnd(mhandle,0,intout,scan_xres,scan_yres,&scanptr);
   scan_clip();
   txtptr = get_arttxt();
   region_ptr = getf_aregion(&rect_in_mu[0],&rect_in_mu[1],
			     &rect_in_mu[2],&rect_in_mu[3],&page);

   while(region_ptr != rptr && region_ptr)
   {
      region_ptr = getn_aregion(&rect_in_mu[0],&rect_in_mu[1],
			        &rect_in_mu[2],&rect_in_mu[3],&page);	
      txtptr = get_txtptr(region_ptr);
   }
   while(region_ptr)
   {
      clrmem(scanptr,scan_bytes);
      put_txtptr(region_ptr,txtptr);
      get_txtattr(region_ptr,&gltxtattr);

      opcode = get_fprimitive(region_ptr,&count,&wmode);
      while(opcode != -1)
      {
	     switch(opcode)
	     {
	        case 0:
                   redraw_polygon(count,wmode,g_flag);
		   break;
		case 1:
                   redraw_ellipse(wmode,g_flag);
		   break;

		case 2:	   /* deliberately skip...*/
		case 3:
		case 4:
			   break;
	     }
             opcode = get_nprimitive(&count,&wmode);
      }
      if(!g_flag && txtptr && *txtptr)
      {
	 chk_repel(region_ptr,rect_in_mu);
         zdevice = SCANNER;
         SH = vmutopix((int)gltxtattr.lnsp);
         get_buffvars(region_ptr);
	 open_region(region_ptr);
	 if(page == curr_page)
	    endptr = do_handjreg(txtptr,&dflag,3,rect_in_mu);
	 else
            endptr = do_handjreg(txtptr,&dflag,1,rect_in_mu);
         put_buffvars(region_ptr);
      } 

      if(dflag || (endptr == -1L))
      {
	  mode_flag = prev_flag;
          GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);
	  if(redraw_flag)
	     page_cleanup(rptr);
          graf_mouse(ARROW,&dummy);
          return;
      }

      if(!g_flag && txtptr)
           txtptr = endptr;

      region_ptr = getn_aregion(&rect_in_mu[0],&rect_in_mu[1],
			        &rect_in_mu[2],&rect_in_mu[3],&page);
   }
   mode_flag = prev_flag;
   free_repbuffs();
   GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);
   if(redraw_flag)
      page_cleanup(rptr);
   graf_mouse(ARROW,&dummy);
}


/**************************************************************************/
/*  Function:   graphic_setup()						  */
/*  Description: if "image_status" == 0, draw with filled Atari Logos	  */
/*		 else draw the actual image.				  */
/**************************************************************************/
graphic_setup()
{
   if(!image_status)
   {
      ptsarray[4] = ptsarray[2];
      ptsarray[5] = ptsarray[3];
		 
      ptsarray[2] = ptsarray[0];
      ptsarray[3] = ptsarray[5];

      ptsarray[6] = ptsarray[4];
      ptsarray[7] = ptsarray[1];
      cur_primitive = OIMAGE;
      redraw_polygon(4,wmode,1);
      cur_primitive = 0;
   }
   else insert_graphic();
}



/**************************************************************************/
/*  Function:   force_preview()						  */
/*  Description: Forces a redraw on the preview window...		  */
/**************************************************************************/
force_preview()
{
     force_draw_flag = TRUE;
     msg_buff[0] = msg_buff[1] = msg_buff[2] = 0;
     msg_buff[3] = prev_handle;
     msg_buff[4] = pwork.g_x;
     msg_buff[5] = pwork.g_y;
     msg_buff[6] = pwork.g_w;
     msg_buff[7] = pwork.g_h;
     do_redraw(msg_buff);
}



/**************************************************************************/
/* Function: force_blit_redraw()					  */
/* Description: Another force redraw message				  */
/**************************************************************************/
force_blit_redraw(noprev)
int noprev;
{
     if(!noprev)
     {
        msg_buff[0] = msg_buff[1] = msg_buff[2] = 0;
        msg_buff[3] = prev_handle;
        msg_buff[4] = pwork.g_x;
        msg_buff[5] = pwork.g_y;
        msg_buff[6] = pwork.g_w;
        msg_buff[7] = pwork.g_h;
        do_redraw(msg_buff);
     }
}


/**************************************************************************/
/* Function:  recalc_txtptrs()						  */
/* Description: Adjusts the vgtext to break on consistent boundaries.     */
/**************************************************************************/
recalc_txtptrs()
{
    register unsigned long txtptr;
    int dummy;

    if(deferhj)			/* Defer h&j so don't recalc text ptrs */
	return;
    graf_mouse(2,&dummy);
    txtptr = getf_article();
    while(txtptr)
    {
         do_update_text();
         txtptr = getn_article();
    }
    graf_mouse(ARROW,&dummy);
}




/**************************************************************************/
/* Function: recalc_rtext()						  */
/* Description: Only recalc 1 articles region textptrs			  */
/**************************************************************************/
recalc_rtext()
{
   int dummy;
   long tempart;

   if(deferhj)
	return;
   graf_mouse(2,&dummy);
   tempart = get_regart(gl_region_ptr);
   if(tempart)
   {
      open_article(tempart);
      do_update_text();
   }
   graf_mouse(ARROW,&dummy);
}




/**************************************************************************/
/* Function: clear_preview()						  */
/* Description: Clear preview window					  */
/**************************************************************************/
clear_preview()
{
    vsf_interior(shandle,2);
    vsf_style(shandle,1);
    vsf_perimeter(shandle,0);

    vr_recfl(shandle,aclear);
    vr_recfl(shandle,aclear2);
}



/**************************************************************************/
/* Function: update_preview_blit()					  */
/* Description: update blit rectangles...				  */
/**************************************************************************/
update_preview_blit()
{
    blit_area[4] = dpwork.g_x;
    blit_area[5] = dpwork.g_y;
    blit_area[6] = dpwork.g_x + dpwork.g_w - 1;
    blit_area[7] = dpwork.g_y + dpwork.g_h - 1;
    mutopage(page_area.g_w,page_area.g_h,&page.g_w,&page.g_h,1);
}





/**************************************************************************/
/* Function: init_rulers()						  */
/* Description: initialize h and v rulers				  */
/**************************************************************************/
init_rulers()
{
   int pxy[4];

   vsf_interior(rule_handle,0);
   vswr_mode(rule_handle,1);
   
   vsl_width(mhandle,1);		/* set line width to 1		  */
   vsl_type(mhandle,1);			/* set line type to solid	  */
   vsl_ends(mhandle,0,0); 		/* restore end styles		  */
   
   pxy[0] = pwork.g_x;
   pxy[1] = pwork.g_y;
   pxy[2] = dpwork.g_x;
   pxy[3] = dpwork.g_y;
   vr_recfl(rule_handle,pxy);

   vswr_mode(rule_handle,3);

   if(view_size == P200)
   {
	mutopage(324,288,&hhalf,&vhalf,1);
	mutopage(41,36,&hlen,&vlen,1);
   }
   else
   {
        mutopage(648,576,&hhalf,&vhalf,1);
        mutopage(81,72,&hlen,&vlen,1);		/* Ruler length 1/16 incs    */
   }

   
   x_eighths = 162;
   y_eighths = 144;
  
   if(hrbuffer)
   {
      free(hrbuffer);
   }
   if(vrbuffer)
   {
      free(vrbuffer);
   }
   hrbuffer = (int *)get_lcmem((long)(vhalf*(((mxres+7)/8)+1)));
   vrbuffer = (int *)get_lcmem((long)(myres * (((hhalf+7)/8)+1)));
   if(hrbuffer && vrbuffer)
   {
      ruler_hasmem = 1;
      init_hrulers();
      init_vrulers();
      GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);
   }
   else
   {
      alert_cntre(ALERT30);
      ruler_hasmem = 0;
   }
   xold_mark = -1;				/* Init ruler marks */
   yold_mark = -1;   

}





/**************************************************************************/
/* Function: init_hrulers()						  */
/* Description: initialize horizontal rulers				  */
/**************************************************************************/
init_hrulers()
{
   int pxy[4];
   int dummy;

   GDvq_extnd(mhandle,0,intout,mxres,vhalf,&hrbuffer);
   vst_alignment(mhandle,1,5,&dummy,&dummy);
   hrule_mfdb.fd_addr = hrbuffer;
   hrule_mfdb.fd_w    = mxres;
   hrule_mfdb.fd_h    = vhalf;
   hrule_mfdb.fd_wdwidth = (mxres + 15)/16;
   hrule_mfdb.fd_stand = 0;
   hrule_mfdb.fd_nplanes = 1;

   pxy[0] = 0;
   pxy[1] = 0;
   pxy[2] = mxres - 1;
   pxy[3] = vhalf - 1;
   vs_clip(mhandle,1,pxy);

   pxy[0] = 0;
   pxy[1] = vhalf - 1;
   pxy[2] = mxres;
   pxy[3] = vhalf - 1;
   v_pline(mhandle,2,pxy);
 
   switch(unit_type)
   {
  	case 0:
		init_hinches();
		break;

	case 1:
		init_hpicas();
		break;

	case 2:
		init_hcents();
		break;

	case 3: init_hciceros();
		break;
   }
}




/**************************************************************************/
/* Function: init_vrulers()						  */
/* Description: Initialize vertical rulers				  */
/**************************************************************************/
init_vrulers()
{
   int pxy[4];
   int dummy;

   GDvq_extnd(mhandle,0,intout,hhalf,myres,&vrbuffer);
   vst_alignment(mhandle,1,1,&dummy,&dummy);
   vrule_mfdb.fd_addr = vrbuffer;
   vrule_mfdb.fd_w    = hhalf;
   vrule_mfdb.fd_h    = myres;
   vrule_mfdb.fd_wdwidth = (hhalf + 15)/16;
   vrule_mfdb.fd_stand = 0;
   vrule_mfdb.fd_nplanes = 1;

   pxy[0] = 0;
   pxy[1] = 0;
   pxy[2] = hhalf - 1;
   pxy[3] = myres - 1;
   vs_clip(mhandle,1,pxy);


   pxy[0] = hhalf - 1;
   pxy[1] = 0;
   pxy[2] = hhalf - 1;
   pxy[3] = myres - 1;
   v_pline(mhandle,2,pxy);
 
   switch(unit_type)
   {
  	case 0:
		init_vinches();
		break;

	case 1:
		init_vpicas();
		break;

	case 2:
		init_vcents();
		break;

	case 3: init_vciceros();
		break;
   }
}




/**************************************************************************/
/* Function: init_hinches()						  */
/* Description: Initialize h-ruler to inches				  */
/**************************************************************************/
init_hinches()
{
   int hpos;
   int vpos;
   int pxy[4];
   register int i;
   register int xmu_pos;
   register int len;
   char str[3];

   i = 1;
   xmu_pos = x_eighths;
   mutopage(xmu_pos,0,&hpos,&vpos,1);

   while(hpos < pagew)
   {
        hpos ++;
	len = vlen;
	if(!(i%2))
	   len += vlen;
	if(!(i%4))
	   len += vlen;
	if(!(i%8))
   	{
	   len += vlen;
	   if((view_size != PSIZE) &&
	      (view_size != PADJCNT))
	   {
	      itoa(i/8,str);
	      v_gtext(mhandle,hpos+2*hlen,2*vlen,str);
	   }
	}

	pxy[0] = pxy[2] = hpos;
	pxy[1] = vhalf - 1;
	pxy[3] = pxy[1] - len;
	v_pline(mhandle,2,pxy);
	xmu_pos += x_eighths;			/* Add an eighth to hpos */
	mutopage(xmu_pos,0,&hpos,&vpos,1);
        i++;
   }

}





/**************************************************************************/
/* Function: init_hpicas()						  */
/* Description: Initialize h-ruler to picas				  */
/**************************************************************************/
init_hpicas()
{
   int hpos;
   int vpos;
   int pxy[4];
   register int i;
   register int len;
   register int xmu_pos;
   char str[3];

   i = 1;
   xmu_pos = 216;			/* mu's per pica	*/
   mutopage(xmu_pos,0,&hpos,&vpos,1);
   while(hpos < pagew)
   {
	hpos++;
        len = vlen;
	if(!(i%10))
	{
	   len += vlen;
	   if( (view_size != PSIZE) && (view_size != PADJCNT))
	   {
	      itoa(i,str);
	      v_gtext(mhandle,hpos+2*hlen,2*vlen,str);
	   }
        }
	pxy[0] = pxy[2] = hpos;
	pxy[1] = vhalf - 1;
	pxy[3] = pxy[1] - len;
	v_pline(mhandle,2,pxy);
	xmu_pos += 216;
	mutopage(xmu_pos,0,&hpos,&vpos,1);
        i++;
   }

}





/**************************************************************************/
/* Function: init_hcents()						  */
/* Description: Initialize h-ruler to centimeters			  */
/**************************************************************************/
init_hcents()
{
   int hpos,vpos;
   int pxy[4];
   register int i;
   register int xmu_pos;
   register int len;
   char str[3];
   int centi_pos;

   i = 1;
   centi_pos = 0;		/* Avoid propagating error	   */
   xmu_pos = 51;				/* Mu's/millimeter */
   mutopage(xmu_pos,0,&hpos,&vpos,1);
   while(hpos < pagew)
   {
	hpos++;
	len = vlen;
	if(!(i%10))
   	{
	   len += vlen;
	   if((view_size != PSIZE) &&
	      (view_size != PADJCNT))
	   {
	      itoa(i/10,str);
	      v_gtext(mhandle,hpos+2*hlen,2*vlen,str);
	   }
	   centi_pos += 510;
	   xmu_pos = centi_pos;		/* re-calibrate spacing */
	}

	pxy[0] = pxy[2] = hpos;
	pxy[1] = vhalf - 1;
	pxy[3] = pxy[1] - len;
	v_pline(mhandle,2,pxy);
	xmu_pos += 51;
	mutopage(xmu_pos,0,&hpos,&vpos,1);
        i++;
   }

}



/**************************************************************************/
/* Function: init_hciceros()						  */
/* Description: Initialize h-ruler to ciceros				  */
/**************************************************************************/
init_hciceros()
{
   int hpos;
   int vpos;
   int pxy[4];
   register int i;
   register int len;
   register int xmu_pos;
   char str[3];

   i = 1;
   xmu_pos = 231;			/* mu's per cicero	*/
   mutopage(xmu_pos,0,&hpos,&vpos,1);
   while(hpos < pagew)
   {
	hpos++;
        len = vlen;
	if(!(i%10))
	{
	   len += vlen;
	   if( (view_size != PSIZE) && (view_size != PADJCNT))
	   {
	      itoa(i,str);
	      v_gtext(mhandle,hpos+2*hlen,2*vlen,str);
	   }
        }
	pxy[0] = pxy[2] = hpos;
	pxy[1] = vhalf - 1;
	pxy[3] = pxy[1] - len;
	v_pline(mhandle,2,pxy);
	xmu_pos += 231;
	mutopage(xmu_pos,0,&hpos,&vpos,1);
        i++;
   }
}



/**************************************************************************/
/* Function: init_vinches()						  */
/* Description: initialize v-ruler to inches				  */
/**************************************************************************/
init_vinches()
{
   int hpos;
   int vpos;
   int pxy[4];
   register int i;
   register int ymu_pos;
   int len;
   char str[3];

   i = 1;
   ymu_pos = y_eighths;
   mutopage(0,ymu_pos,&hpos,&vpos,1);
   while(vpos < pageh)
   {
	len = hlen;
	if(!(i%2))
	   len += hlen;
	if(!(i%4))
	   len += hlen;
	if(!(i%8))
   	{
	   len += hlen;
	   if((view_size != PSIZE) &&
	      (view_size != PADJCNT))
	   {
	      itoa(i/8,str);
	      v_gtext(mhandle,3*hlen,vpos+vlen,str);
	   }
	}

	pxy[0] = hhalf - 1;
	pxy[1] = pxy[3] = vpos;
	pxy[2] = pxy[0] - len;
	v_pline(mhandle,2,pxy);
	ymu_pos += y_eighths;			/* Add an eighth to hpos */
	mutopage(0,ymu_pos,&hpos,&vpos,1);
        i++;
   }

}




/**************************************************************************/
/* Function: init_vpicas()						  */
/* Description: Initialize v-ruler to picas				  */
/**************************************************************************/
init_vpicas()
{
   int hpos;
   int vpos;
   int pxy[4];
   register int i;
   register int ymu_pos;
   register int len;
   char str[3];

   i = 1;
   ymu_pos = 192;
   mutopage(0,ymu_pos,&hpos,&vpos,1);
   while(vpos < pageh)
   {
        len = hlen;
	if(!(i%10))
	{
	   len += hlen;
	   if((view_size != PSIZE) &&
	      (view_size != PADJCNT))
	   {
	      itoa(i,str);
	      v_gtext(mhandle,3*hlen,vpos+vlen,str);
	   }
	}
	pxy[0] = hhalf - 1;
	pxy[1] = pxy[3] = vpos;
	pxy[2] = pxy[0] - len;
	v_pline(mhandle,2,pxy);
	ymu_pos += 192;
	mutopage(0,ymu_pos,&hpos,&vpos,1);
        i++;
   }
}




/**************************************************************************/
/* Function: init_vcents()						  */
/* Description: Initialize v-ruler to centimeters			  */
/**************************************************************************/
init_vcents()
{
   int hpos;
   int vpos;
   int pxy[4];
   register int i;
   register int ymu_pos;
   register int len;
   char str[3];
   int centi_pos;

   i = 1;
   centi_pos = 0;
   ymu_pos = 45;
   mutopage(0,ymu_pos,&hpos,&vpos,1);
   while(vpos < pageh)
   {
	len = hlen;
	if(!(i%10))
   	{
	   len += hlen;
	   if((view_size != PSIZE) &&
	      (view_size != PADJCNT))
	   {
	      itoa(i/10,str);
	      v_gtext(mhandle,3*hlen,vlen+vpos,str);
	   }
	   centi_pos += 454;
	   ymu_pos = centi_pos;
	}

	pxy[0] = hhalf - 1;
	pxy[1] = pxy[3] = vpos;
	pxy[2] = pxy[0] - len;
	v_pline(mhandle,2,pxy);
	ymu_pos += 45;   
	mutopage(0,ymu_pos,&hpos,&vpos,1);
        i++;
   }

}




/**************************************************************************/
/* Function: init_vciceros()						  */
/* Description: Initialize v-ruler to ciceros				  */
/**************************************************************************/
init_vciceros()
{
   int hpos;
   int vpos;
   int pxy[4];
   register int i;
   register int ymu_pos;
   register int len;
   char str[3];

   i = 1;
   ymu_pos = 205;
   mutopage(0,ymu_pos,&hpos,&vpos,1);
   while(vpos < pageh)
   {
        len = hlen;
	if(!(i%10))
	{
	   len += hlen;
	   if((view_size != PSIZE) &&
	      (view_size != PADJCNT))
	   {
	      itoa(i,str);
	      v_gtext(mhandle,3*hlen,vpos+vlen,str);
	   }
	}
	pxy[0] = hhalf - 1;
	pxy[1] = pxy[3] = vpos;
	pxy[2] = pxy[0] - len;
	v_pline(mhandle,2,pxy);
	ymu_pos += 205;
	mutopage(0,ymu_pos,&hpos,&vpos,1);
        i++;
   }
}



/**************************************************************************/
/* Function: show_rulers()						  */
/* Description: Handle the display of rulers				  */
/**************************************************************************/   
show_rulers()
{
int pxy[8];
long scrn_mfdb;
int xoffset,yoffset;
int dummy;
int color_index[2];


   color_index[0] = 1;
   color_index[1] = 0;
   scrn_mfdb = 0L;
   mutopage(page_area.g_x,page_area.g_y,&xoffset,&yoffset,1);
   vsf_interior(shandle,0);

   pxy[0] = xoffset;
   pxy[1] = 0;
   pxy[2] = pxy[0] + dpwork.g_w - 1;
   pxy[3] = vhalf - 1;
   pxy[4] = pwork.g_x + hhalf - 1;
   pxy[5] = pwork.g_y;
   pxy[6] = pxy[4] + dpwork.g_w - 1;
   pxy[7] = pxy[5] + vhalf - 1;
   if(ruler_hasmem)
      vrt_cpyfm(rule_handle,1,pxy,&hrule_mfdb,&scrn_mfdb,color_index);
   else
      vr_recfl(shandle,&pxy[4]);		/* Don't draw in xor */
   pxy[0] = 0;
   pxy[1] = yoffset;
   pxy[2] = hhalf - 1;
   pxy[3] = pxy[1] + dpwork.g_h - 1;
   pxy[4] = pwork.g_x;
   pxy[5] = dpwork.g_y;
   pxy[6] = pxy[4] + hhalf - 1;
   pxy[7] = pxy[5] + dpwork.g_h - 1;
   if(ruler_hasmem)
      vrt_cpyfm(rule_handle,1,pxy,&vrule_mfdb,&scrn_mfdb,color_index);
   else
      vr_recfl(shandle,&pxy[4]);
   pxy[0] = pwork.g_x;
   pxy[1] = pwork.g_y;
   pxy[2] = dpwork.g_x;
   pxy[3] = dpwork.g_y;
   vr_recfl(shandle,pxy);		/* Don't draw in xor */

   pxy[0] = dpwork.g_x;
   pxy[1] = pwork.g_y;
   pxy[2] = dpwork.g_x;
   pxy[3] = dpwork.g_y;
   pxy[4] = pwork.g_x;
   pxy[5] = dpwork.g_y;
   v_pline(rule_handle,3,pxy);

   graf_mkstate(&newx,&newy,&dummy,&dummy);
   xold_mark = -1;
   yold_mark = -1;
   do_rule_mark();
}




/**************************************************************************/
/* Function: do_grids()							  */
/* Description: Display grids on screen					  */
/**************************************************************************/
do_grids(clip,x1,y1,x2,y2)
int clip;
register int x1;
int y1;
register int x2;
int y2;
{

   int xpos,ypos;
   register int hmus,vmus;
   int bytes_line;

   bytes_line = (mxres + 7)/8;
   bytes_line = (bytes_line + 1) & 0xFFFE;

   if(clip)
   {
	x1 -= hgridspace;
	x2 += hgridspace;
	y1 -= vgridspace;
	y2 += vgridspace;
   }
   x1 = max(0,x1);
   y1 = max(0,y1);

   for(vmus = vgridspace;vmus < vpage_size;vmus += vgridspace)
   {
        if(!clip || (vmus >= y1 && vmus <= y2))
        {
	   for(hmus = hgridspace;hmus < hpage_size;hmus += hgridspace)
	   {
	      if(!clip || (hmus >= x1 && hmus <= x2))
	      {
	         mutopage(hmus,vmus,&xpos,&ypos,1);
	         put_mpix(xpos,ypos,bytes_line);
	      }
	   }
        }
   }
}




/**************************************************************************/
/* Function: put_mpix()							  */
/* Description: Put grid pixel in memory buffer				  */ 
/**************************************************************************/
put_mpix(x,y,bytes_line)
int x,y;
int bytes_line;
{
   char *ptr;
   register long offset;


   offset = page_ptr;

   offset += (long)((long)bytes_line*(long)y);
   offset += (long)(x/8);
   ptr = (char *)offset;
   *ptr |= pixtbl[x%8];
}




/**************************************************************************/
/* Function: calc_size_fit()						  */
/* Description: Calc page size for size to fit and PADJCNT		  */
/**************************************************************************/
calc_size_fit(item)
int item;
{
	int hwidth;
	int pixw;
 	int pixh;

	pixw = hmutopix(hpage_size);
	pixh = vmutopix(vpage_size);	
        hwidth = ((item == PADJCNT) ? (pixw * 2) : (pixw));
	if(dpwork.g_w <= scale_iv(dpwork.g_h,hwidth,pixh))
	{
		pagew = dpwork.g_w;
		pageh = scale_iv(dpwork.g_w,pixh,hwidth);
	}
	else
	{
		pageh = dpwork.g_h;
		pagew = scale_iv(dpwork.g_h,hwidth,pixh);
		pageh = dpwork.g_h = scale_iv(pagew,pixh,hwidth);
	}
        pxy[0] = dpwork.g_x;
        pxy[1] = dpwork.g_y;
	pxy[2] = dpwork.g_x + pagew - 1;
	pxy[3] = dpwork.g_y + pageh - 1;

}




/**************************************************************************/
/* this is only temporary for experimental purposes 			  */
/**************************************************************************/
/* Function: redraw_alt()						  */
/* Description: Redraw Handler for PADJCNT				  */
/**************************************************************************/
redraw_alt()
{
   int endflag;
   int g_flag;				/* graphic region? */
   int pxy[4];
   int rtemp_page;
   int tpage;

   PAGE *rpagehd;
   PAGE *rcurpage;
   ARTICLE *rarthd;

   if(tmplate_flag)
   {
      rpagehd = pagehd;
      rcurpage = curpage;
      rarthd   = arthd;
   }

   endflag = 0;
   if((!blit_flag) || mode_change)
   {
      clrmem(page_ptr,pagebytes);

      pxy[1] = 0;
      pxy[3] = pageh-1;

      if(show_grids)
	do_grids(0,0,0,0,0);

      rtemp_page = curr_page;
      tpage = ((curr_page % 2) ? (curr_page - 1) : (curr_page));
      for(curr_page = tpage;curr_page <= tpage+1;curr_page++)
      {
	  if(tmplate_flag)
          {
	    if(curr_page == -2)
	    {
	      pagehd = curpage = left_tmplate;
	      arthd  = ltarthd;
	    }
	    else
	    {
	      pagehd = curpage = right_tmplate;
	      arthd = rtarthd;
	    }
	      
          }

          display_template(1,0L);

          region_ptr = get_fregion(curr_page,
			&rect_in_mu[0],&rect_in_mu[1],
			&rect_in_mu[2],&rect_in_mu[3],&g_flag);

          while(region_ptr)
          {
 	     mclip();
             if(!g_flag)
                get_txtattr(region_ptr,&gltxtattr);
	     else
	        get_grattr(region_ptr,glgrattr);
	     if(g_flag || !mode_flag)
	     {
                opcode = get_fprimitive(region_ptr,&count,&wmode);
                while(opcode != -1)
                {
	          switch(opcode)
	          {
	   	    case 3:
	            case 4:
	            case 0: redraw_polygon(count,wmode,g_flag);
                            break;

		    case 1: redraw_ellipse(wmode,g_flag);
		            break;

	            case 2: graphic_setup();
  	                    break;
	          }
                  opcode = get_nprimitive(&count,&wmode);
                }
	    }
            if(mode_flag && !g_flag)
	    {
	       if(txtptr = get_txtptr(region_ptr))
               {
		  if(*txtptr)
		  {
	             get_buffvars(region_ptr);
		     open_region(region_ptr);
                     do_regoutput(txtptr,&endflag);
                     put_buffvars(region_ptr);
		  }
               }
	       GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);		
            }
	    region_ptr = get_nregion(&rect_in_mu[0],&rect_in_mu[1],
 		                  &rect_in_mu[2],&rect_in_mu[3],&g_flag);
	 } /* while region_ptr */
         display_template(2,0L);
	 do_numbers(0L,0);
       }   /* for(curr_page =temp_page;curr_page <= temp_page+1;curr_page++)*/

   	set_clip(TRUE,&dpwork);
        if(view_size == PADJCNT)
        {
	  vsl_type(mhandle,1);
	  vsl_width(mhandle,1);
	  vsl_ends(mhandle,0,0);
          pxy[0] = pxy[2] = pagew/2;
          pxy[1] = 0;
          pxy[3] = pageh;
          v_pline(mhandle,2,pxy);
        }
        mode_change = FALSE;
        curr_page = rtemp_page;	
	alt_offset = ((curr_page % 2) ? (1) : (0));
     }   			/*if((!blit_flag) || mode_change)*/
   do_blit();			/* Either blit now or redraw,then blit*/
   if(tmplate_flag)
   {
     pagehd = rpagehd;
     curpage = rcurpage;
     arthd   = rarthd;
   }
}

/************************************************************************/
/*									*/
/*	In:	Pointer to graphic region to repel around		*/
/*		x1,y1,x2,y2, bounding rectangle in mus of this region   */
/*									*/
/*	Builds graphic region using scanner mem driver into another     */
/*	scan buffer. Assumes scan buffer already has masks drawn into   */
/*	it so display list can now be cleared.  Blit to a smaller buffer*/
/*	then call buildmask to build actual mask.  AND this buffer into */
/*    	the original scan buffer to create repel effect			*/
/************************************************************************/
repel_images(region_ptr,mux1,muy1,mux2,muy2,repoffset,buffaddr)
long region_ptr;
int mux1,muy1,mux2,muy2;
int repoffset;
long *buffaddr;
{
   long tmp_scanbuf;
   long maskbuf;
   int count,wmode,opcode;
   int tmpmode;
   int tmpprint;
   int x1,y1,x2,y2;
   int width,height;
   FDB scanmfdb;
   FDB maskmfdb;
   int pxy[8];
   int hoffset,voffset;
   int nrect[4];
   int oldwidth,oldheight;
   int newwidth,newheight;
   register int i;
   int odeltax,ndeltax,odeltay,ndeltay;
   int byte_width;
   long bufsize;

   hoffset = repoffset * 18;
   voffset = repoffset * 16;		/* Convert to mus */

   nrect[0] = mux1 - hoffset;
   nrect[1] = muy1 - voffset;
   nrect[2] = mux2 + hoffset;
   nrect[3] = muy2 + voffset;

   mutomem(nrect[0],nrect[1],&x1,&y1);
   mutomem(nrect[2],nrect[3],&x2,&y2);
   if(x1 < 0)
	x1 = 0;
   if(y1 < 0)
	y1 = 0;
   if(x2 > scan_xres)
	x2 = scan_xres;
   if(y2 > scan_yres)
	y2 = scan_yres;
   width = x2 - x1 + 1;
   height = y2 - y1 + 1;
   scanmfdb.fd_w = scan_xres;
   maskmfdb.fd_w = width;
   scanmfdb.fd_h = scan_yres;
   maskmfdb.fd_h = height;
   scanmfdb.fd_wdwidth = (scan_xres + 15)/16;
   maskmfdb.fd_wdwidth = (width + 15)/16;
   scanmfdb.fd_stand = maskmfdb.fd_stand = 0;
   scanmfdb.fd_nplanes = maskmfdb.fd_nplanes = 1;
   if(*buffaddr)
   {
      scanmfdb.fd_addr = scanptr;
      maskmfdb.fd_addr = *buffaddr;
   }	
   else
   {
      oldwidth = mux2 - mux1 + 1;
      oldheight = muy2 - muy1 + 1;
      newwidth = nrect[2] - nrect[0] + 1;
      newheight = nrect[3] - nrect[1] + 1;
      maskbuf = get_lcmem((long)((long)height * ((((long)width+7)/8)+1)));
      tmpmode = mode_flag;
      tmpprint = print_flag;
      tmp_scanbuf = scanptr;
      scanptr = get_lcmem((long)((long)scan_yres * ((((long)scan_xres+7)/8)+1)));

      byte_width = ((width+2+15)/16)*2;
      bufsize = (long)byte_width * (long)(height + 2);
      newscreen = (((realscreen = (long)get_lcmem(bufsize + 512)) + 512)
				&0xFFFFFE00L);
      if(!scanptr || !maskbuf || !newscreen)
      {
	 if(!alerted)
	 {
	    alerted = 1;
  	    alert_cntre(ALERT31);
	 }
	 scanptr = tmp_scanbuf;
	 return;
      }	 
	 
      GDvq_extnd(mhandle,0,intout,scan_xres,scan_yres,&scanptr);
      scanmfdb.fd_addr = scanptr;
      maskmfdb.fd_addr = maskbuf;

      pxy[0] = x1;
      pxy[1] = y1;
      pxy[2] = x2;
      pxy[3] = y2;
      pxy[4] = pxy[5] = 0;
      pxy[6] = width - 1;
      pxy[7] = height - 1;

      mode_flag = TRUE;
      print_flag = 2;
      opcode = get_fprimitive(region_ptr,&count,&wmode);
             while(opcode != -1)
             {
	        switch(opcode)
	        {
		   case 3:
	           case 4:
	           case 0:
			   i=0;
			   while(i<count*2)
			   {
				   odeltax = ptsarray[i] - mux1;
				   ndeltax = scale_iv(odeltax,newwidth,
					oldwidth); 
				   ptsarray[i++] = nrect[0] + ndeltax;

				   odeltay = ptsarray[i] - muy1;
				   ndeltay = scale_iv(odeltay,newheight,
					oldheight);
				   ptsarray[i++] = nrect[1] + ndeltay;
			   } 
			   redraw_polygon(count,wmode,0);
                           break;

		   case 1: 
			        case12_scale(mux1,muy1,
					     oldwidth,oldheight,
					     nrect[0],
					     nrect[1],
					     newwidth,
					     newheight,1);
 			   redraw_ellipse(wmode,0);
		           break;

		   case 2: 
			        case12_scale(mux1,muy1,
					     oldwidth,oldheight,
					     nrect[0],
					     nrect[1],
					     newwidth,
					     newheight,2);
			   insert_graphic();
  		           break;
	        }
                opcode = get_nprimitive(&count,&wmode);
             }
      vro_cpyfm(shandle,3,pxy,&scanmfdb,&maskmfdb);
      buildmsk(maskbuf,width,height);
      free(scanptr);
      scanptr = tmp_scanbuf;   
      GDvq_extnd(mhandle,0,intout,scan_xres,scan_yres,&scanptr);
      scanmfdb.fd_addr = scanptr;
      mode_flag = tmpmode;
      print_flag = tmpprint;
      set_repbuff(region_ptr,maskbuf);
   }

   pxy[0] = pxy[1] = 0;
   pxy[2] = width - 1;
   pxy[3] = height - 1;
   pxy[4] = x1;
   pxy[5] = y1;
   pxy[6] = x2;
   pxy[7] = y2;
   vro_cpyfm(shandle,1,pxy,&maskmfdb,&scanmfdb);	/* "AND" blt */

}


buildmsk(srcbuf,xres,yres)
long srcbuf;
register int xres,yres;
{
   FDB srcmfdb;
   FDB desmfdb;
   int clip[4];
   int pts[8];
   int byte_width;
   long bufsize;
   long screen;
   int attr[5];

   gsx_moff();   
   vqf_attributes(shandle,attr);
   vsf_interior(shandle,1);		/* Solid fills for seed fill */
   screen = Logbase();

   byte_width = ((xres+2+15)/16)*2;
   bufsize = (long)byte_width * (long)(yres + 2);

   srcmfdb.fd_addr = srcbuf;
   desmfdb.fd_addr = newscreen;
   srcmfdb.fd_w = xres;
   desmfdb.fd_w = xres + 2;
   srcmfdb.fd_h = yres;
   desmfdb.fd_h = yres + 2;
   srcmfdb.fd_wdwidth = (xres + 15)/16;
   desmfdb.fd_wdwidth = (xres + 2 + 15)/16;
   srcmfdb.fd_stand = desmfdb.fd_stand = 0;
   srcmfdb.fd_nplanes = desmfdb.fd_nplanes = 1;

   pts[0] = 0;
   pts[1] = 0;
   pts[2] = xres - 1;
   pts[3] = yres - 1;
   pts[4] = 1;
   pts[5] = 1;
   pts[6] = xres;
   pts[7] = yres;

   vro_cpyfm(shandle,3,pts,&srcmfdb,&desmfdb);

   setvdi(xres+2,yres+2,byte_width);		/* Set vdi variables */

   Setscreen(newscreen,-1L,-1L);
   clip[0] = 0;
   clip[1] = 0;
   clip[2] = xres+1;
   clip[3] = yres+1;
   vs_clip(shandle,1,clip);   

   v_contourfill(shandle,0,0,1);
   vro_cpyfm(shandle,6,pts,&srcmfdb,&desmfdb);
   pts[0] += 1;
   pts[1] += 1;
   pts[2] += 1;
   pts[3] += 1;
   pts[4] -= 1;
   pts[5] -= 1;
   pts[6] -= 1;
   pts[7] -= 1;
   vro_cpyfm(shandle,3,pts,&desmfdb,&srcmfdb);
   fixvdi();
   Setscreen(screen,-1L,-1L);

   vs_clip(shandle,0,clip);
   vsf_interior(shandle,attr[0]);
   free(realscreen);
   gsx_mon();
}


free_repbuffs()
{
   register long region_ptr;
   int g_flag;
   int rect[4];
   long tmppage;

   tmppage = curpage;   
   region_ptr = get_fregion(curr_page,
			&rect[0],&rect[1],
			&rect[2],&rect[3],&g_flag);
   while(region_ptr)
   {
	if(g_flag)
		clr_grbuff(region_ptr);
        region_ptr = get_nregion(&rect[0],&rect[1],
 			           &rect[2],&rect[3],&g_flag);
    }
    curpage = tmppage;
}



display_template(num,rgrect)
int num;
register int rgrect[];
{
  int endflag;
  int g_flag;				/* graphic region? */
  PAGE *rpagehd;
  PAGE *rcurpage;
  int  rtemp_page;
  ARTICLE *rarthd;
  int tgrect[4];
  int tpxy[4];
  int rectmu[4];

  if(disp_pos)				/* display in back */
  {
     if(num != 1)			/* so goes first   */
	   return;
  }
  else
  {
     if(num != 2)
	   return;
  }

  if(!tmplate_flag && displ_tmpl_flag)  
  {
    rpagehd = pagehd;
    rcurpage = curpage;
    rarthd   = arthd;
 
    switch(disp_type)
    {
      case 0: /* both */
	      pagehd=curpage=((curr_page%2)?(right_tmplate):(left_tmplate));
	      arthd = ((curr_page%2)?(rtarthd):(ltarthd));
	      break;
      case 1: /* left only */
	      pagehd = curpage = left_tmplate;
	      arthd  = ltarthd;
	      break;
      case 2: /* right only */
	      pagehd = curpage = right_tmplate;
	      arthd = rtarthd;
	      break;
    }

    rtemp_page = curr_page;
    curr_page = curpage->pagenum;

    endflag = 0;

    region_ptr = get_fregion(curr_page,
		        &rectmu[0],&rectmu[1],
			&rectmu[2],&rectmu[3],&g_flag);


    while(region_ptr)
    {
        if(rgrect)
	{
           mutopage(rectmu[0],rectmu[1],&tpxy[0],&tpxy[1]);
           mutopage(rectmu[2],rectmu[3],&tpxy[2],&tpxy[3]);

	   tgrect[0] = tpxy[0];
           tgrect[1] = tpxy[1];
           tgrect[2] = tpxy[2] - tpxy[0] + 1;
           tgrect[3] = tpxy[3] - tpxy[1] + 1;
        }

        if(!rgrect || rc_intersect(rgrect,tgrect))
	{
	  if(!rgrect)
          	mclip();

          if(!g_flag)
          {
             get_txtattr(region_ptr,&gltxtattr);
	     if(mode_flag)
	     {
	        GDvq_extnd(mhandle,0,intout,scan_xres,scan_yres,&scanptr);
		if(!rgrect)
                	scan_clip();
	        clrmem(scanptr,scan_bytes);
	     }
          }
	  else 
	     get_grattr(region_ptr,glgrattr);

	  if(g_flag || !mode_flag)
          {		
            opcode = get_fprimitive(region_ptr,&count,&wmode);
            while(opcode != -1)
            {
	      switch(opcode)
	      {
	        case 3:
	        case 4:
	        case 0: redraw_polygon(count,wmode,g_flag);
                        break;

	        case 1: redraw_ellipse(wmode,g_flag);
	                break;

	        case 2: graphic_setup();
  		        break;
	      }
              opcode = get_nprimitive(&count,&wmode);
            }
          }
       
          if(mode_flag && !g_flag)
	  {
	    if(txtptr = get_txtptr(region_ptr))
            {
	       if(*txtptr)
	       {
		  if(!rgrect)
		  {
	            get_buffvars(region_ptr);
	            open_region(region_ptr);
		    do_regoutput(txtptr,&endflag);
                    put_buffvars(region_ptr);
		  }
		  else
		  {
		     open_region(region_ptr);
                     do_clipregout(tgrect[0],tgrect[1],
			tgrect[2] + tgrect[0] - 1,
			tgrect[3] + tgrect[1] - 1);
		  }
	       }
            }
	    GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);
          }
	}
        region_ptr = get_nregion(&rectmu[0],&rectmu[1],
 	  	                   &rectmu[2],&rectmu[3],&g_flag);

   }
   pagehd    = rpagehd;
   curpage   = rcurpage;
   curr_page = rtemp_page;
   arthd     = rarthd;
  }
}


tdo_template(num)
int num;
{
  int endflag;
  int g_flag;				/* graphic region? */
  PAGE *rpagehd;
  PAGE *rcurpage;
  int  rtemp_page;
  ARTICLE *rarthd;
  int rectmu[4];

  if(disp_pos)				/* display in back */
  {
     if(num != 1)			/* so goes first   */
	   return;
  }
  else
  {
     if(num != 2)
	   return;
  }

  if(!tmplate_flag && displ_tmpl_flag)  
  {
    rpagehd = pagehd;
    rcurpage = curpage;
    rarthd   = arthd;
 
    switch(disp_type)
    {
      case 0: /* both */
	      pagehd=curpage=((curr_page%2)?(right_tmplate):(left_tmplate));
	      arthd = ((curr_page%2)?(rtarthd):(ltarthd));
	      break;
      case 1: /* left only */
	      pagehd = curpage = left_tmplate;
	      arthd  = ltarthd;
	      break;
      case 2: /* right only */
	      pagehd = curpage = right_tmplate;
	      arthd = rtarthd;
	      break;
    }

    rtemp_page = curr_page;
    curr_page = curpage->pagenum;

    endflag = 0;

    region_ptr = get_fregion(curr_page,
		        &rectmu[0],&rectmu[1],
			&rectmu[2],&rectmu[3],&g_flag);
    while(region_ptr)
    {
          if(!g_flag)
             get_txtattr(region_ptr,&gltxtattr);
	  else 
	     get_grattr(region_ptr,glgrattr);

	  if(g_flag)
          {		
            opcode = get_fprimitive(region_ptr,&count,&wmode);
            while(opcode != -1)
            {
	      switch(opcode)
	      {
		    case 3:
		    case 4:
		    case 0:
		    case 1:  TYF_Gtype = 5;
	   		     calc_prim(opcode,&TYF_Gx0,&TYF_Gy0,
					&TYF_Gx1,&TYF_Gy1,count);
			     insGR_TYF(opcode,count,glgrattr);
		 	     break;
		    case 2:  TYF_Gfile = (char *)&ptsarray[5];
			     TYF_Gx0 = ptsarray[0];
			     TYF_Gy0 = ptsarray[1];
			     TYF_Gx1 = ptsarray[2];
			     TYF_Gy1 = ptsarray[3];
			     switch(ptsarray[4])
			     {
				case 0:
				   TYF_Gtype = 2;
				   break;
				case 1:
				   TYF_Gtype = 3;
				   break;
				case 2:
				   TYF_Gtype = 1;
				   break;
			        case 3:
				   TYF_Gtype = 4;
				   break;
			     }
			     insGR_TYF(opcode,count,glgrattr);
			     break;
	      }
              opcode = get_nprimitive(&count,&wmode);
            } /* while */
          }   /* if g_flag */
       
          if(!g_flag)
	  {
	    if(txtptr = get_txtptr(region_ptr))
            {
	       if(*txtptr)
	       {
		  get_buffvars(region_ptr);
		  open_region(region_ptr);
		  do_tdoout(txtptr,&endflag);
	       }
            }
          }
	}
        region_ptr = get_nregion(&rectmu[0],&rectmu[1],
 	  	                   &rectmu[2],&rectmu[3],&g_flag);

   pagehd    = rpagehd;
   curpage   = rcurpage;
   curr_page = rtemp_page;
   arthd     = rarthd;
  }
}

redraw_spot(rptr,murect,bltflag)
register REGION *rptr;
register int murect[];
int bltflag;
{
   int g_flag;				/* graphic region? */
   int rgrect[4];
   int tgrect[4];
   int rpxy[4];
   int tpxy[4];
   int murec1[4];
   int pts;

   int xoffset,yoffset;

   if(!rptr)
   {
	pts = 36;
	xoffset = pts * 18;
	yoffset = pts * 16;
   }	
   else
   {
	pts = rptr->grattr[1];
        if(pts && (rptr->grattr[2] & 0x8000))
        {
	   xoffset = pts * 18;
	   yoffset = pts * 16;
        }
        else
	{
	   xoffset = 162; /* offsets are in machine units */
	   yoffset = 144; /* an eighth of a inch each way*/
	}
   }

   murect[0] -= xoffset;
   murect[1] -= yoffset;
   murect[2] += xoffset;
   murect[3] += yoffset;

   
   GDvq_extnd(mhandle,0,intout,mxres,myres,&page_ptr);

   mutopage(murect[0],murect[1],&rpxy[0],&rpxy[1],1);
   mutopage(murect[2],murect[3],&rpxy[2],&rpxy[3],1);
#if NEVER
   rpxy[0] -= 2;		/* With solid fills perimeter is on */
   rpxy[1] -= 2;		/* so when erasing with hollow fill */
   rpxy[2] += 2;		/* we must ......		    */
   rpxy[3] += 2;		/* Adjust for perimeter being off   */
#endif
   rpxy[0] = max(0,rpxy[0]);
   rpxy[1] = max(0,rpxy[1]);
   rpxy[2] = min(pagew - 1,rpxy[2]);
   rpxy[3] = min(pageh - 1,rpxy[3]);

   vs_clip(mhandle,1,rpxy);
   write_white(mhandle);
   v_bar(mhandle,rpxy);
   write_black(mhandle);

   rgrect[0] = rpxy[0];
   rgrect[1] = rpxy[1];
   rgrect[2] = rpxy[2] - rpxy[0] + 1;
   rgrect[3] = rpxy[3] - rpxy[1] + 1;

   if(show_grids)	/* moved it here cjg */
	do_grids(1,murect[0],murect[1],murect[2],murect[3]);

   display_template(1,rgrect);
   
   region_ptr = get_fregion(curr_page,
	&murec1[0],&murec1[1],
	&murec1[2],&murec1[3],&g_flag);
   while(region_ptr)
   {
     if(rptr != region_ptr)
     {
        mutopage(murec1[0],murec1[1],&tpxy[0],&tpxy[1]);
        mutopage(murec1[2],murec1[3],&tpxy[2],&tpxy[3]);
	
	tgrect[0] = tpxy[0];
        tgrect[1] = tpxy[1];
        tgrect[2] = tpxy[2] - tpxy[0] + 1;
        tgrect[3] = tpxy[3] - tpxy[1] + 1;
	
	if(rc_intersect(rgrect,tgrect))
	{
	   if(g_flag)
               get_grattr(region_ptr,glgrattr);

           if(g_flag || !mode_flag)
           {
               opcode = get_fprimitive(region_ptr,&count,&wmode);
               while(opcode != -1)
               {
                   switch(opcode)
                   {
        	       case 3:
	               case 4:
	               case 0: redraw_polygon(count,wmode,g_flag);
                               break;

		       case 1: redraw_ellipse(wmode,g_flag);
		               break;

		       case 2: graphic_setup();
  		               break;
	            }
                    opcode = get_nprimitive(&count,&wmode);
               }
	   }
           if(mode_flag && !g_flag)
	   {
	      if(txtptr = get_txtptr(region_ptr))
              {
	          if(*txtptr)
		  {
	             open_region(region_ptr);
                     do_clipregout(tgrect[0],tgrect[1],
			tgrect[2] + tgrect[0] - 1,
			tgrect[3] + tgrect[1] - 1);
                  }
	      }
           }
	}
      }
      region_ptr = get_nregion(&murec1[0],&murec1[1],
 			       &murec1[2],&murec1[3],&g_flag);
   }

   display_template(2,rgrect);
   do_numbers(rgrect,0);

   if(bltflag)
   {
      mclip();
      do_blit();
   }

}
