在编写了一些打印机驱动程序后,我可以确认,由于打印机的工作方式,文档通常会令人困惑。你提到的这份文件在我看来其实并不坏。
我认为你在光栅模式下打印是正确的,总的来说,这将产生最好的结果。
根据Star文档,我认为您需要发送:
1. x1b*rR Initialize raster mode
2. x1b*rA Enter raster mode
3. x1b*rC Clear raster data
4. x1b*rml
4. bx##x##xAAxAAxAA....<DATA>..........
5. x1bx0Cx00 Raster Form feed(??) - should spit out the data.
6. x1b*rB Clear raster data
正面。在上面的x1b中是ESC的C编码(即字符27 0x1b)。
从我阅读的所有文档中,以下是如何在光栅模式下格式化图像。当处于行模式时,它与垂直&;水平方向被交换。来自热敏打印机程序手册(TSP552、TSP552II、TSP2000)
这相当于下面的字节流。
在第4个命令行上,它实际上是b,后面跟着两个定义大小的字节。该大小被计算为流%256和/256中包含的像素数。所以对于320x1,d 0x40,0x01
因此,将以上内容插入到一个简单的测试程序中,您应该使用以下方法进行测试:
char rasterImage [] = {
0x1b, * , r , R , // Initialize raster mode
0x1b, * , r , A , // Enter raster mode
0x1b, * , r , C , // Clear raster data
// n1 n2 d1 d2..
0x1b, b , 0x2, 0, 0x00, 0x00, // data
0x1b, b , 0x2, 0, 0x1F, 0xF8,
0x1b, b , 0x2, 0, 0x3F, 0xFC,
0x1b, b , 0x2, 0, 0x77, 0xEE,
0x1b, b , 0x2, 0, 0xF8, 0x1F,
0x1b, b , 0x2, 0, 0xF8, 0x1F,
0x1b, b , 0x2, 0, 0xF8, 0x1F,
0x1b, b , 0x2, 0, 0x0F, 0xF0,
0x1b, b , 0x2, 0, 0x1F, 0xF8,
0x1b, b , 0x2, 0, 0x1F, 0xF8,
0x1b, b , 0x2, 0, 0x3E, 0x7C,
0x1b, b , 0x2, 0, 0x38, 0x1C,
0x1b, b , 0x2, 0, 0x79, 0x9E,
0x1b, b , 0x2, 0, 0x73, 0xCE,
0x1b, b , 0x2, 0, 0x73, 0xCE,
0x1b, b , 0x2, 0, 0xF9, 0x9F,
0x1b, b , 0x2, 0, 0xF8, 0x1F,
0x1b, b , 0x2, 0, 0xFE, 0x7F,
0x1b, b , 0x2, 0, 0xFF, 0xFF,
0x1b, b , 0x2, 0, 0xFF, 0xFF,
0x1b, b , 0x2, 0, 0x00, 0x00,
0x1b, b , 0x2, 0, 0x00, 0x00,
0x1b, b , 0x2, 0, 0x00, 0x00,
0x1b, b , 0x2, 0, 0x00, 0x00};
[self.currentDataBeingSent appendBytes:rasterImage length:sizeof(rasterImage)];
只要把它喷到打印机上,你就可以得到上面的照片。在这里,您可以轻松地调整和使用确切的命令来获得工作效果。通常,这是我唯一能弄清楚应该做什么的方法。
rev.3
参考注释。
如果每个像素有一个字节,则需要将这些字节合并为一系列位;以下内容应该根据您的pastebin代码完成工作。我还将char*
更改为无符号,因为它是有符号的,在比特操作时可能会导致问题。
NSUInteger bitmapBytePerRow = width/8;
NSUInteger bytesPerRow = 3 + bitmapBytePerRow;
[self.currentDataBeingSent = [NSMutableData dataWithLength:bytesPerRow * height];
[self.currentDataBeingSent appendBytes:initializeRaster length:sizeof(initializeRaster)];
[self.currentDataBeingSent appendBytes:enterRaster length:sizeof(enterRaster)];
NSUInteger byteOffset = 0;
for (NSUInteger y = 0; y < height; y++)
{
unsigned char *rasterCommandForRow = (unsigned char *)calloc(bytesPerRow, sizeof(char));
unsigned char *current_raster = rasterCommandForRow;
*current_raster++ = x6B ;
*current_raster++ = (width*height) % 256;
*current_raster++ = (width*height) / 256;
unsigned char mask = x80 ;
unsigned char out = 0 ;
for (NSUInteger x = 0; x < width; x++)
{
if (*(data + (byteOffset * sizeof(char))))
out |= mask ;
byteOffset++;
mask >>= 1 ;
if( 0 == mask )
{
mask = x80 ;
*current_raster++ = out ;
if( out )
lastDot = nextOut ;
out = 0 ;
}
}
// handle partially finished byte .
if( ( x80 != mask ) && ( 0 != out ) )
*current_raster++ = out ;
[self.currentDataBeingSent appendBytes:rasterCommandForRow length:bytesPerRow];
}
rev.3a
查看mac CUPS支持来自Star,它获得了驱动程序的源代码,其中包含了许多关于如何做到这一点的线索。有时代码比文档更容易阅读。
星杯sdrv-3.3.1.1_mac_20100423.zipstarcupsdv-3.3.1.1_macSourceCode
包含starcupsdrv-src 3.1.1.tar.gz
子文件夹star cupsdrvsrc
查看rastertostar.c,重要的一点是计算n1/n2值。这些根本不是X&;Y,但基于像素计数,lastBlackPixel是源的像素计数。
putchar( b );
putchar((char) ((lastBlackPixel > 0)?(lastBlackPixel % 256):1));
putchar((char) (lastBlackPixel / 256));
我已经修改了上面的代码以包括修复,希望能更接近。如果没有对打印机输出的内容进行扫描,诊断发生的情况将非常有用。
供参考580:650之间的代码来自jsStarUSB.cpp似乎符合生成缓冲区(存储在nextOut
中)所需的内容,该缓冲区包含要直接发送到打印机的格式的光栅数据。
rev. 4 (2023)
Joshua May在评论中建议,rasterImage不需要每行都有ESC(0x1b),只需要b,只需删除0x1b就“对我有用”。