#include #include #include #include "portab.h" #include "treiber.h" /***************************/ /* Version 1.0 von 10.2.93 */ /* Markus Pristovsek */ /* Nur 240*216 dpi */ /***************************/ /* Version 1.1 von 1.3.93 */ /* Alle Aufl”sungen, d.h. */ /* hor.: 240,120,90,80,72 */ /* ver.: 216,144,72 dpi */ /***************************/ /* Version 1.2 von 23.8.93 */ /* Drehen per Assembler */ /***************************/ /* Version 1.3 von 7.10.95 */ /* Quer- und Hochkant in */ /* einem Treibermodul */ /***************************/ #define BITS_PER_CHAR 20 /* Elite-Dichte! */ #define COMPRESSION 2 /* Von 2 bis 0 (so lassen) */ #define MAX_DPI 240L #define WEITE 1920 /* Fr DINA3 vergr”žern! */ #define HOEHE -1 /* Unbeschr„nkt */ static UBYTE dpi_modus[]={ 240, 3, 120, 1, 90, 6, 72, 5 }; static UBYTE dpi_vmodus[]={ 216, 3, 144, 2, 72, 1 }; static UBYTE *INIT="\33@\33M\33\63\1\15"; static UBYTE *V_STEP="\0\33J\0"; LONG max_puffer_laenge = 1; /* Nur Semaphore bekommen (=<128)! */ /********************************************************************/ /* Komprimiert eine Zeile */ void write_compressed( WORD th, UBYTE *tmp, LONG len, long bpc ) { LONG i, j; if( len>0 ) { #if COMPRESSION==2 /* Schneidet nur links und rechts ab */ /* Diese Routine sollte mit nahezu jedem Drucker gehen! */ /* wenn man BITS_PER_CHAR (bpc) kennt! */ for( i=0; ii ) len--; if( i0 && tmp[i+5]==0; i-- ) ; len--; if( i>0 ) { len = i; tmp[3] = (UBYTE)(len % 256); tmp[4] = (UBYTE)(len / 256); Fwrite( th, 5L+len, tmp ); } #else /* Und unkomprimiert! */ Fwrite( th, 5L+len, tmp ); #endif } Fwrite( th, 2L, "\015\012" ); } /********************************************************************/ /* Erst Quer (Landscape) */ /* Zwischenspeicher fr eine Zeile */ static UBYTE tmp1[WEITE+6L]; static UBYTE tmp2[WEITE+6L]; static UBYTE tmp3[WEITE+6L]; static LONG bit_table[]= { 0x00800000L,0x00400000L,0x00200000L,0x00100000L, 0x00080000L,0x00040000L,0x00020000L,0x00010000L, 0x00008000L,0x00004000L,0x00002000L,0x00001000L, 0x00000800L,0x00000400L,0x00000200L,0x00000100L, 0x00000080L,0x00000040L,0x00000020L,0x00000010L, 0x00000008L,0x00000004L,0x00000002L,0x00000001L }; /* Querdruck in 216, 144, 72 Dpi */ WORD drucke_quer( UBYTE *p, LONG start_x, LONG weite, LONG hoehe, LONG h_dpi, LONG v_dpi, WORD th, WORD flag ) { LONG max_spalte, max_zeile, zeile, lz; LONG len, bytes_per_row, offset, i, j, k; UBYTE t; for( i=6; i>0 && v_dpi>dpi_modus[i]*11/10; i-=2 ) ; t = dpi_modus[i+1]; v_dpi = dpi_modus[i]; for( i=6; i>0 && h_dpi>dpi_vmodus[i]*11/10; i-=2 ) ; h_dpi = dpi_vmodus[i]; bytes_per_row = dpi_vmodus[i+1]; /* Ab hier wird es ernst */ if( hoehe>(WEITE*h_dpi)/MAX_DPI ) max_spalte = (WEITE*h_dpi)/MAX_DPI; else max_spalte = (hoehe*h_dpi)/MAX_DPI; /* Diverse Variablen initialisieren */ zeile = 0; max_zeile = weite-start_x; if( HOEHE>0 && (max_zeile*v_dpi)/MAX_DPI>HOEHE ) max_zeile = ((HOEHE-start_x)*v_dpi)/MAX_DPI; weite = (weite+15L)/16L; weite *= 2; /* Reset + LQ-Mode */ if( flag&1 ) Fwrite( th, 8L, INIT ); /* Endlich drucken */ max_zeile--; while( max_zeile>0 && flag&2 ) { for( lz=0; ist_next_leer( p+lz, weite, hoehe ) && lz*80 ) { /* Leerzeilen berspringen */ zeile += lz*8; p += lz; if( zeile>max_zeile ) lz = max_zeile-(zeile-lz*8); lz = lz*8*3/bytes_per_row; while( lz>0 ) { if( lz>255 ) V_STEP[3] = 255; else V_STEP[3] = lz; Fwrite( th, 4L, V_STEP ); lz -= 255; } } if( zeile>=max_zeile ) break; len = max_spalte; if( max_spalte<(WEITE*h_dpi)/MAX_DPI ) offset = (WEITE*h_dpi)/MAX_DPI-max_spalte; else offset = 0; tmp1[0] = '\033'; tmp1[1] = '*'; tmp1[2] = t; switch( (int)bytes_per_row ) { case 1: for( lz=0; lz0 ) return drucke_quer( p, start_y, weite, hoehe, h_dpi, v_dpi, th, flag ); /* Aufl”sung feststellen */ for( i=4; i>0 && h_dpi>dpi_modus[i]; i-=2 ) ; modus = dpi_modus[i+1]; h_dpi = dpi_modus[i]; for( i=6; i>0 && v_dpi>dpi_vmodus[i]*11/10; i-=2 ) ; v_dpi = dpi_vmodus[i]; v_modus = dpi_vmodus[i+1]; /* Ab hier wird es ernst */ if( weite0 ) { if( lz>255 ) V_STEP[3] = 255; else V_STEP[3] = lz; Fwrite( th, 4L, V_STEP ); lz -= 255; } if( zeile>=hoehe ) break; /* R„nder feststellen */ for( rechts=max_spalte-1; ist_next_leer( p+rechts, weite, v_modus*8 ) && rechts>linker_rand; rechts-- ) ; rechts++; /* Leerzeichen am linken Rand */ for( links=linker_rand; ist_next_leer( p+links, weite, v_modus*8 ) && links0 ) memset( tmp1+5, 0, h_len ); tmp1[3] = (UBYTE)(len % 256); tmp1[4] = (UBYTE)(len / 256); /* 24 Zeilen (3x Druckkopfh”he an den Drucker! */ /* Oder auch weniger bei geringerer Aufl”sung */ for( lz=0; lz=hoehe ) { int bit, byte, and_it; bit = (int)((zeile+v_modus*8+lz - hoehe)/v_modus); and_it = (0x00FF<<(bit&7)); for( byte=0; byte=hoehe ) links = hoehe-zeile-v_modus; zeile += (8*v_modus); } /* Ende Seite */ if( (flag&4) ) { if( 2!=Fwrite( th, 2L, " \014" ) ) /* Platz reichte nicht aus */ return -1; } return 0; } /* 17.1.93 */