/*************************************************************************
****	Kern des universellen 24-Nadeltreibers													****
****	Sollte von Headerdatei aufgerufen werden												****
*************************************************************************/

#include <portab.h>
#include <mintbind.h>
#include <stdlib.h>
#include <string.h>

#include "treiber.h"


#ifndef STEP_360
#error "Bitte diese Datei nur per #include lesen!"
#endif


UBYTE 	*INIT 			= "\033@\033x\1";
UBYTE 	*GRAFIK_180 = "\033*\047\0";
UBYTE 	*GRAFIK_360 = "\033*\050\0";
UBYTE 	*STEP_180 	= "\033\063";




VOID	block_out( UBYTE *dest, UBYTE *src, WORD ende, LONG offset, WORD hoehe )
{
	WORD		i, j, k;
#if 0
	if(  hoehe != 0  && hoehe < 8)
	{
		/* Nur wenn es wirklich ntig ist die langsame Bitpfriemelei */
		for(	i=0;	i<=ende;	i++  )
		{
			/* Byte-Pfriemeln */
			for(	j=7;	j>=0;  j--	)
			{
				*dest = 0;
				for(	k=0;	k<hoehe;	k++  )
					*dest |= ((src[0+k*offset]>>j)&1)<<(7-k);
			}
			dest++;
			src++;
		}
		return;
	}
#endif
	/* So ist wesentlich schneller */
	for(	i=0;	i<=ende;	i++  )
	{
		/* Byte-Pfriemeln */
		for(	j=7;	j>=0;  j--	)
		{
			*dest = 0;
			*dest |= ((src[0]>>j)&1)<<7;
			*dest |= ((src[offset]>>j)&1)<<6;
			*dest |= ((src[offset*2]>>j)&1)<<5;
			*dest |= ((src[offset*3]>>j)&1)<<4;
			*dest |= ((src[offset*4]>>j)&1)<<3;
			*dest |= ((src[offset*5]>>j)&1)<<2;
			*dest |= ((src[offset*6]>>j)&1)<<1;
			*dest |= (src[offset*7]>>j)&1;
			dest++;
			*dest |= ((src[offset*8]>>j)&1)<<7;
			*dest |= ((src[offset*9]>>j)&1)<<6;
			*dest |= ((src[offset*10]>>j)&1)<<5;
			*dest |= ((src[offset*11]>>j)&1)<<4;
			*dest |= ((src[offset*12]>>j)&1)<<3;
			*dest |= ((src[offset*13]>>j)&1)<<2;
			*dest |= ((src[offset*14]>>j)&1)<<1;
			*dest |= (src[offset*15]>>j)&1;
			dest++;
			*dest |= ((src[offset*16]>>j)&1)<<7;
			*dest |= ((src[offset*17]>>j)&1)<<6;
			*dest |= ((src[offset*18]>>j)&1)<<5;
			*dest |= ((src[offset*19]>>j)&1)<<4;
			*dest |= ((src[offset*20]>>j)&1)<<3;
			*dest |= ((src[offset*21]>>j)&1)<<2;
			*dest |= ((src[offset*22]>>j)&1)<<1;
			*dest |= (src[offset*23]>>j)&1;
			dest++;
		}
		src++;
	}
}
/* 20.1.93 */



/* Zur Zeit wird fast nicht optimiert; Zum einen sollte jetzt fast jeder
 * Drucker arbeiten; Zum anderen habe ich keinen 24-Nadeldrucker zum Testen
 * Bastler sind hier zur Arbeit aufgefordert!
 */
static UBYTE	tmp[8192];

WORD	drucke( UBYTE *p, LONG weite, LONG max_zeile, LONG h_dpi, LONG v_dpi )
{
	UBYTE v_modus, *v_step, *grafik;
	LONG	max_spalte, zeile, lz, links, linker_rand, rechts;
	LONG	h_len, len, i;
	WORD	th;

	th = (WORD)get_tempfile( "n24" );
	if(  th<0  )
		return -1;

	grafik = GRAFIK_360;
	v_step = STEP_360;
	if(  h_dpi<200	)
	{
		grafik = GRAFIK_180;
		h_dpi = 180;
	}
	else
		h_dpi = 360;

	if(  v_dpi<200	)
	{
		v_step = STEP_180;
		v_dpi = 180;
	}
	else
		v_dpi = 360;

		/* Ab hier wird es ernst */
	if(  weite<WEITE*h_dpi/360L  ) /* Fr DINA3 vergrern! */
		max_spalte = (weite+7)/8;
	else
		max_spalte = WEITE*h_dpi/(360*8L);

		/* Diverse Variablen initialisieren */
	zeile = 0;
	weite = (weite+15L)/16L;
	weite *= 2;
	p += weite*OBEN + LINKS;	/* Nicht druckbare Rnder*/
	max_zeile -= OBEN;
	if(  HOEHE>0	&&	max_zeile>HOEHE  )
		max_zeile = HOEHE;
	lz = 0;
	v_modus = v_dpi/180;
	linker_rand = 0;

	Fwrite( th, strlen(INIT), INIT ); /* Reset + LQ-Mode */

	/* Endlich drucken */
	max_zeile--;
	while(	zeile<max_zeile )
	{
		/* Leerzeilen berspringen */
		for(	;  ist_leerzeile( p, max_spalte )  &&  zeile<(max_zeile-1);  lz++, zeile++	)
			p += weite;

		while(	lz>0	)
		{
			Fwrite( th, 2L, v_step );
			if(  lz>255  )
				Fputchar( th, 255, 0 );
			else
				Fputchar( th, lz, 0 );
			Fputchar( th, 10, 0 );
			lz -= 255;
		}
		if(  zeile==max_zeile  )
			break;

			/* Rnder feststellen */
		for(	rechts=max_spalte-1;	ist_next_leer( p+rechts, weite, v_modus*24 )	&&	rechts>linker_rand;  rechts--  )
			;
		rechts++;
		links = 0;
		len = rechts;
		h_len = 5;
		strcpy( tmp, grafik );
		tmp[3] = (UBYTE)(8*(rechts-links) % 256);
		tmp[4] = (UBYTE)(8*(rechts-links) / 256);
		if(  len>0	)
			memset( tmp+h_len, 0, 24*len );

		/* Oder auch weniger bei geringerer Auflsung */
		for(	lz=0;  lz<v_modus;	zeile++  )
		{
			i = (max_zeile - 1 - zeile)/v_modus;
			i = 24-i;
			if(  i<0	)
				i = 0;
			block_out( tmp+h_len, p+links, (WORD)(rechts-links), weite*v_modus, (WORD)i );
			Fwrite( th, h_len+24*(rechts-links), tmp );
			Fputchar( th, 13, 0 );
			p += weite;

			if(  ++lz<v_modus  )
			{
				Fwrite( th, 2L, v_step );
				Fputchar( th, 1, 0 );
				Fputchar( th, 10, 0 );
			}
		}
		lz = 1+23*v_modus;	/* +eine Zeile mehr berspringen */
		p += (weite*lz);
		zeile += lz;
 }

		/* Ende Seite */
	if(  1!=Fputchar( th, 12, 0 )  )
	{
		/* Platz reichte nicht aus */
		Fclose( th );
		return -1;
	}
	return th;
}
/* 17.1.93 */
/* Viele kleine Fehler gefunden und gefixt. 6.5.93 Marcus Haebler */

