#ifndef Epson_h
#define Epson_h

/* $Header: /usr/local/src/mctex/imagen/epson.h,v 1.1 1993/03/31 03:16:47 neal Exp neal $ */

/* Copyright (c) 1993 Neal Becker
 * All rights reserved.
 * Permission to copy for any purpose is hereby granted
 * so long as this copyright notice remains intact.
*/

/*
$Log: epson.h,v $
 * Revision 1.1  1993/03/31  03:16:47  neal
 * Initial revision
 *
 * Revision 1.1  91/08/05  23:40:19  ROOT_DOS
 * Initial revision
 * 
*/

#include <stdio.h>
#include "Bset.h"

#define MaxImFamily	128	/* hardware limitation on font family index */
#define DefaultDPIh	240	/* 300 for Imagen 8/300, 240 for Imprint-10 */
#define DefaultDPIv	216	/* 300 for Imagen 8/300, 240 for Imprint-10 */
#define DefaultMaxDrift	3	/* default value for MaxDrift */

/* 1 inch left margin */
const int HPixels = 240 * 7.5;
const int VPixels = 216 * 11;
const int HBytes = ( HPixels + 7 ) / 8;
#ifdef TWOPASS
const int BitMapRows = VPixels / 2;
#else
const int BitMapRows = VPixels;
#endif /* TWOPASS */
const int ExtraRows = 0;
const int LeftMarginSpaces = 10; /* 10 extra spaces = 1 inch margin */
const int LeftMarginPixels = 240;

const short MaxShort = 0x7fff;

inline int max( int a, int b ) {
  return ( a > b ) ? a : b;
}

inline int min( int a, int b ) {
  return ( a < b ) ? a : b;
}

struct BitMapRow {
  short Length;			/* last byte pos used */
  short Start;			/* first byte pos used */
  unsigned char Printed;
  char* Bits;
  BitMapRow();
  void Clear();
  void Set( char* S, int Slen, int Pos ) {
    Bset( S, Slen, Bits, HBytes, Pos );
    Length = max( Length, min( HBytes - 1, Pos / 8 + Slen + 1 ) );
    Start = min( Start, Pos / 8 );
  };

  void SetBits( int Slen, int Pos ) {
    ::SetBits( Slen, Bits, HPixels, Pos );
    Length = max( Length, min( HBytes - 1, Pos / 8 + Slen / 8 + 1 ) );
    Start = min( Start, Pos / 8 );
  };

  int NeedToPrint() {
    return !Printed && Start != MaxShort;
  };

  void Mark() {
    Printed = 1;
  };
};

struct BitMap {
  BitMapRow* Rows[ BitMapRows + ExtraRows ];
  BitMap();
  void Clear();
  int NeedToPrint( int Row ) {
    return Rows[ Row ]->NeedToPrint();
  };
  int FindLength( int Row );
  int FindFirst( int Row );
  void Mark( int Row ) {
    Rows[ Row ]->Mark();
  };
  void Set( char* S, int Slen, int Row, int Pos ) {
    Rows[ Row ]->Set( S, Slen, Pos );
  };
  void SetBits( int Slen, int Row, int Pos ) {
    Rows[ Row ]->SetBits( Slen, Pos );
  };
};

static const int BitMask[ 8 ] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80 };
void ReportMem();

class epson {

private:
  FILE* fp;
  int PrintPos;
  int DviPos;
  int HasFastSpace;

  void PrintRow( BitMap& theBitMap, int Row );

  void Output8Rows( BitMap& theBitMap, int Row );

  void Encode8Bytes( BitMap& theBitMap, int Row, int HByte, char Bytes[ 8 ] );

  void SetVpos( int Row );

  void Vaddv( int n );

/* Reset Printer, Select Pica (10 cpi) */
  void Init() {
    fputs( "\x1b" "@" "\x1b" "P", fp );
  }

public:

  epson( FILE* f, int fastspace = 0 ) : fp( f ), DviPos( 0 ), PrintPos( 0 ),
    HasFastSpace( fastspace )
     { Init(); Reset(); }

  void Reset() {
    SetVaddv( 0 );
    PrintPos = 0;
  }

  void Eol() {
      fputc( '\r', fp );
  }

  void EoP() {
    fputc( '\f', fp );
  }

  void SetVaddv( int n ) {
    fputs( "\x1b" "3", fp );
    fputc( n, fp );
  }
  
  void ResVaddv() {
    fputs( "\x1b" "2", fp );
  }

  void PrintBitMap( BitMap& theBitMap );

  void SyncVpos() {
      SetVpos( DviPos );
  }

};

#endif


