/* Framebuffer Graphics Libary for Linux, Copyright 1993 Harm Hanemaayer */
/* text.c	Text writing and fonts */


#include <stdlib.h>
#include <vga.h>
#include "inlstring.h"		/* include inline string operations */

#include "vgagl.h"
#include "def.h"



/* Text/font functions */

static int initialized = 0;
static int font_width = 8;
static int font_height = 8;
static char *font_address;
static int font_charactersize = 64;
static int font_writemode = WRITEMODE_OVERWRITE;


void gl_colorfont( int fw, int fh, int fg, void *_dp ) {
	uchar *dp = _dp;
	int i;
	i = fw * fh * 256;
	switch (BYTESPERPIXEL) {
	case 1 :
		while (i > 0) {
			if (*dp)
				*dp = fg;
			dp++;
			i--;
		}
		break;
	case 2 :
		while (i > 0) {
			if (*(ushort *)dp)
				*(ushort *)dp = fg;
			dp += 2;
			i--;
		}
		break;
	case 3 :
		while (i > 0) {
			if (*(ushort *)dp || *(dp + 2)) {
				*(ushort *)dp = fg;
				*(dp + 2) = fg >> 16;
			}
			dp += 3;
			i--;
		}
		break;
	case 4 :
		while (i > 0) {
			if (*(int *)dp)
				*(int *)dp = fg;
			dp += 4;
			i--;
		}
		break;
		
	}
}

void gl_setfont( int fw, int fh, void *font ) {
	int i;
	font_width = fw;
	font_height = fh;
	font_charactersize = font_width * font_height * BYTESPERPIXEL;
	font_address = font;
}

void gl_setwritemode( int m ) {
	font_writemode = m;
} 

void gl_write( int x, int y, char *s ) {
/* clipping in putbox */
	int i = 0;
	if (font_writemode == WRITEMODE_OVERWRITE) {
		while (s[i] != 0) {
			gl_putbox(x + i * font_width, y, font_width,
				font_height, font_address +
				(unsigned char)s[i] * font_charactersize);
			i++;
		}
	}
	else {	/* masked write */
		while (s[i] != 0) {
			gl_putboxmask(x + i * font_width, y, font_width, 
				font_height, font_address + 
				(unsigned char)s[i] * font_charactersize);
			i++;
		}
	}
}

void gl_writen( int x, int y, int n, char *s ) {
	char *str = alloca(n + 1);
	memcpy(str, s, n);
	str[n] = 0;
	gl_write(x, y, str);
}

void gl_expandfont( int fw, int fh, int fg, void *_f1, void *_f2 ) {
/* Convert bit-per-pixel font to byte(s)-per-pixel font */
	uchar *f1 = _f1;
	uchar *f2 = _f2;
	int i, x, y, b;
	for (i = 0; i < 256; i++) {
		for (y = 0; y < fh; y++)
			for (x = 0; x < fw; x++) {
				if (x % 8 == 0)
					b = *f1++;
				if (b & (128 >> (x % 8)))	/* pixel */
					switch (BYTESPERPIXEL) {
					case 1 :
						*f2 = fg;
						f2++;
						break;
					case 2 :
						*(ushort *)f2 = fg;
						f2 += 2;
						break;
					case 3 :
						*(ushort *)f2 = fg;
						*(f2 + 2) = fg >> 16;
						f2 += 3;
						break;
					case 4 :
						*(uint *)f2 = fg;
						f2 += 4;
					}
				else	/* no pixel */
					switch (BYTESPERPIXEL) {
					case 1 :
						*f2 = 0;
						f2++;
						break;
					case 2 :
						*(ushort *)f2 = 0;
						f2 += 2;
						break;
					case 3 :
						*(ushort *)f2 = 0;
						*(f2 + 2) = 0;
						f2 += 3;
						break;
					case 4 :
						*(uint *)f2 = 0;
						f2 += 4;
					}
			}
	}
} 
