home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK4 / SAMPLES / IOSTUTOR / HSTREAM.CP$ / HSTREAM
Encoding:
Text File  |  1992-02-18  |  5.1 KB  |  178 lines

  1. // hstream.cpp  - HP LaserJet output stream
  2. #include "hstream.h"
  3.  
  4. #define REG 0x01   // Regular font code
  5. #define UND 0x02   // Underline font code
  6. #define CR 0x0d    // Carriage return character
  7. #define NL 0x0a    // Newline character
  8. #define FF 0x0c    // Formfeed character
  9. #define TAB 0x09   // Tab character
  10.  
  11. #define LPP 57     // Lines per Page
  12. #define TABW 5     // Tab width
  13.  
  14. // Prolog defines printer initialization (font, orientation, etc.
  15. char prolog[] =
  16. { 0x1B, 0x45,                                // Reset printer
  17.   0x1B, 0x28, 0x31, 0x30, 0x55,            // IBM PC char set
  18.   0x1B, 0x26, 0x6C, 0x31, 0x4F,            // Landscape
  19.   0x1B, 0x26, 0x6C, 0x38, 0x44,              // 8 lines-per-inch
  20.   0x1B, 0x26, 0x6B, 0x32, 0x53};              // Lineprinter font
  21.  
  22. // Epilog prints the final page and terminates the output
  23. char epilog[] = { 0x0C, 0x1B, 0x45 };   // Formfeed, reset
  24.  
  25. char uon[] = { 0x1B, 0x26, 0x64, 0x44, 0 }; // Underline on
  26. char uoff[] = { 0x1B, 0x26, 0x64, 0x40, 0 };//  Underline off
  27.  
  28. hstreambuf::hstreambuf( int filed ) : filebuf( filed )
  29. {
  30.      column = line = page = 0;
  31.      int size = sizeof( prolog );
  32.      setp( prolog, prolog + size );
  33.      pbump( size );   // Puts the prolog in the put area
  34.      filebuf::sync(); // Sends the prolog to the output file
  35.      buffer = new char[1024]; // Allocates destination buffer
  36. }
  37.  
  38. hstreambuf::~hstreambuf()
  39. {
  40.      sync(); // Makes sure the current buffer is empty
  41.      delete buffer; // Free the memory
  42.      int size = sizeof( epilog );
  43.      setp( epilog, epilog + size );
  44.      pbump( size );   // Puts the epilog in the put area
  45.      filebuf::sync(); // Sends the epilog to the output file
  46. }
  47.  
  48. int hstreambuf::sync()
  49. {
  50.      long count = out_waiting();
  51.     if ( count ) {
  52.         convert( count );
  53.     }
  54.     return filebuf::sync();
  55. }
  56.  
  57. int hstreambuf::overflow( int ch )
  58. {
  59.      long count = out_waiting();
  60.     if ( count ) {
  61.         convert( count );
  62.     }
  63.     return filebuf::overflow( ch );
  64. }
  65. //*** The following code is specific to the HP LaserJet printer ***
  66.  
  67. // Converts a buffer to HP, then writes it
  68. void hstreambuf::convert( long cnt )
  69. {
  70.     char *bufs, *bufd; // Source, destination pointers
  71.     int j = 0;
  72.  
  73.     bufs = pbase();
  74.     bufd = buffer;
  75.     if( page == 0 ) {
  76.         newline( bufd, j );
  77.     }
  78.     for( int i = 0; i < cnt; i++ ) {
  79.         char c = *( bufs++ );  // Gets character from source buffer
  80.         if( c >= ' ' ) {     // Character is printable
  81.             * ( bufd++ ) = c;
  82.             j++;
  83.             column++;
  84.         }
  85.  
  86.         else if( c == NL ) { // Moves down one line
  87.             *( bufd++ ) = c;   // Passes character through
  88.             j++;
  89.             line++;
  90.             newline( bufd, j ); // Checks for page break, etc.
  91.         }
  92.         else if( c == FF ) {    // Ejects paper on formfeed
  93.             line = line - line % LPP + LPP;
  94.             newline( bufd, j ); // Checks for page break, etc.
  95.         }
  96.         else if( c == TAB ) {   // Expands tabs
  97.             do {
  98.                 *( bufd++ ) = ' ';
  99.                 j++;
  100.                 column++;
  101.             } while ( column % TABW );
  102.         }
  103.         else if( c == UND ) { // Responds to 'und' manipulator
  104.             pstring( uon, bufd, j );
  105.         }
  106.         else if( c == REG ) { // Responds to 'reg' manipulator
  107.             pstring( uoff, bufd, j );  //
  108.         }
  109.     }
  110.     setp( buffer, buffer + 1024 ); // Sets new put area
  111.     pbump( j ); // Indicates the number of characters in the dest buffer
  112. }
  113.  
  114. // simple manipulators - apply to all ostream classes
  115. ostream& und( ostream& os ) // Turns on underscore mode
  116. {
  117.     os << (char) UND; return os;
  118. }
  119.  
  120. ostream& reg( ostream& os ) // Turns off underscore mode
  121. {
  122.     os << (char) REG; return os;
  123. }
  124.  
  125. void hstreambuf::newline( char*& pd, int& jj )
  126. // Called for each newline character
  127. {
  128.     column = 0;
  129.     if ( ( line % ( LPP*2 ) ) == 0 ) // Even page
  130.         {
  131.         page++;
  132.         pstring( "\033&a+0L", pd, jj );  //  Set left margin to zero
  133.         heading( pd, jj );        /*  print heading  */
  134.         pstring( "\033*p0x77Y", pd, jj ); // Cursor to (0,77) dots  
  135.         }
  136.  
  137.     if ( ( ( line % LPP ) == 0 ) && ( line % ( LPP*2 ) ) != 0 ) 
  138. // Odd page
  139.         { //  prepare to move to right column
  140.         page++;
  141.         pstring( "\033*p0x77Y", pd, jj ); // Cursor to (0,77) dots  
  142.         pstring( "\033&a+88L", pd, jj ); // Left margin to 88th column
  143.         }
  144.     }
  145. void hstreambuf::heading( char*& pd, int& jj ) // Prints page heading
  146. {
  147.         char hdg[20];
  148.         int i;
  149.  
  150.         if( page > 1 ) {
  151.             *( pd++ ) = FF;
  152.             jj++;
  153.         }
  154.         pstring( "\033*p0x0Y", pd, jj ); // Top of page
  155.         pstring( uon, pd, jj ); // Underline on
  156.         sprintf( hdg, "Page %-3d", page );
  157.         pstring( hdg, pd, jj );
  158.         for( i=0; i < 80; i++ ) { // Pads with blanks
  159.             *( pd++ ) = ' ';
  160.             jj++;
  161.         }
  162.         sprintf( hdg, "Page %-3d", page+1 ) ;
  163.         pstring( hdg, pd, jj );
  164.         for( i=0; i < 80; i++ ) { // Pads with blanks
  165.             *( pd++ ) = ' ';
  166.             jj++;
  167.         }
  168.         pstring( uoff, pd, jj ); // Underline off
  169. }
  170. // Outputs a string to the buffer
  171. void hstreambuf::pstring( char* ph, char*& pd, int& jj )
  172. {
  173.     int len = strlen( ph );
  174.     strncpy( pd, ph, len );
  175.     pd += len;
  176.     jj += len;
  177. }
  178.