Aros/开发者/文档/设备/打印机
AmigaDOS 3.1(AROS 模仿的对象)没有像您在其他操作系统中看到的那样的标准打印对话框,用于选择要打印的文档页数、选择横向模式与纵向模式、纸张尺寸、纸张类型、双面模式、打印预览等。每个程序都必须自行滚动以与打印机首选项接口以进行这些操作。
在 AmigaDOS 1.x-3.1 中,每个应用程序程序都必须对高分辨率、高质量打印进行自己的支持,因为图形显示和打印 API 没有任何分辨率独立性内置在创建和显示绘图命令列表中,然后将该列表转换为结构化的绘图格式或语言输出,包括徽标或字体等。(与 MacOS 或 Windows 不同)。
在 AmigaDOS 1.x-3.1 中,打印由一个原始的 printer.device 组成,它只理解 ANSI 格式的文本和几种类型的图形 rastport 二进制数据,并查询 printer、printergfx 和 printerps 首选项以决定如何处理打印到位图方向打印机、ANSI 序列文本打印机或通过馈送原始数据(由希望打印原始数据的每个单独程序独立生成)。每台打印机都会有一个为其定制的设备文件,用于在文本和图形之间切换模式(从内部 Amiga 图形或文本格式转换为打印机喜欢的格式),并执行诸如走纸、设置边距等操作,printer.device 将(通过打印机首选项)决定将该数据发送到哪个端口,检查打印时的错误等。
目前,AROS 支持将任何文本和图片转换为 Postscript (.ps) 文件,然后可以将这些文件保存为文件或打印到有限范围的打印机。
- 使用现有的 printer.device API
- PRD_RAWWRITE 将未处理的数据发送到打印机
- PRD_DUMPRPORT (IODRPReq->ioCommand) 将 rastport 发送到打印机
- PRD_QUERY (IOStdReq->io_Command) 打印机端口处于什么状态
- PRD_PRTCOMMAND (IOPrtCmdReq->ioCommand) 通过 CMD_WRITE 将 ANSI 转义序列发送到打印机(不支持)
- 将输出写入
- 用户指定的(通过首选项或弹出窗口)文件名
- 到另一个程序的管道(通过首选项或弹出请求器)
- 输出是 PostScript Level 2(或更低版本)
- 选择 A4、Letter 或自定义(以英寸或毫米为单位)的页面大小
状态
- printer.device 的代码完成率约为 99%
- L:port-handler 代码已完成
- C:Print 代码已完成(通过 Datatypes 打印)
- DEVS:Printers/PostScript 的代码完成率约为 95%
特点
+ All 10 printer.device units should be available + Each unit runs in its own DOS Process + Each unit has its own instance of a DEVS:Printer/* driver + The instance only exists while the unit is open. + Print to file, serial, parallel, or USB (the last 3 are untested) + PAR: SER: and PRT: DOS handlers for printing (and general IO) - Of note, see DEVS:DosDrivers/SER0 - it can be adapted for to connect to any streaming device. + Landscape/Portrait works + PostScript Level 2, with %%Page: and EPS compatible comments - makes enscript happier
已知问题
- Only PCC_BGR printers are supported at this time (I'll get CYMK and B&W working in a bit) - Only (due to licensing [1]) PostScript and Skeleton (demo) printers are available. - Centering, color inversion, and a number of other minor features are missing or broken. - No attempt is made to correct the aspect ratio of the printed pictures.
- 几乎所有可以找到的带有源代码的打印机驱动程序都在顶部有一个大大的“版权所有 (c) 19xx Amiga”。希望人们可以使用 PostScript 和 Skeleton 驱动程序来编写具有更好许可证的打印机驱动程序。
/************************************************************** **** Print.h : procedures for printing **** **** Free software under GNU license, started on 2/2/2012 **** **** © AROS Team **** **************************************************************/ #ifndef PRINT_H #define PRINT_H #include "Memory.h" /* Print a file */ BYTE print_file(LINE *svg, unsigned char eol); /* Get/set current printer.device unit * If unit < 0, gets current printer unit * Otherwise, sets unit to the selected unit */ BYTE print_unit(BYTE unit); #endif
/**************************************************************
**** Print.c : procedures for printing ****
**** Free software under GNU license, started on 2/2/2012 ****
**** © AROS Team ****
**************************************************************/
#include <intuition/intuition.h>
#include <libraries/asl.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <proto/exec.h>
#include "Gui.h"
#include "Project.h"
#include "Utility.h"
#include "ProtoTypes.h"
#include "Print.h"
#include "DiskIO.h"
#define CATCOMP_NUMBERS /* Error msg use strings id */
#include "strings.h"
static inline BYTE PWrite(struct IORequest *io, CONST_STRPTR buffer, LONG len)
{
struct IOStdReq *sio = (struct IOStdReq *)io;
sio->io_Command = CMD_WRITE;
sio->io_Data = (APTR)buffer;
sio->io_Length = len;
return (DoIO(io) == 0 && sio->io_Actual == len) ? 1 : 0;
}
/* Print a file
*/
BYTE print_file(LINE *svg, unsigned char eol)
{
STRPTR buf;
LONG i;
BYTE szeol = szEOL[eol];
LINE *ln;
BYTE retval = 0;
struct IORequest *io;
struct MsgPort *mp;
if ((mp = CreateMsgPort())) {
if ((io = CreateIORequest(mp, sizeof(struct IOStdReq)))) {
if (0 == OpenDevice("printer.device", print_unit(-1), io, 0)) {
BusyWindow(Wnd);
for(ln=svg, buf=NULL, i=0; ln; ln=ln->next)
{
if (i == 0)
buf = ln->stream;
/* An unmodified line (2nd cond. is for deleted lines) */
if (ln->max == 0 && ln->stream-buf == i) {
i+=ln->size+szeol;
} else {
/* Flush preceding unmodified buffer */
i -= szeol;
if( i>=0 && (PWrite(io, buf, i) != 1 ||
PWrite(io, &chEOL[eol], szeol) != 1 ) )
{
retval = 0;
break;
}
/* Writes the modified line */
if( PWrite(io, ln->stream, ln->size) != 1 || (ln->next != NULL &&
PWrite(io, &chEOL[eol], szeol) != 1 ) ) {
retval = 0;
break;
}
i=0;
}
}
/* Flush buffer */
if( i>szeol && PWrite(io, buf, i-szeol) !=1 ) {
retval = 0;
}
WakeUp(Wnd);
CloseDevice(io);
}
DeleteIORequest(io);
}
DeleteMsgPort(mp);
}
return retval;
}
/* Get/set current printer.device unit
* If unit < 0, do not change current unit
* Return:
* printer unit to be used for printing
*
*/
BYTE print_unit(BYTE unit)
{
static BYTE current_unit = 0;
if (unit >= 0)
current_unit = unit;
return current_unit;
}
/*
* Copyright (C) 2012, The AROS Development Team. All rights reserved.
* Author: Jason S. McMullan <[email protected]>
*
* Licensed under the AROS PUBLIC LICENSE (APL) Version 1.1
*/
#include <aros/debug.h>
#include <aros/printertag.h>
#include <clib/alib_protos.h>
#include <devices/printer.h>
#include <devices/prtgfx.h>
#include <prefs/printergfx.h>
#include <prefs/printertxt.h>
#include <exec/rawfmt.h>
#include <proto/exec.h>
#include <proto/graphics.h>
/* Support binary compatability with AOS */
#ifdef __mc68000
#undef RAWFMTFUNC_STRING
#define RAWFMTFUNC_STRING (VOID (*)())"\x16\xC0\x4E\x75"
#endif
static LONG sk_Init(struct PrinterData *pd);
static VOID sk_Expunge(VOID);
static LONG sk_Open(union printerIO *ior);
static VOID sk_Close(union printerIO *ior);
static LONG sk_Render(SIPTR ct, LONG x, LONG y, LONG status);
static LONG sk_ConvFunc(UBYTE *buf, UBYTE c, LONG crlf_flag);
static LONG sk_DoPreferences(union printerIO *ior, LONG command);
static VOID sk_CallErrHook(union printerIO *ior, struct Hook *hook);
static LONG sk_DoSpecial(UWORD *command, UBYTE output_buffer[],
BYTE *current_line_position,
BYTE *current_line_spacing,
BYTE *crlf_flag, UBYTE params[]);
static CONST_STRPTR PED_Commands[] = {
"\377", /* 0 aRIS (reset) */
"\377\377", /* 1 aRIN (initialize) */
"\377", /* 2 aIND (linefeed) */
"\377", /* 3 aNEL (CR/LF) */
"\377", /* 4 aRI (reverse LF) */
"\377", /* 5 aSGR0 (Courier) */
"\377", /* 6 aSGR3 (italics) */
"\377", /* 7 aSGR23 (no italics) */
"\377", /* 8 aSGR4 (underline) */
"\377", /* 9 aSGR24 (no underline) */
"\377", /* 10 aSGR1 (boldface) */
"\377", /* 11 aSGR21 (no boldface) */
"\377", /* 12 aSFC (set text color) */
"\377", /* 13 aSBC (set background color) */
"\377", /* 14 aSHORP0 (normal pitch) */
"\377", /* 15 aSHORP2 (elite) */
"\377", /* 16 aSHORP1 (no elite) */
"\377", /* 17 aSHORP4 (condensed) */
"\377", /* 18 aSHORP3 (no condensed) */
"\377", /* 19 aSHORP6 (enlarge) */
"\377", /* 20 aSHORT5 (no enlarge) */
"\377", /* 21 aDEN6 (shadow) */
"\377", /* 22 aDEN5 (no shadow) */
"\377", /* 23 aDEN4 (double strike) */
"\377", /* 24 aDEN3 (no double strike) */
"\377", /* 25 aDEN2 (NLQ) */
"\377", /* 26 aDEN1 (no NLQ) */
"\377", /* 27 aSUS2 (superscript) */
"\377", /* 28 aSUS1 (no superscript) */
"\377", /* 29 aSUS4 (subscript) */
"\377", /* 30 aSUS3 (no subscript) */
"\377", /* 31 aSUS0 (normal) */
"\377", /* 32 aPLU (partial line up) */
"\377", /* 33 aPLD (partial line down) */
"\377", /* 34 aFNT0 (Courier) */
"\377", /* 35 aFNT1 (Helvetica) */
"\377", /* 36 aFNT2 (Font 2) */
"\377", /* 37 aFNT3 (Font 3) */
"\377", /* 38 aFNT4 (Font 4) */
"\377", /* 39 aFNT5 (Font 5) */
"\377", /* 40 aFNT6 (Font 6) */
"\377", /* 41 aFNT7 (Font 7) */
"\377", /* 42 aFNT8 (Font 8) */
"\377", /* 43 aFNT9 (Font 9) */
"\377", /* 44 aFNT10 (Font 10) */
"\377", /* 45 aPROP2 (proportional) */
"\377", /* 46 aPROP1 (no proportional) */
"\377", /* 47 aPROP0 (default proportion) */
"\377", /* 48 aTSS (set proportional offset) */
"\377", /* 49 aJFY5 (left justify) */
"\377", /* 50 aJFY7 (right justify) */
"\377", /* 51 aJFY6 (full justify) */
"\377", /* 52 aJFY0 (no justify) */
"\377", /* 53 aJFY3 (letter space) */
"\377", /* 54 aJFY1 (word fill) */
"\377", /* 55 aVERP0 (1/8" line spacing) */
"\377", /* 56 aVERP1 (1/6" line spacing) */
"\377", /* 57 aSLPP (form length) */
"\377", /* 58 aPERF (skip n perfs) */
"\377", /* 59 aPERF0 (no skip perfs) */
"\377", /* 60 aLMS (left margin) */
"\377", /* 61 aRMS (right margin) */
"\377", /* 62 aTMS (top margin) */
"\377", /* 63 aBMS (bot margin) */
"\377", /* 64 aSTBM (top & bottom margin) */
"\377", /* 65 aSLRM (left & right margin) */
"\377", /* 66 aCAM (no margins) */
"\377", /* 67 aHTS (horizontal tabs) */
"\377", /* 68 aVTS (vertical tabs) */
"\377", /* 69 aTBC0 (clear horizontal tab) */
"\377", /* 70 aTBC3 (clear all horiz. tabs) */
"\377", /* 71 aTBC1 (clear vertical tab) */
"\377", /* 72 aTBC4 (clear all vertical tabs) */
"\377", /* 73 aTBCALL (clear all tabs) */
"\377", /* 74 aTBSALL (default tabs) */
"\377", /* 75 aEXTEND (extended chars) */
"\377", /* 76 aRAW (next N chars are literal) */
};
static CONST_STRPTR cmdTable[] = {
"aRIS", /* 0 */
"aRIN", /* 1 */
"aIND", /* 2 */
"aNEL", /* 3 */
"aRI", /* 4 */
"aSGR0", /* 5 */
"aSGR3", /* 6 */
"aSGR23", /* 7 */
"aSGR4", /* 8 */
"aSGR24", /* 9 */
"aSGR1", /* 10 */
"aSGR21", /* 11 */
"aSFC", /* 12 */
"aSBC", /* 13 */
"aSHORP0", /* 14 */
"aSHORP2", /* 15 */
"aSHORP1", /* 16 */
"aSHORP4", /* 17 */
"aSHORP3", /* 18 */
"aSHORP6", /* 19 */
"aSHORT5", /* 20 */
"aDEN6", /* 21 */
"aDEN5", /* 22 */
"aDEN4", /* 23 */
"aDEN3", /* 24 */
"aDEN2", /* 25 */
"aDEN1", /* 26 */
"aSUS2", /* 27 */
"aSUS1", /* 28 */
"aSUS4", /* 29 */
"aSUS3", /* 30 */
"aSUS0", /* 31 */
"aPLU", /* 32 */
"aPLD", /* 33 */
"aFNT0", /* 34 */
"aFNT1", /* 35 */
"aFNT2", /* 36 */
"aFNT3", /* 37 */
"aFNT4", /* 38 */
"aFNT5", /* 39 */
"aFNT6", /* 40 */
"aFNT7", /* 41 */
"aFNT8", /* 42 */
"aFNT9", /* 43 */
"aFNT10", /* 44 */
"aPROP2", /* 45 */
"aPROP1", /* 46 */
"aPROP0", /* 47 */
"aTSS", /* 48 */
"aJFY5", /* 49 */
"aJFY7", /* 50 */
"aJFY6", /* 51 */
"aJFY0", /* 52 */
"aJFY3", /* 53 */
"aJFY1", /* 54 */
"aVERP0", /* 55 */
"aVERP1", /* 56 */
"aSLPP", /* 57 */
"aPERF", /* 58 */
"aPERF0", /* 59 */
"aLMS", /* 60 */
"aRMS", /* 61 */
"aTMS", /* 62 */
"aBMS", /* 63 */
"aSTBM", /* 64 */
"aSLRM", /* 65 */
"aCAM", /* 66 */
"aHTS", /* 67 */
"aVTS", /* 68 */
"aTBC0", /* 69 */
"aTBC3", /* 70 */
"aTBC1", /* 71 */
"aTBC4", /* 72 */
"aTBCALL", /* 73 */
"aTBSALL", /* 74 */
"aEXTEND", /* 75 */
"aRAW", /* 76 */
};
static CONST_STRPTR PED_8BitChars[] = {
" ", /* SPC (160) */
"?", /* ! */
"?", /* c */
"?", /* £ */
"?", /* o */
"?", /* Y */
"|",
"?", /* S */
"?",
"?", /* Copyright */
"?", /* a */
"?", /* < */
"?", /* - */
"?", /* SHY */
"?", /* R */
"?", /* - */
"?", /* o (176) */
"?", /* +- */
"?", /* 2 */
"?", /* 3 */
"?",
"?", /* u */
"?", /* P */
"?", /* . */
"?", /* , */
"?", /* 1 */
"?", /* o */
"?", /* > */
"?", /* 1/4 */
"?", /* 1/2 */
"?", /* 3/4 */
"?", /* ? */
"?", /* A' (192) */
"?", /* A' */
"?", /* A^ */
"?", /* A~ */
"?", /* A: */
"?", /* Ao */
"?", /* AE */
"?", /* C */
"?", /* E' */
"?", /* E' */
"?", /* E^ */
"?", /* E: */
"?", /* I' */
"?", /* I' */
"?", /* I^ */
"?", /* I: */
"?", /* D- (208) */
"?", /* N~ */
"?", /* O' */
"?", /* O' */
"?", /* O^ */
"?", /* O~ */
"?", /* O: */
"?", /* x */
"?", /* 0 */
"?", /* U' */
"?", /* U' */
"?", /* U^ */
"?", /* U: */
"?", /* Y' */
"?", /* p */
"?", /* B */
"?", /* a' (224) */
"?", /* a' */
"?", /* a^ */
"?", /* a~ */
"?", /* a: */
"?", /* ao */
"?", /* ae */
"?", /* c */
"?", /* e' */
"?", /* e' */
"?", /* e^ */
"?", /* e: */
"?", /* i' */
"?", /* i' */
"?", /* i^ */
"?", /* i: */
"?", /* o (240) */
"?", /* n~ */
"?", /* o' */
"?", /* o' */
"?", /* o^ */
"?", /* o~ */
"?", /* o: */
"?", /* / */
"?", /* 0 */
"?", /* u' */
"?", /* u' */
"?", /* u^ */
"?", /* u: */
"?", /* y' */
"?", /* p */
"?", /* y: */
};
static struct TagItem PED_TagList[] = {
{ PRTA_8BitGuns, TRUE }, /* 0 */
{ PRTA_MixBWColor, TRUE }, /* 1 */
{ PRTA_LeftBorder, 0 }, /* 2 */
{ PRTA_TopBorder, 0 }, /* 3 */
// { PRTA_ConvertSource, TRUE }, /* 4 */
{ PRTA_ColorCorrection, TRUE }, /* 5 */
{ TAG_END }
};
AROS_PRINTER_TAG(PED, 44, 0,
.ped_PrinterName = "Skeleton",
.ped_Init = sk_Init,
.ped_Expunge = sk_Expunge,
.ped_Open = sk_Open,
.ped_Close = sk_Close,
/* Settings for a 'graphics only' printer */
.ped_PrinterClass = PPC_COLORGFX | PPCF_EXTENDED,
.ped_MaxColumns = 0, /* Set during render */
.ped_ColorClass = PCC_YMCB | PCC_MULTI_PASS,
.ped_NumCharSets = 2,
.ped_NumRows = 1, /* minimum pixels/row in gfx mode */
.ped_MaxXDots = 0, /* Set during render */
.ped_MaxYDots = 0, /* Set during render */
.ped_XDotsInch = 0, /* Set during render */
.ped_YDotsInch = 0, /* Set during render */
.ped_Commands = (STRPTR *)PED_Commands, /* No ANSI commands */
.ped_DoSpecial = sk_DoSpecial,
.ped_Render = sk_Render,
.ped_TimeoutSecs = 1000, /* For print-to-file timeouts */
.ped_8BitChars = (STRPTR *)PED_8BitChars,
.ped_PrintMode = 1,
.ped_ConvFunc = sk_ConvFunc,
.ped_TagList = &PED_TagList[0],
.ped_DoPreferences = sk_DoPreferences,
.ped_CallErrHook = sk_CallErrHook,
);
struct PrinterData *PD;
static CONST_STRPTR sk_PaperSize;
static LONG sk_PrintBufLen;
static LONG sk_SpacingLPI;
static LONG sk_FontCPI;
static LONG sk_Init(struct PrinterData *pd)
{
D(bug("sk_Init: pd=%p\n", pd));
PD = pd;
return 0;
}
static VOID sk_Expunge(VOID)
{
D(bug("sk_Expunge\n"));
PD = NULL;
}
static struct {
char buff_a[16];
char buff_b[16];
char *buff;
int len;
} sk_PState = {
.buff = &sk_PState.buff_a[0]
};
#define PFLUSH() do { \
PD->pd_PWrite(sk_PState.buff, sk_PState.len); \
if (sk_PState.buff == &sk_PState.buff_a[0]) \
sk_PState.buff = &sk_PState.buff_b[0]; \
else \
sk_PState.buff = &sk_PState.buff_a[0]; \
sk_PState.len = 0; \
} while (0)
static AROS_UFH2(void, sk_PPutC,
AROS_UFHA(UBYTE, c, D0),
AROS_UFHA(APTR, dummy, A3))
{
AROS_USERFUNC_INIT
/* Ignore the trailing 0 that RawDoFmt() tacks on the end */
if (c == 0)
return;
sk_PState.buff[sk_PState.len++]=c;
if (sk_PState.len >= 16)
PFLUSH();
AROS_USERFUNC_EXIT
}
#define sk_PWrite(fmt, ...) \
do { \
IPTR args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) }; \
RawDoFmt(fmt, args, (VOID_FUNC)sk_PPutC, NULL); \
PFLUSH(); \
} while (0);
#define sk_VWrite(buf, fmt, ...) \
do { \
IPTR args[] = { AROS_PP_VARIADIC_CAST2IPTR(__VA_ARGS__) }; \
RawDoFmt(fmt, args, RAWFMTFUNC_STRING, buf); \
} while (0);
static LONG sk_Open(union printerIO *ior)
{
D(bug("sk_Open: ior=%p\n", ior));
return 0;
}
static VOID sk_Close(union printerIO *ior)
{
D(bug("sk_Close: ior=%p\n", ior));
}
static LONG sk_RenderInit(struct IODRPReq *io, LONG width, LONG height)
{
D(bug("sk_RenderInit: Dump raster %ldx%ld pixels, io_RastPort=%p\n", width, height, io->io_RastPort));
D(bug("\t@%ldx%ld (%ldx%ld) => @%ldx%ld\n",
io->io_SrcX, io->io_SrcY, io->io_SrcWidth,
io->io_SrcHeight, io->io_DestCols, io->io_DestRows));
LONG alignOffsetX = 0;
LONG alignOffsetY = 0;
LONG x, y;
sk_PrintBufLen = width;
PD->pd_PrintBuf = AllocMem(sk_PrintBufLen * 6, MEMF_ANY);
if (PD->pd_PrintBuf == NULL)
return PDERR_BUFFERMEMORY;
if (PD->pd_Preferences.PrintFlags & PGFF_CENTER_IMAGE) {
alignOffsetX = (PED->ped_MaxXDots - width) / 2;
alignOffsetY = (PED->ped_MaxYDots - height) / 2;
}
sk_PWrite("[IMAGE]\n");
return PDERR_NOERR;
}
static LONG sk_RenderTransfer(struct PrtInfo *pi, LONG color, LONG y)
{
UBYTE *ptr = PD->pd_PrintBuf;
union colorEntry *src = pi->pi_ColorInt;
int x;
D(bug("\tSource=%p\n", src));
sk_PWrite("[Image %ld] ", y);
for (x = 0; x < pi->pi_width; x++, src++, ptr++) {
*ptr = " ..ccooCCOO@@##"[(src->colorByte[PCMBLACK] >> 4) & 0xf];
}
return PDERR_NOERR;
}
static LONG sk_RenderFlush(LONG rows)
{
PD->pd_PWrite(PD->pd_PrintBuf, sk_PrintBufLen);
PD->pd_PWrite("\n", 1);
return PDERR_NOERR;
}
static LONG sk_RenderClear(void)
{
memset(PD->pd_PrintBuf, ' ', sk_PrintBufLen);
return PDERR_NOERR;
}
static LONG sk_RenderPreInit(struct IODRPReq *io, LONG flags)
{
ULONG dpiX, dpiY;
ULONG width, height;
/* Select DPI */
switch (flags & SPECIAL_DENSITYMASK) {
case SPECIAL_DENSITY1:
dpiX = 72;
dpiY = 72;
break;
case SPECIAL_DENSITY2:
dpiX = 10;
dpiY = 10;
break;
case SPECIAL_DENSITY3:
dpiX = 120;
dpiY = 120;
break;
case SPECIAL_DENSITY4:
dpiX = 150;
dpiY = 150;
break;
case SPECIAL_DENSITY5:
dpiX = 300;
dpiY = 300;
break;
case SPECIAL_DENSITY6:
dpiX = 600;
dpiY = 600;
break;
case SPECIAL_DENSITY7:
dpiX = 1200;
dpiY = 1200;
break;
default:
dpiX = 72;
dpiY = 72;
}
switch (PD->pd_Preferences.PrintPitch) {
case PP_ELITE: sk_FontCPI = 120; break;
case PP_FINE: sk_FontCPI = 171; break;
case PP_PICA: sk_FontCPI = 100; break;
default:
return PDERR_BADDIMENSION;
}
switch (PD->pd_Preferences.PrintSpacing) {
case PS_SIX_LPI: sk_SpacingLPI = 6; break;
case PS_EIGHT_LPI: sk_SpacingLPI = 8; break;
default:
return PDERR_BADDIMENSION;
}
switch (PD->pd_Preferences.PaperSize) {
/* PaperSize (in units of 0.0001 meters) */
case US_LETTER: sk_PaperSize = "Letter"; break; /* 8.5"x11" */
case US_LEGAL: sk_PaperSize = "Legal"; break; /* 8.5"x14" */
case N_TRACTOR: sk_PaperSize = "80-Col"; break; /* 9.5"x11" */
case W_TRACTOR: sk_PaperSize = "132-Col"; break; /* 14.86"x11" */
/* European sizes */
case EURO_A0: sk_PaperSize = "A0"; break; /* A0: 841 x 1189 */
case EURO_A1: sk_PaperSize = "A1"; break; /* A1: 594 x 841 */
case EURO_A2: sk_PaperSize = "A2"; break; /* A2: 420 x 594 */
case EURO_A3: sk_PaperSize = "A3"; break; /* A3: 297 x 420 */
case EURO_A4: sk_PaperSize = "A4"; break; /* A4: 210 x 297 */
case EURO_A5: sk_PaperSize = "A5"; break; /* A5: 148 x 210 */
case EURO_A6: sk_PaperSize = "A6"; break; /* A6: 105 x 148 */
case EURO_A7: sk_PaperSize = "A7"; break; /* A7: 74 x 105 */
case EURO_A8: sk_PaperSize = "A8"; break; /* A8: 52 x 74 */
case CUSTOM: sk_PaperSize = "Custom"; break;
default: return PDERR_BADDIMENSION;
}
/* Set up for the page size */
switch (PD->pd_Preferences.PaperSize) {
/* PaperSize (in units of 0.0001 meters) */
case US_LETTER: width = 2159; height = 2794; break; /* 8.5"x11" */
case US_LEGAL: width = 2159; height = 3556; break; /* 8.5"x14" */
case N_TRACTOR: width = 2413; height = 2794; break; /* 9.5"x11" */
case W_TRACTOR: width = 3774; height = 2794; break; /* 14.86"x11" */
/* European sizes */
case EURO_A0: width = 8410; height = 11890; break; /* A0: 841 x 1189 */
case EURO_A1: width = 5940; height = 8410; break; /* A1: 594 x 841 */
case EURO_A2: width = 4200; height = 5940; break; /* A2: 420 x 594 */
case EURO_A3: width = 2970; height = 4200; break; /* A3: 297 x 420 */
case EURO_A4: width = 2100; height = 2970; break; /* A4: 210 x 297 */
case EURO_A5: width = 1480; height = 2100; break; /* A5: 148 x 210 */
case EURO_A6: width = 1050; height = 1480; break; /* A6: 105 x 148 */
case EURO_A7: width = 740; height = 1050; break; /* A7: 74 x 105 */
case EURO_A8: width = 520; height = 740; break; /* A8: 52 x 74 */
case CUSTOM: width = PD->pd_Preferences.PrintMaxWidth * 254 / 10;
height = PD->pd_Preferences.PrintMaxHeight * 254 / 10;
break;
default: return PDERR_CANCEL;
}
PED->ped_MaxColumns = width * sk_FontCPI / 2540;
PED->ped_XDotsInch = dpiX;
PED->ped_YDotsInch = dpiY;
PED->ped_MaxXDots = width * dpiX / 254;
PED->ped_MaxYDots = height * dpiY / 254;
D(bug("MaxColumns=%d, dpiX=%d, dpiY=%d, MaxXDots=%d, MaxYDots=%d (%d x %d in)\n",
PED->ped_MaxColumns, PED->ped_XDotsInch, PED->ped_YDotsInch,
PED->ped_MaxXDots, PED->ped_MaxYDots,
PED->ped_MaxXDots / dpiX, PED->ped_MaxYDots / dpiY));
return PDERR_NOERR;
}
static LONG sk_RenderClose(SIPTR error, ULONG flags)
{
if (error != PDERR_CANCEL) {
/* Send formfeed */
if (!(flags & SPECIAL_NOFORMFEED))
sk_PWrite("[FF]\n");
}
sk_PWrite("[Close]\n");
return PDERR_NOERR;
}
static LONG sk_RenderNextColor(void)
{
return PDERR_NOERR;
}
/* If Tag PRTA_ConvertSource is set, this function is called instead
* of the printer.device built-in to convert.
*
* The size of each entry is either sizeof(union colorEntry), or
* Tag PRTA_ColorSize (if set)
*
* The conversion is done in-place.
*/
static LONG sk_RenderConvert(APTR row, LONG entries, LONG is_pixels)
{
return PDERR_NOERR;
}
/* If Tag PRTA_ColorCorrection is set, this function is called instead
* of the printer.device built-in to correct printer-space colors.
*
* The size of each entry is either sizeof(union colorEntry), or
* Tag PRTA_ColorSize (if set)
*
* The conversion is done in-place.
*/
static LONG sk_RenderCorrect(APTR row, LONG entries, LONG is_pixels)
{
return PDERR_NOERR;
}
static LONG sk_Render(SIPTR ct, LONG x, LONG y, LONG status)
{
LONG err = PDERR_NOERR;
switch (status) {
case PRS_INIT:
D(bug("PRS_INIT: IODRPReq=%p, width=%d, height=%d\n", ct, x, y));
err = sk_RenderInit((struct IODRPReq *)ct, x, y);
break;
case PRS_TRANSFER:
D(bug("PRS_TRANSFER: PrtInfo=%p, color=%d, row=%d\n", ct, x, y));
err = sk_RenderTransfer((struct PrtInfo *)ct, x, y);
break;
case PRS_FLUSH:
D(bug("PRS_FLUSH: ct=%p, x=%d, rows=%d\n", ct, x, y));
err = sk_RenderFlush(y);
break;
case PRS_CLEAR:
D(bug("PRS_CLEAR: ct=%p, x=%d, y=%d\n", ct, x, y));
err = sk_RenderClear();
break;
case PRS_CLOSE:
D(bug("PRS_CLOSE: error=%d, io_Special=0x%0x, y=%d\n", ct, x, y));
err = sk_RenderClose(ct, x);
break;
case PRS_PREINIT:
D(bug("PRS_PREINIT: IODRPReq=%p, io_Special=0x%0x, y=%d\n", ct, x, y));
err = sk_RenderPreInit((struct IODRPReq *)ct, x);
break;
case PRS_NEXTCOLOR:
D(bug("PRS_NEXTCOLOR: ct=%p, x=0x%0x, y=%d\n", ct, x, y));
err = sk_RenderNextColor();
break;
case PRS_UNKNOWN:
D(bug("PRS_UNKNOWN: ct=%p, x=0x%0x, y=%d\n", ct, x, y));
err = PDERR_NOERR;
break;
case PRS_CONVERT:
D(bug("PRS_CONVERT: row=%p, entries=%d, type=%s\n", ct, x, y ? "pixels" : "union colorEntry"));
err = sk_RenderConvert((APTR)ct, x, y);
break;
case PRS_CORRECT:
D(bug("PRS_CORRECT: row=%p, entries=%d, type=%s\n", ct, x, y ? "pixels" : "union colorEntry"));
err = sk_RenderCorrect((APTR)ct, x, y);
break;
default:
D(bug("PRS_xxxx(%d): ct=%p, x=0x%0x, y=%d\n", status, ct, x, y));
break;
}
return err;
}
/* Text output:
* > 0 = processed, add N chars
* 0 = not handled by DoSpecial
* -1 = Unsupported command
* -2 = Processed, but no additional chars in the buffer
*/
static LONG sk_DoSpecial(UWORD *command, UBYTE output_buffer[],
BYTE *current_line_position,
BYTE *current_line_spacing,
BYTE *crlf_flag, UBYTE params[])
{
D(bug("sk_DoSpecial: command=0x%04x, output_buffer=%p, current_line_position=%d, current_line_spacing=%d, crlf_flag=%d, params=%s\n",
*command, output_buffer, *current_line_position, *current_line_spacing, *crlf_flag, params));
sk_VWrite(output_buffer, "[%s %ld,%ld,%ld,%ld]", cmdTable[*command], params[0], params[1], params[2], params[3]);
return strlen(output_buffer);
}
static LONG sk_ConvFunc(UBYTE *buf, UBYTE c, LONG crlf_flag)
{
D(bug("sk_ConvFunc: %p '%c' %d\n", buf, c, crlf_flag));
/* NOTE: For compatability with AOS 3.x, do
* not attempt to convert ESC or \377
* characters if you want DoSpecial() to work.
*/
if (c == 0x1b || c == 0xff)
return -1;
/* As a demo, we're going to UPPERCASE all characters,
* and put a '\' in front of the modified character.
*/
if (c >= 'a' && c <= 'z') {
*(buf++) = '\\';
*(buf++) = c;
return 2;
}
return -1;
}
static LONG sk_DoPreferences(union printerIO *ior, LONG command)
{
D(bug("sk_DoPreferences: ior=%p, command=%d\n"));
return 0;
}
static VOID sk_CallErrHook(union printerIO *ior, struct Hook *hook)
{
D(bug("sk_CallErrHook: ior=%p, hook=%p\n", ior, hook));
}
struct FileHandle *file; file = Open( "PRT:", MODE_NEWFILE ); /* Open PRT: */ if (file == 0) /* if the open was unsuccessful */ exit(PRINTER_WONT_OPEN);
参见 2View src
还可以看一下 TurboPrint 的 printer.device API 扩展。在 v44 之前,它一直是多年来的事实标准。可以在 此处找到文档。实际上,AROS printer.device 已经支持所有 CyberGfx 位图格式以及每种屏幕模式。当然。但 TurboPrint 还用自己的命令扩展了 printer.device。如果您对 68k 二进制兼容性感兴趣,这可能是一个简单的补充,因为它非常接近 CBM 的 DUMPRPORT 命令。
它的工作原理是将所有缩放比例放到源位图的 AllocBitmap()“朋友”中,并使用 CyberGfx ReadPixelArray() 从中获取 BGR032 像素行。BGR032 与打印机驱动程序内部使用的格式相同(除非为 YMCK 目的而反转),因此无需在那里进行额外的转换。io_Modes 仅用于获取显示器的纵横比。我还没有测试过打印 HAM6 或 HAM8 图像,但我也不知道是否有用于此的测试程序。我建议使用 Turboprint SDK 和 Ghostscript 68k(旧的 5.x,包含在 TurboPrint 中,以及新的)中的示例程序。两者都提供源代码。ArtEffect 也支持 Turboprint,还有我的 Scandal(aros x86 版本也是如此,但您必须有一些支持的扫描仪才能获取要打印的数据 :))
commit 43799 重新结构化以允许未来的打印机驱动程序。
struct IODRPReq { struct Message io_Message; struct Device *io_Device; /* device node pointer */ struct Unit *io_Unit; /* unit (driver private)*/ UWORD io_Command; /* device command */ UBYTE io_Flags; BYTE io_Error; /* error or warning num */ struct RastPort *io_RastPort; /* raster port */ struct ColorMap *io_ColorMap; /* color map */ ULONG io_Modes; /* graphics viewport modes */ UWORD io_SrcX; /* source x origin */ UWORD io_SrcY; /* source y origin */ UWORD io_SrcWidth; /* source x width */ UWORD io_SrcHeight; /* source x height */ LONG io_DestCols; /* destination x width */ LONG io_DestRows; /* destination y height */ UWORD io_Special; /* option flags */ };
struct IOPrtCmdReq { struct Message io_Message; struct Device *io_Device; /* device node pointer */ struct Unit *io_Unit; /* unit (driver private)*/ UWORD io_Command; /* device command */ UBYTE io_Flags; BYTE io_Error; /* error or warning num */ UWORD io_PrtCommand; /* printer command */ UBYTE io_Parm0; /* first command parameter */ UBYTE io_Parm1; /* second command parameter */ UBYTE io_Parm2; /* third command parameter */ UBYTE io_Parm3; /* fourth command parameter */ };
错误在 io_Error 中找到。
PRINTER DEVICE ERROR CODES Error Value Explanation ----- ----- ----------- PDERR_NOERR 0 Operation successful PDERR_CANCEL 1 User canceled request PDERR_NOTGRAPHICS 2 Printer cannot output graphics PDERR_INVERTHAM 3 OBSOLETE PDERR_BADDIMENSION 4 Print dimensions are illegal PDERR_DIMENSIONOVERFLOW 5 OBSOLETE PDERR_INTERNALMEMORY 6 No memory available for internal variables PDERR_BUFFERMEMORY 7 No memory available for print buffer EXEC ERROR CODES Error Value Explanation ---- ----- ----------- IOERR_OPENFAIL -1 Device failed to open IOERR_ABORTED -2 Request terminated early (after AbortIO()) IOERR_NOCMD -3 Command not supported by device IOERR_BADLENGTH -4 Not a valid length
Amiga Printer Commands ---------------------- Esc[<n>"<x> where `<n>' is the decimal typed number of bytes in the string `<x>', which actually contains your special printer sequence. This ANSI sequence tells the printer driver to not interpret or translate the next `<n>' bytes. 10 Line Feed 13 Carriage Return 14 Form Feed ESCc Reset ESC#1 Initialise ESCD Line feed ESCE CR, LF ESCM Reverse line feed ESC[0m Normal char set ESC[3m Italics on ESC[23m Italics off ESC[4m Underline on ESC[24m Underline off ESC[1m Bold on ESC[22 Boldface off ESC[nm Set foreground colour (30-39) ESC[nm Set background colour (40-49) ESC[0w Normal pitch ESC[2w Elite on ESC[1w Elite off ESC[4w Condensed on ESC[3w Condensed off ESC[6w Enlarge on ESC[5w Enlarge off ESC[6"z Shadow print on ESC[5"z Shadow print off ESC[4"z Doublestrikes on ESC[3"z Doublestrikes off ESC[2"z NLQ on ESC[1"z NLQ off ESC[2v Superscript on ESC[1v Superscript off ESC[4v Subscript on ESC[3v Subscript off ESC[0v Normalise the line ESCL Partial line up ESCK Partial line down ESC(B US Char set (Typeface 0) ESC(R French char set (Typeface 1) ESC(K German char set (Typeface 2) ESC(A UK char set (Typeface 3) ESC(E Danish 1 char set (Typeface 4) ESC(H Swedish char set (Typeface 5) ESC(Y Italian char set (Typeface 6) ESC(Z Spanish char set (Typeface 7) ESC(J Japanese char set (Typeface 8) ESC(6 Norwegian char set (Typeface 90) ESC(C Danish 2 char set (Typeface 10) ESC[2p Proportional on ESC[1p Proportional off ESC[0p Proportional clear ESC[nE Set proportional offset ESC[5F Auto left justify ESC[7F Auto right justify ESC[6F Auto full justify ESC[0F Auto justify off ESC[3F Letter space (justify) ESC[1F Word fill (Auto Centre) ESC[0z 1/8" line spacing ESC[1z 1/6" line spacing ESC[nt Set form length n ESC[nq Perforation skip n (n>0) ESC[0q Perforation skip off ESC#9 Set left margin ESC#0 Set right margin ESC#8 Set top margin ESC#2 Set bottom margin ESC[n;nr Top and bottom margins ESC[n;ns Left and right margins ESC#3 Clear margins ESCH Set horizontal tab ESCJ Setg Vertical tab ESC[0g Clear horizontal tab ESC[3g Clear all horizontal tabs ESC[1g Clear Vertical tab ESC[4g Clear all vertical tabs ESC#4 Clear all tabs ESC#5 Set default tabs ESC[n"x Extended commands n = Decimal number e.g. 12
PRINTER DEVICE COMMAND FUNCTIONS Cmd Escape Defined Name No. Sequence Function by: ---- --- -------- -------- ------- aRIS 0 ESCc Reset ISO aRIN 1 ESC#1 Initialize +++ aIND 2 ESCD Linefeed ISO aNEL 3 ESCE Return,linefeed ISO aRI 4 ESCM Reverse linefeed ISO aSGR0 5 ESC[0m Normal char set ISO aSGR3 6 ESC[3m Italics on ISO aSGR23 7 ESC[23m Italics off ISO aSGR4 8 ESC[4m Underline on ISO aSGR24 9 ESC[24m Underline off ISO aSGR1 10 ESC[1m Boldface on ISO aSGR22 11 ESC[22m Boldface off ISO aSFC 12 ESC[nm Set foreground color where n ISO stands for a pair of ASCII digits, 3 followed by any number 0-9 (See ISOColor Table) aSBC 13 ESC[nm Set background color where n ISO stands for a pair of ASCII digits, 4 followed by any number 0-9 (See ISO Color Table) aSHORP0 14 ESC[0w Normal pitch DEC aSHORP2 15 ESC[2w Elite on DEC aSHORP1 16 ESC[1w Elite off DEC aSHORP4 17 ESC[4w Condensed fine on DEC aSHORP3 18 ESC[3w Condensed off DEC aSHORP6 19 ESC[6w Enlarged on DEC aSHORP5 20 ESC[5w Enlarged off DEC aDEN6 21 ESC[6"z Shadow print on DEC aDEN5 22 ESC[5"z Shadow print off (sort of)DEC aDEN4 23 ESC[4"z Doublestrike on DEC aDEN3 24 ESC[3"z Doublestrike off DEC aDEN2 25 ESC[2"z NLQ on DEC aDEN1 26 ESC[1"z NLQ off DEC aSUS2 27 ESC[2v Superscript on +++ aSUS1 28 ESC[1v Superscript off +++ aSUS4 29 ESC[4v Subscript on +++ aSUS3 30 ESC[3v Subscript off +++ aSUS0 31 ESC[0v Normalize the line +++ aPLU 32 ESCL Partial line up ISO aPLD 33 ESCK Partial line down ISO aFNT0 34 ESC(B US char set or Typeface 0 DEC aFNT1 35 ESC(R French char set or Typeface 1 DEC aFNT2 36 ESC(K German char set or Typeface 2 DEC aFNT3 37 ESC(A UK char set or Typeface 3 DEC aFNT4 38 ESC(E Danish I char set or Typeface 4 DEC aFNT5 39 ESC(H Swedish char set or Typeface 5 DEC aFNT6 40 ESC(Y Italian char set or Typeface 6 DEC aFNT7 41 ESC(Z Spanish char set or Typeface 7 DEC aFNT8 42 ESC(J Japanese char set or Typeface 8 +++ aFNT9 43 ESC(6 Norwegian char set or Typeface 9 DEC aFNT10 44 ESC(C Danish II char set or Typeface 10 +++ (See Suggested Typefaces Table) aPROP2 45 ESC[2p Proportional on +++ aPROP1 46 ESC[1p Proportional off +++ aPROP0 47 ESC[0p Proportional clear +++ aTSS 48 ESC[n E Set proportional offset ISO aJFY5 49 ESC[5 F Auto left justify ISO aJFY7 50 ESC[7 F Auto right justify ISO aJFY6 51 ESC[6 F Auto full justify ISO aJFY0 52 ESC[0 F Auto justify off ISO aJFY3 53 ESC[3 F Letter space (justify) (special)ISO aJFY1 54 ESC[1 F Word fill(auto center) (special)ISO aVERP0 55 ESC[0z 1/8" line spacing +++ aVERP1 56 ESC[1z 1/6" line spacing +++ aSLPP 57 ESC[nt Set form length n DEC aPERF 58 ESC[nq Perf skip n (n>0) +++ aPERF0 59 ESC[0q Perf skip off +++ aLMS 60 ESC#9 Left margin set +++ aRMS 61 ESC#0 Right margin set +++ aTMS 62 ESC#8 Top margin set +++ aBMS 63 ESC#2 Bottom margin set +++ aSTBM 64 ESC[n; nr Top and bottom margins DEC aSLRM 65 ESC[n; ns Left and right margins DEC aCAM 66 ESC#3 Clear margins +++ aHTS 67 ESCH Set horizontal tab ISO aVTS 68 ESCJ Set vertical tabs ISO aTBC0 69 ESC[0g Clear horizontal tab ISO aTBC3 70 ESC[3g Clear all h. tabs ISO aTBC1 71 ESC[1g Clear vertical tab ISO aTBC4 72 ESC[4g Clear all v. tabs ISO aTBCALL 73 ESC#4 Clear all h. & v. tabs +++ aTBSALL 74 ESC#5 Set default tabs +++ aEXTEND 75 ESC[n"x Extended commands +++ aRAW 76 ESC[n"r Next n chars are raw +++ Legend: ------ ISO indicates that the sequence has been defined by the International Standards Organization. This is also very similar to ANSI x3.64. DEC indicates a control sequence defined by Digital Equipment Corporation. +++ indicates a sequence unique to Amiga. n stands for a decimal number expressed as a set of ASCII digits. In the aRAW string ESC[5"rHELLO, n is substituted by 5, the number of RAW characters you send to the printer. ISO Color Table Suggested Typefaces --------------- ------------------- 0 Black 0 Default typeface 1 Red 1 Line Printer or equivalent 2 Green 2 Pica or equivalent 3 Yellow 3 Elite or equivalent 4 Blue 4 Helvetica or equivalent 5 Magenta 5 Times Roman or equivalent 6 Cyan 6 Gothic or equivalent 7 White 7 Script or equivalent 8 NC 8 Prestige or equivalent 9 Default 9 Caslon or equivalent 10 Orator or equivalent
The status is returned in the two UBYTES set in the io_Data field. The printer type, either serial or parallel, is returned in the io_Actual field. io_Data Bit Active Function (Serial Device) ------- --- ------ ------------------------ LSB 0 low reserved 1 low reserved 2 low reserved 3 low Data Set Ready 4 low Clear To Send 5 low Carrier Detect 6 low Ready To Send 7 low Data Terminal Ready MSB 8 high read buffer overflow 9 high break sent (most recent output) 10 high break received (as latest input) 11 high transmit x-OFFed 12 high receive x-OFFed 13-15 high reserved io_Data Bit Active Function (Parallel Device) ------- --- ------ -------------------------- LSB 0 high printer busy (offline) 1 high paper out 2 high printer selected 3 - read=0; write=1 4-7 reserved MSB 8-15 reserved io_Actual 1-parallel, 2-serial
PIO->iodrp.io_Special = SPECIAL_ASPECT | SPECIAL_FRACCOLS; PIO->iodrp.io_DestCols = 0xffffffff / 2; PIO->iodrp.io_DestRows = 0;