| Previous | Table of Contents | Next |
Since 13.2 is 0.8 units distant from 14, adding 0.8 of input pixel 13s intensity to 0.2 of input pixel 14s intensity produces the desired output pixel 22. These scaled output pixel values are then reduced to bilevel pixel values using digital halftoning procedures. PRINTPCX.C finally prints the derived digital halftone images on an IBM Proprinter using the following logic:
#define ESC '\x1B'
USGC IbmPpNoAutoLf[] = { ESC, '5', '0' };
USGC IbmPpGraphicsLineSpacing[] = { ESC, '3', 24 };
USGC IbmPpDualDensityGraphics[] = { ESC, 'L', };
USGC IbmPpUniDirectionalPrint[] = { ESC, 'U', '1' };
USGC IbmPpPrintArray[8][120]; /* 120 * 8 == 960 */
int IbmPpPrintBiLevelLine()
{
static NextLineValue = 0, Entered = 0;
if (!Entered)
{
InitializeIbmPp();
Entered = 1;
}
m em cpy(IbmPpPrintArray[NextLineValue], GrayBilevelLine,
MaxPrintPelsPerLine / 8);
NextLineValue = (++NextLineValue % 8);
if (!NextLineValue)
{
USGI OutputByteIndex, RowIndex, TargetByte, Index;
USGC CharValue, MaskValue, TestMask;
for (Index = 0; Index < sizeof(IbmPpDualDensityGraphics); Index++)
PrintByte(IbmPpDualDensityGraphics[Index]);
PrintByte( ActualPrintScanLinePels & 0x00FF);
PrintByte((ActualPrintScanLinePels >> 8) & 0x00FF);
for (OutputByteIndex = 0;
OutputByteIndex < ActualPrintScanLinePels;
OutputByteIndex++)
{
CharValue = 0x00;
MaskValue = 0x80;
TargetByte = OutputByteIndex / 8;
TestMask = (0x80 >> (OutputByteIndex % 8));
for (RowIndex = 0; RowIndex < 8; RowIndex++)
{
if (TestMask &
IbmPpPrintArray[RowIndex][TargetByte])
CharValue |= MaskValue;
MaskValue >>= 1;
}
PrintByte(CharValue);
}
PrintByte('\x0D'); PrintByte('\x0A');
}
return 0;
}
int InitializeIbmPp()
{
USGI Index;
ResetPrinter();
for (Index = 0; Index < sizeof(IbmPpUniDirectionalPrint); Index++)
PrintByte(IbmPpUniDirectionalPrint[Index]);
for (Index = 0; Index < sizeof(IbmPpNoAutoLf); Index++)
PrintByte(IbmPpNoAutoLf[Index]);
for (Index = 0; Index < sizeof(IbmPpGraphicsLineSpacing); Index++)
PrintByte(IbmPpGraphicsLineSpacing[Index]);
return 0;
}
The IbmPpPrintBiLevelLine() receives pixel printing information generated from the derived achromatic image by a digital halftoning routine discussed in Chapter 14. IbmPpPrintBiLevelLine() first checks if it has previously been entered. If not, it invokes the InitializeIbmPP() routine.
InitializeIbmPP() first sends an escape sequence directing the printer to print pels only when moving the head from left to right. This prevents the printer from printing as the print head moves from right to left. Though this wastes time as the print head returns to the left margin to print the next band, it eliminates image distortions that occur when bands print slightly horizontally shiftedcausing vertical lines to wiggle down the page. InitializeIbmPP() next directs the printer not to automatically generate a line feed when it receives a carriage return, providing the program greater control over vertical head movements. Finally InitializeIbmPP() sets the line spacing to 24/216 inch for eight scan-line band printing before returning to IbmPpPrintBiLevelLine().
IbmPpPrintBiLevelLine() moves the received pixel scan line into the first available row in the array IbmPpPrintArray[8][120] (in 120 bytes, there are 960 bits for 960 bilevel pels) and checks if it has now accumulated eight image scan lines. If not, IbmPpPrintBiLevelLine() returns. Otherwise, IbmPpPrintBiLevelLine() prints the eight scan-line band, transmits a carriage return-line feed combination, and returns to the caller. When IbmPpPrintBiLevelLine() executes again, it treats the IbmPpPrintArray array as empty and reuses IbmPpPrintArray starting with row zero to accumulate the next band.
To print a band, IbmPpPrintBiLevelLine() first sends the printer the IbmPpDualDensityGraphics escape sequence followed by the number of image columns it will print. The value of the number of bytes to print is byte-reversed (little-endian byte ordering). Moving from column zero to the last valid image column in IbmPpPrintArray, IbmPpPrintBiLevelLine() repeatedly calls PrintByte() to print eight vertical image pels at a time.
For a print wire to generate a black pel, its corresponding bit value in the character should be a binary one. For a print wire to generate a white pixel (not print), its corresponding bit value should be a binary zero. The top (uppermost) wire in the vertical print wire stack corresponds to the high-order bit position in the character to print and the bottom (lowest) wire corresponds as indicated in Table 8-2.
| Wire Position | Bit Position |
| 8 (Top) | 10000000 (High Order) |
| 7 | 01000000 |
| 6 | 00100000 |
| 5 | 00010000 |
| 4 | 00001000 |
| 3 | 00000100 |
| 2 | 00000010 |
| 1 (Bottom) | 00000001 (Low Order) |
Table 8-2: IBM Proprinter print wire bit positions
| Previous | Table of Contents | Next |