/* $Log:	downloadchar.c,v $
 * Revision 0.8  92/11/23  19:46:43  19:46:43  bt (Bo Thide')
 * Fixed resolution bug. Portable downloading. Added/changed options. PJXL color support
 * 
 * Revision 0.7  92/11/13  02:41:27  02:41:27  bt (Bo Thide')
 * More bug fixes and improvements. Support for PaintJet XL
 * 
 * Revision 0.6  92/11/10  21:47:43  21:47:43  bt (Bo Thide')
 * Bug fixes. Added -R option. Better font handling.
 * 
 * Revision 0.5  92/11/09  16:25:30  16:25:30  bt (Bo Thide')
 * Rewrite of dospecial.c. Extended \special support
 * 
 * Revision 0.4  92/11/08  02:45:45  02:45:45  bt (Bo Thide')
 * Changed to portable bit manipulations. Replaced strrstr for non-POSIX compliant C. Fixed numerous bugs. Added support for more \special's.
 * 
 * Revision 0.3  92/08/24  12:45:38  12:45:38  bt (Bo Thide')
 * Fixed 8 bit (dc font) support.
 * 
 * Revision 0.2  92/08/23  17:28:56  17:28:56  bt (Bo Thide')
 * Source cleaned up.  Changed certain function calls.  Removed globals.
 * 
 * Revision 0.1  92/08/22  23:58:47  23:58:47  bt (Bo Thide')
 * First Release.
 *  */

/*
 * Download character 'c', assuming that the corresponding font file is in 
 * .pk format. Therefore, 'pktopxl(c)' is called which converts the pk-coded
 * character into the corresponding byte aligned pixel pattern, stored in
 * 'pxlbuffer'. 'pktopxl(c)' also determines the global variables
 *      c_width, c_height, c_hoffset, c_voffset.
 *
 * For landscape mode the pixel pattern then will be rotated and stored at
 * the end of the character pixel pattern at 'endofchardata' in pxlbuffer.
 * The appropriate pixel pattern then is downloaded, i.e is put in bitfile,
 * if possible, including the corresponding character descriptor for the
 * printer. For those characters which don't fit into the printer's maximum
 * character cell (use_count < 0) raster information is stored in *gfont
 * and memory space is allocated to store the corresponding pixel pattern.
 * Stored characters are drawn in graphics mode by 'drawchar(c)'.
 */

#include <stdio.h>
#include <stdlib.h>
#include "globals.h"
#include "pcl.h"

static char rcsid[] = "$Header: downloadchar.c,v 0.8 92/11/23 19:46:43 bt Exp $";


int downloadchar(bitfile, c, device)
FILE	*bitfile;
int	c;
short	device;
{
	int		i;
	charfmt		*u;
	int		length;
	int 		width_bytes;
	int		width, height;
	byte		*p;

	pktopxl(c);

	/* Determine the char descriptor values */
	cd.format = 4;
	cd.continuation = 0;
	cd.size = 14;
	cd.class = 1;
	cd.reserved = 0;
	if(landscape){
		p = (byte *)rotatechar();
		width  = c_height;
		height = c_width;
		cd.orientation = '\1';
		cd.left_offset = -c_voffset;
		cd.top_offset  = height - c_hoffset - 1;
	}
	else{
		width  = c_width;
		height = c_height;
		cd.orientation = '\0';
		cd.left_offset = -c_hoffset;
		cd.top_offset  = c_voffset;
		p =  pxlbuffer;
	}
	width_bytes = (width + 7) / 8;
	length = height*width_bytes;

	/* This is for empty characters */
	if(!length) {
		length = 1;
		if(!width)
			width=1;
		if(!height) {
			height = 1;
			cd.top_offset = 1;
		}
	}

	u = cbase + c;
	cd.char_width  = (ushort)width;
	cd.char_height = (ushort)height;
	cd.delta_x = (short)(4*u->pxl_width);		/* In quarterdots! */
	if(device == DEV_LJPLUS) {
		if(c <= 32)
			c += 160;
	}

#ifdef DEBUG2
fprintf(stderr,"downloadchar: cd.format = %d\n", cd.format);
fprintf(stderr,"downloadchar: cd.continuation = %d\n", cd.continuation);
fprintf(stderr,"downloadchar: cd.size = %d\n", cd.size);
fprintf(stderr,"downloadchar: cd.class = %d\n", cd.class);
fprintf(stderr,"downloadchar: cd.orientation = %d\n", cd.orientation);
fprintf(stderr,"downloadchar: cd.reserved = %d\n", cd.reserved);
fprintf(stderr,"downloadchar: cd.left_offset = %d\n", cd.left_offset);
fprintf(stderr,"downloadchar: cd.top_offset = %d\n", cd.top_offset);
fprintf(stderr,"downloadchar: cd.char_width = %d\n", cd.char_width);
fprintf(stderr,"downloadchar: cd.char_height = %d\n", cd.char_height);
fprintf(stderr,"downloadchar: cd.delta_x = %d\n", cd.delta_x);
#endif /* DEBUG2 */

	/* Send character ID escape sequence to printer */
	fprintf(bitfile, PCL4_CHAR_ID, c, length + (int)cd.size + 2);

	/*
	* Download each char descriptor value individually to avoid 
	* possible struct alignment problems.
	*/ 
	fwrite((void *)&cd.format, sizeof(cd.format), 1, bitfile);
	fwrite((void *)&cd.continuation, sizeof(cd.continuation), 1, bitfile);
	fwrite((void *)&cd.size, sizeof(cd.size), 1, bitfile);
	fwrite((void *)&cd.class, sizeof(cd.class), 1, bitfile);
	fwrite((void *)&cd.orientation, sizeof(cd.orientation), 1, bitfile);
	fwrite((void *)&cd.reserved, sizeof(cd.reserved), 1, bitfile);
	fwrite((void *)&cd.left_offset, sizeof(cd.left_offset), 1, bitfile);
	fwrite((void *)&cd.top_offset, sizeof(cd.top_offset), 1, bitfile);
	fwrite((void *)&cd.char_width, sizeof(cd.char_width), 1, bitfile);
	fwrite((void *)&cd.char_height, sizeof(cd.char_height), 1, bitfile);
	fwrite((void *)&cd.delta_x, sizeof(cd.delta_x), 1, bitfile);

	/* Now download pixel pattern for c */
	for(i = 0 ; i < length ; i++)
		putc(*p++, bitfile);

	return(height*((width + 7)/8) + (int)cd.size + 2);
}
