PRINTING IN COLOR

  The HP deskjet line of printer are great. They are relativly inexpensive
  and all the new models will print in color. When I wanted to write
  a program that would dump the 16 color VGA screen to my printer, I ran
  into a problem. I could not find any source code that showed how to print
  in color. So I had to figure it out for myself. I wasted alot of ink and
  paper, but I figured it out. Now to save you the frustration here's how
  to do it.
  First of all let's explore how to print a simple black and white image
  to the deskjet. Well first you send some codes that setup the printer,
  to let it know that we are going to send it some graphic information.
  Here are the codes to send:

  Write(Lst, #27'E');     { Reset }
  Write(Lst, #27'*t300R');{ Set Raster Resolution can be 300,150,75 }
  Write(Lst, #27'&l0E');  { Set Top Margin 0 Lines }
  Write(Lst, #27'*b0M');  { Raster Graphics Mode 0 (uncompressed) }

  Now the printer is ready to accept graphics information. For each line
  of pixels you want to print you must send these codes:

  NumBytes:=300;     { Number of graphic bytes that I'm going to send }
  Write(Lst, #27'*b',NumBytes,'W'; { Inform printer to expect graphics line }
  For I:=1 to 300 Do Write(Lst, #255); { Send a black line }

  Note that this example will print a solid black line the width of the paper.
  Of course you would change the #255 to whatever graphic data you want to
  print. Now these last three steps must be used for every single line. Here
  is a complete program that will print 5 black lines then eject the page:

----------------------  SNIP HERE  ------------------------
Program BlackLin;
Uses Printer;
Var
  I, J: Integer;
Begin
  Write(Lst, #27'E');     { Reset }
  Write(Lst, #27'*t300R');{ Set Raster Resolution can be 300,150,75 }
  Write(Lst, #27'&l0E');  { Set Top Margin 0 Lines }
  Write(Lst, #27'*b0M');  { Raster Graphics Mode 0 (uncompressed) }
  For I:=1 to 5 Do
  Begin
    Write(Lst, #27'*b300W'); { Sending 300 bytes of graphic info }
    For J:=1 to 300 Do Write(Lst, #255);
  End;
  Write(Lst, #12); { #12 is a formfeed, makes printer eject page }
End.
----------------------  SNIP HERE  ------------------------

SOLID BLACK LINES SUCK

  Now remember that a byte contains 8 bits, and bits are what the printer
  prints. So for every byte of graphic information that we send the printer
  is going to print 8 dots. If a bit is on the a black dot will be printed,
  if a bit is off then the dot is not printed (white). So in the examples
  we are sending #255 as the graphic information. The value 255 happens to
  have all the bits set on. This causes the black line to be printed. Now
  I don't know why anyone would want to print anything besides black lines
  but if you must send other patterns here is the binary representation:
  128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 || 128 | 64 | 32 | 16 | 8| 4 | 2 | 1

  The first 8 numbers are the values in the first byte and the second 8
  are the values in the second byte (of couse this extends for each
  additional byte sent to the printer). So lets say we want to print a
  little box that is 16 pixels high and 16 pixels wide. Here is what we
  would send:
  1st line:           #255,#255
  2nd..15th line:     #128,#1
  16th line:          #255,#255
  This would print a solid line for the top and bottom and two vertical lines
  for the sides.

ON TO COLOR !

  Ok enough with this black and white stuff, I paid good money for a color
  printer and by God I want to print in color. Well the printer is capable
  of printing 7 colors plus white. The colors are:

  White    - No color at all
  Cyan     - Pure color (cartridge has cyan ink)
  Magenta  - Pure color (cartridge has magenta ink)
  Yellow   - Pure color (cartridge has yellow ink)
  Blue     - Combination of Cyan and Magenta
  Green    - Combination of Cyan and Yellow
  Red      - Combination of Magenta and Yellow
  Black    - Combination of Cyan, Magenta, and Yellow (dark brown really)

  Cyan-Bit      Magenta-Bit    Yellow-Bit    Printed Color
  --------      -----------    ----------    --------------
     0               0             0         White (none)
     0               0             1         Yellow
     0               1             0         Magenta
     0               1             1         Red
     1               0             0         Cyan
     1               0             1         Green
     1               1             0         Blue
     1               1             1         Composite Black

  Note that if your printer holds two cartridges then you can also print
  in true black (black ink).

  In order to print in color you must first inform the printer that you will
  be printing in color and how you will send the color information. There are
  three ways to send color information:

  CMY  - Send cyan information, then magenta, then yellow
  CMYK - Send cyan information, then magenta, then yellow, then true black
  RGB  - Send red information, then green, then blue

  Note for RGB mode. The printer uses cyan, magenta and yellow ink. In RGB
  mode the printer translates the RGB values into CMY values. Also note that
  in RGB mode if R=0 and G=0 and B=0 the color printed is black.

  Note that the printer does not print in RGB it just processes the data
  for you to break it into cyan, magenta and yellow. * see note
  You send the color information exactly like the black information that we
  send earlier. Only you have to send 3 different lines to get one line on
  the printer. Here is an example that prints a cyan box:

----------------------  SNIP HERE  ------------------------
Program CyanBox;

Uses Printer;

Var
  I: Integer;
Begin
  Write(Lst, #27'E'); { Reset }
  Write(Lst, #27'*t75R'); { Set resolution to 75 DPI }
  Write(Lst, #27'&l0E'); { Set top margin to 0 lines }
  Write(Lst, #27'*b0M'); { Send graphics in mode 0 no compression }
  Write(Lst, #27'*r-3U');{ Sending color graphics in CMY mode }
                         { Use #27'*r-4U for CMYK }
                         { Use #27'*r3U for RGB }
  Write(Lst, #27'*b2V'); { Sending 2 bytes (note V not W at end) }
  Write(Lst, #255,#255); { Send first line cyan graphic info }
  Write(Lst, #27'*b2V'); { Sending 2 bytes (note V not W at end) }
  Write(Lst, #0#0);      { Send first line magenta info }
  Write(Lst, #27'*b2W'); { Sending 2 bytes (note W for last line) }
                         { If we were using CMYK mode then the setup for
                           yellow would also have V and the K (black) line
                           would have the W. In other words the last color
                           has the W. All others should have V }
  Write(Lst, #0#0);      { Send first line yellow info }

  For I:=2 to 15 Do
  Begin
    Write(Lst, #27'*b2V'); { Sending 2 bytes (note V not W at end) }
    Write(Lst, #128,#1);   { Send first line cyan graphic info }
    Write(Lst, #27'*b2V'); { Sending 2 bytes (note V not W at end) }
    Write(Lst, #0#0);      { Send first line magenta info }
    Write(Lst, #27'*b2W'); { Sending 2 bytes (note W for last line) }
    Write(Lst, #0#0);      { Send first line yellow info }
  End;

  Write(Lst, #27'*b2V'); { Sending 2 bytes (note V not W at end) }
  Write(Lst, #255,#255); { Send first line cyan graphic info }
  Write(Lst, #27'*b2V'); { Sending 2 bytes (note V not W at end) }
  Write(Lst, #0#0);      { Send first line magenta info }
  Write(Lst, #27'*b2W'); { Sending 2 bytes (note W for last line) }
  Write(Lst, #0#0);      { Send first line yellow info }

  Write(Lst, #12);       { Send formfeed to eject page }
End.
----------------------  SNIP HERE  ------------------------

  Now for something more complex, printing the VGA screen. First off we have
  a problem. The VGA screen has 16 colors and we only have 8. The problem is
  that the VGA screen has the same 8 colors only with 2 different intensities.
  For example Red and LightRed, Blue and LightBlue. So for now we are just
  going to ignore the intensity. The only real problem is brown, which is
  low intensity yellow (Oh, well). First order of business, how do we map
  the screen colors to the printer colors. Well lets look at the screen
  colors and printer colors in binary.

  Screen Color - Value - Binary         Printer Color - CMY - Value
  -----------------------------         ---------------------------
  Black   -  0 - 000                     Black   - 111 - 7
  Blue    -  1 - 001                     Blue    - 110 - 6
  Green   -  2 - 010                     Green   - 101 - 5
  Cyan    -  3 - 011                     Cyan    - 100 - 4
  Red     -  4 - 100                     Red     - 011 - 3
  Magenta -  5 - 101                     Magenta - 010 - 2
  Yellow  -  6 - 110                     Yellow  - 001 - 1
  White   -  7 - 111                     White   - 000 - 0

  Do you see how the screen color values can be converted to the printer
  color values. Right just reverse the 1's and 0's. The reason you must do
  this is because screen colors are additive and ink colors are subtractive.
  In other words when the screen has no color it is black, but if the paper
  has no color it is white.

  Now all we have to do is write some code to scan the VGA screen pixel by
  pixel and convert the colors to printer colors, then print them out.
  This is kind of more difficult than it seems because of the way the
  printer values are sent to the printer. Follow this code carefully because
  there are alot of binary operations to move the color bits around.

----------------------  SNIP HERE  ------------------------
Program PrtVGA;

Uses Printer, Graph;

Procedure Print_VGA_Screen;
Var
  X, Y, I: Integer; { Screen Coords }
  Screen_Value: Byte; { Holds value of current screen pixel }
  Printer_Value: Byte; { Holds value of current printer pixel }
  { These hold the actual bytes that get sent to the printer }
  Cyan_Line, Magenta_Line, Yellow_Line: Array[0..79] of Byte;
Begin
  { Init printer }
  Write(Lst, #27'E'); { Reset }
  Write(Lst, #27'*t150R'); { Set resolution to 150 DPI }
  Write(Lst, #27'&l0E'); { Set top margin to 0 lines }
  Write(Lst, #27'*b0M'); { Send graphics in mode 0 no compression }
  Write(Lst, #27'*r-3U');{ Sending color graphics in CMY mode }
  For Y:=0 to 479 Do
  Begin
    { Zero printer color arrays for each horizontal line }
    FillChar(Cyan_Line, SizeOf(Cyan_Line), 0);
    FillChar(Magenta_Line, SizeOf(Magenta_Line), 0);
    FillChar(Yellow_Line, SizeOf(Yellow_Line), 0);
    For X:=0 to 639 Do
    Begin
      Screen_Value:=GetPixel(X, Y);
      Screen_Value:=Screen_Value AND 7; { Ignore intensity }
      Printer_Value:=7 - Screen_Value; { Printer color is bit reversed }
      { Now comes the complicated part: If a bit is on in Printer_Value
        then we want to turn on the bit in the appropriate printer color
        array. }
      If (Printer_Value AND 1) = 1 Then
       Yellow_Line[X Div 8]:=Yellow_Line[X Div 8] OR (128 SHR (X Mod 8));
      If (Printer_Value AND 2) = 2 Then
       Magenta_Line[X Div 8]:=Magenta_Line[X Div 8] OR (128 SHR (X Mod 8));
      If (Printer_Value AND 4) = 4 Then
       Cyan_Line[X Div 8]:=Cyan_Line[X Div 8] OR (128 SHR (X Mod 8));
    End;
    { Ok now print the line }
    Write(Lst, #27'*b80V'); { Sending 80 bytes }
    For I:=0 to 79 Do Write(Lst, Char(Cyan_Line[I]));
    Write(Lst, #27'*b80V'); { Sending 80 bytes }
    For I:=0 to 79 Do Write(Lst, Char(Magenta_Line[I]));
    Write(Lst, #27'*b80W'); { Sending 80 bytes }
    For I:=0 to 79 Do Write(Lst, Char(Yellow_Line[I]));
  End;
  Write(Lst, #12); { FormFeed, ejects page from printer }
End;

{ Start of main-line code }

Var
  GrDriver, GrMode: Integer;
  I: Integer;
Begin
  GrDriver:=VGA;
  GrMode:=VGAHi;
  InitGraph(GrDriver, GrMode, 'C:\TP\BGI');
  SetFillStyle(SolidFill, White);
  Bar(0, 0, 639, 479);
  For I:=0 to 150 Do
  Begin
    SetColor(I Mod 8);
    Circle(319, 239, I * 2);
  End;

  Print_VGA_Screen;

  CloseGraph;
End.
----------------------  SNIP HERE  ------------------------

  I bet you thought it was going to be alot harder that this didn't you.
  Well what can I say about the awsome power of Turbo Pasal.

  I'm working on developing this topic further by showing you how to read
  and display BMP files. Then eventually how to print them in color.

  Bean, thitt@igateway.com

*)



    Source: geocities.com/SiliconValley/2926/tpsrc

               ( geocities.com/SiliconValley/2926)                   ( geocities.com/SiliconValley)