From 987f2a6d7cfdff80a9cf234e6172c5f21c9ad2a3 Mon Sep 17 00:00:00 2001 From: Michael Pfeiffer Date: Mon, 27 Jan 2003 22:07:23 +0000 Subject: [PATCH] Implemented PCL5 printer driver using Y. Takagis excellent libprint. Color printing not supported yet! git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2589 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/add-ons/print/drivers/pcl5/Jamfile | 15 ++ src/add-ons/print/drivers/pcl5/PCL5.cpp | 248 ++++++++++++++++++ src/add-ons/print/drivers/pcl5/PCL5.h | 39 +++ src/add-ons/print/drivers/pcl5/PCL5.rsrc | Bin 0 -> 4161 bytes src/add-ons/print/drivers/pcl5/PCL5Cap.cpp | 134 ++++++++++ src/add-ons/print/drivers/pcl5/PCL5Cap.h | 19 ++ src/add-ons/print/drivers/pcl5/PCL5Entry.cpp | 83 ++++++ .../print/drivers/pcl5/PCL5_Protocol.txt | 84 ++++++ 8 files changed, 622 insertions(+) create mode 100644 src/add-ons/print/drivers/pcl5/Jamfile create mode 100644 src/add-ons/print/drivers/pcl5/PCL5.cpp create mode 100644 src/add-ons/print/drivers/pcl5/PCL5.h create mode 100644 src/add-ons/print/drivers/pcl5/PCL5.rsrc create mode 100644 src/add-ons/print/drivers/pcl5/PCL5Cap.cpp create mode 100644 src/add-ons/print/drivers/pcl5/PCL5Cap.h create mode 100644 src/add-ons/print/drivers/pcl5/PCL5Entry.cpp create mode 100644 src/add-ons/print/drivers/pcl5/PCL5_Protocol.txt diff --git a/src/add-ons/print/drivers/pcl5/Jamfile b/src/add-ons/print/drivers/pcl5/Jamfile new file mode 100644 index 0000000000..b854d6e839 --- /dev/null +++ b/src/add-ons/print/drivers/pcl5/Jamfile @@ -0,0 +1,15 @@ +SubDir OBOS_TOP src add-ons print drivers pcl5 ; + +SubDirHdrs [ FDirName $(OBOS_TOP) src add-ons print drivers canon_lips + libprint ] ; + +AddResources PCL5\ Compatible : PCL5.rsrc ; + +Addon PCL5\ Compatible : print : + PCL5Entry.cpp + PCL5.cpp + PCL5Cap.cpp +; + +LinkSharedOSLibs PCL5\ Compatible : be stdc++.r4 libprint.a ; + diff --git a/src/add-ons/print/drivers/pcl5/PCL5.cpp b/src/add-ons/print/drivers/pcl5/PCL5.cpp new file mode 100644 index 0000000000..3d54e894f7 --- /dev/null +++ b/src/add-ons/print/drivers/pcl5/PCL5.cpp @@ -0,0 +1,248 @@ +/* + * PCL5.cpp + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + * Copyright 2003 Michael Pfeiffer. + */ + +#include +#include +#include +#include +#include "PCL5.h" +#include "UIDriver.h" +#include "JobData.h" +#include "PrinterData.h" +#include "PCL5Cap.h" +#include "PackBits.h" +#include "Halftone.h" +#include "ValidRect.h" +#include "DbgMsg.h" + +#if (!__MWERKS__ || defined(MSIPL_USING_NAMESPACE)) +using namespace std; +#else +#define std +#endif + +PCL5Driver::PCL5Driver(BMessage *msg, PrinterData *printer_data, const PrinterCap *printer_cap) + : GraphicsDriver(msg, printer_data, printer_cap) +{ + __halftone = NULL; +} + +bool PCL5Driver::startDoc() +{ + try { + jobStart(); + __halftone = new Halftone(getJobData()->getSurfaceType(), getJobData()->getGamma()); + return true; + } + catch (TransportException &err) { + return false; + } +} + +bool PCL5Driver::startPage(int) +{ + return true; +} + +bool PCL5Driver::endPage(int) +{ + try { + writeSpoolChar('\014'); + return true; + } + catch (TransportException &err) { + return false; + } +} + +bool PCL5Driver::endDoc(bool) +{ + try { + if (__halftone) { + delete __halftone; + } + jobEnd(); + return true; + } + catch (TransportException &err) { + return false; + } +} + +bool PCL5Driver::nextBand(BBitmap *bitmap, BPoint *offset) +{ + DBGMSG(("> nextBand\n")); + + try { + BRect bounds = bitmap->Bounds(); + + RECT rc; + rc.left = (int)bounds.left; + rc.top = (int)bounds.top; + rc.right = (int)bounds.right; + rc.bottom = (int)bounds.bottom; + + int height = rc.bottom - rc.top + 1; + + int x = (int)offset->x; + int y = (int)offset->y; + + int page_height = getPageHeight(); + + if (y + height > page_height) { + height = page_height - y; + } + + rc.bottom = height - 1; + + DBGMSG(("height = %d\n", height)); + DBGMSG(("x = %d\n", x)); + DBGMSG(("y = %d\n", y)); + + if (get_valid_rect(bitmap, __halftone->getPalette(), &rc)) { + + DBGMSG(("validate rect = %d, %d, %d, %d\n", + rc.left, rc.top, rc.right, rc.bottom)); + + x = rc.left; + y += rc.top; + + int width = rc.right - rc.left + 1; + int widthByte = (width + 7) / 8; /* byte boundary */ + int height = rc.bottom - rc.top + 1; + int in_size = widthByte; + int out_size = (widthByte * 6 + 4) / 5; + int delta = bitmap->BytesPerRow(); + + DBGMSG(("width = %d\n", width)); + DBGMSG(("widthByte = %d\n", widthByte)); + DBGMSG(("height = %d\n", height)); + DBGMSG(("in_size = %d\n", in_size)); + DBGMSG(("out_size = %d\n", out_size)); + DBGMSG(("delta = %d\n", delta)); + DBGMSG(("renderobj->get_pixel_depth() = %d\n", __halftone->getPixelDepth())); + + uchar *ptr = (uchar *)bitmap->Bits() + + rc.top * delta + + (rc.left * __halftone->getPixelDepth()) / 8; + + int compression_method; + int compressed_size; + const uchar *buffer; + + uchar *in_buffer = new uchar[in_size]; + uchar *out_buffer = new uchar[out_size]; + + auto_ptr _in_buffer (in_buffer); + auto_ptr _out_buffer(out_buffer); + + DBGMSG(("move\n")); + + move(x, y); + startRasterGraphics(); + + for (int i = rc.top; i <= rc.bottom; i++) { + __halftone->dither(in_buffer, ptr, x, y, width); + + compressed_size = pack_bits(out_buffer, in_buffer, in_size); + + if (compressed_size < in_size) { + compression_method = 2; // back bits + buffer = out_buffer; + } else { + compression_method = 0; // uncompressed + buffer = in_buffer; + compressed_size = in_size; + } + + rasterGraphics( + compression_method, + buffer, + compressed_size); + + ptr += delta; + y++; + } + + endRasterGraphics(); + + } else { + DBGMSG(("band bitmap is clean.\n")); + } + + if (y >= page_height) { + offset->x = -1.0; + offset->y = -1.0; + } else { + offset->y += height; + } + + DBGMSG(("< nextBand\n")); + return true; + } + catch (TransportException &err) { + BAlert *alert = new BAlert("", err.what(), "OK"); + alert->Go(); + return false; + } +} + +void PCL5Driver::jobStart() +{ + // reset + writeSpoolString("\033E"); + // dpi + writeSpoolString("\033*t%dR", getJobData()->getXres()); + // unit of measure + writeSpoolString("\033&u%dD", getJobData()->getXres()); + // page size + writeSpoolString("\033&l0A"); + // page orientation + writeSpoolString("\033&l0O"); + // raster presentation + writeSpoolString("\033*r0F"); + // top maring and perforation skip + writeSpoolString("\033&l0e0L"); + // clear horizontal margins + writeSpoolString("\0339"); + // number of copies + // writeSpoolString("\033&l%ldL", getJobData()->getCopies()); +} + +void PCL5Driver::startRasterGraphics() +{ + writeSpoolString("\033*r1A"); + __compression_method = -1; +} + +void PCL5Driver::endRasterGraphics() +{ + writeSpoolString("\033*rB"); +} + +void PCL5Driver::rasterGraphics( + int compression_method, + const uchar *buffer, + int size) +{ + if (__compression_method != compression_method) { + writeSpoolString("\033*b%dM", compression_method); + __compression_method = compression_method; + } + writeSpoolString("\033*b%dW", size); + writeSpoolData(buffer, size); +} + +void PCL5Driver::jobEnd() +{ + writeSpoolString("\033&l1T"); + writeSpoolString("\033E"); +} + +void PCL5Driver::move(int x, int y) +{ + writeSpoolString("\033*p%dx%dY", x, y+75); +} diff --git a/src/add-ons/print/drivers/pcl5/PCL5.h b/src/add-ons/print/drivers/pcl5/PCL5.h new file mode 100644 index 0000000000..ff14a52e2c --- /dev/null +++ b/src/add-ons/print/drivers/pcl5/PCL5.h @@ -0,0 +1,39 @@ +/* + * PCL5.h + * Copyright 1999-2000 Y.Takagi. All Rights Reserved. + */ + +#ifndef __PCL5_H +#define __PCL5_H + +#include "GraphicsDriver.h" + +class Halftone; + +class PCL5Driver : public GraphicsDriver { +public: + PCL5Driver(BMessage *msg, PrinterData *printer_data, const PrinterCap *printer_cap); + +protected: + virtual bool startDoc(); + virtual bool startPage(int page); + virtual bool nextBand(BBitmap *bitmap, BPoint *offset); + virtual bool endPage(int page); + virtual bool endDoc(bool success); + +private: + void move(int x, int y); + void jobStart(); + void startRasterGraphics(); + void endRasterGraphics(); + void rasterGraphics( + int compression_method, + const uchar *buffer, + int size); + void jobEnd(); + + int __compression_method; + Halftone *__halftone; +}; + +#endif /* __PCL5_H */ diff --git a/src/add-ons/print/drivers/pcl5/PCL5.rsrc b/src/add-ons/print/drivers/pcl5/PCL5.rsrc new file mode 100644 index 0000000000000000000000000000000000000000..6635cc515b30aad061240eb899e507b558ffcde1 GIT binary patch literal 4161 zcmeHK&r4KM6h8g7SE(0#y~Xh0A<`;M6CouqolzNZoMA?!AdpE%9h!7f5senJXd?vE zu5ImF1i8swt2VA%wQJKRm_MM6*!SK0-n^$)f?>6o3vcc@=ljl&Irluro6U(xYdUcb zTY}Gdd>muZSK#~YjES*u%E&bDVbOjP@{<;kj|j~8Z!d_PHECoEa-eKof{c2&wl0gb z8&N(%eskJau$^R`%+iQ&dfn(lqYsT4Xv{!k297@i?A>2ly2xMU0_eK7?V4Y=11t>! zwXB~pL}G5tw(VxD!wjHYj#--FMzV+#bGZUaGcvf~`gMq-QJ>;CKI*{CpW!GBjzKjU z5eP@zeKR-2S4!hhs?|*mX?p-Fh^soza6XO(DMXI?169g4 z{TD$?2bnF5?^u=!r$j_qE@ISirK}L;9En)0&D3Yx5#M0Sn8oj_pEp2)U2u~8e)}T_ zD0ht6Z&1UC^8aHQZ(CR$UQ64;YiTSTIGj(jZ^0|e`EhJcv>Uz+W)k-R2cyZ+;karC zJqU_Ad>tH&X+Cs}lbI5Q2|-isL4Rs+K%On$Yv zw0L8^b8T_9t2|Tc>zrA7REF_Esi6O2@x%Y8U+bCpc%K(P%&C))5Dxfzb4$zKa3P)Z z`mFd;d1JXazp(1{^!N9B_qrzY5A*ZIi2Y`FcdwT!&Mf2$B`-5qD9+6lmaU;u$;;Aj z#mg2}3d?JS*{&n1_-Am%yJpo|)1vn~&#fBu7aPXLs&?9BckouzKF;0y*K18lsbp-~ zeYxJDG3vDQ#>w;H?X3;A3ij^_sW3-yi;LbW|MZr+Z8zzhLGB7_dU~;=ZtJ)zyJh76 zjE8kmeg)2;(@~>L99LvrJ9UA+1N`;-_7Io$+B5hvhvtKWUA}_%VY|IXAKGvCns}p` z%n)<&X_4WPbZ%fMlbIeJ9~#TmUx$fwJjs#fO|{jK#s_kfiRolKJrT0v$rM? +#include +#include + +#include "Exports.h" +#include "PCL5.h" +#include "PrinterData.h" +#include "PCL5Cap.h" +#include "UIDriver.h" +#include "AboutBox.h" +#include "DbgMsg.h" + +char *add_printer(char *printer_name) +{ + DBGMSG((">PCL5: add_printer\n")); + DBGMSG(("\tprinter_name: %s\n", printer_name)); + DBGMSG(("PCL5: config_page\n")); + DUMP_BMESSAGE(msg); + DUMP_BNODE(node); + + PrinterData printer_data(node); + PCL5Cap printer_cap(&printer_data); + UIDriver drv(msg, &printer_data, &printer_cap); + BMessage *result = drv.configPage(); + + DUMP_BMESSAGE(result); + DBGMSG(("PCL5: config_job\n")); + DUMP_BMESSAGE(msg); + DUMP_BNODE(node); + + PrinterData printer_data(node); + PCL5Cap printer_cap(&printer_data); + UIDriver drv(msg, &printer_data, &printer_cap); + BMessage *result = drv.configJob(); + + DUMP_BMESSAGE(result); + DBGMSG(("PCL5: take_job\n")); + DUMP_BMESSAGE(msg); + DUMP_BNODE(node); + + PrinterData printer_data(node); + PCL5Cap printer_cap(&printer_data); + PCL5Driver drv(msg, &printer_data, &printer_cap); + BMessage *result = drv.takeJob(spool); + +// DUMP_BMESSAGE(result); + DBGMSG(("A + size ... 1 Executive, 2 Letter, 3 Legal, 4 Ledge, 26 A4, 27 A3, etc ... + +Logical Page Size Command + Esc&lO + size ... 0 portrait, 1, landscape, 2 reverse portrait, 3 reverse landscape + +Clear Horizontal Margins Command + Esc9 resets margins to that of logical page + +Top Margin Command + Esc&lE + lines ... number of lines + +Unit of Measure + Esc&uD + +Horizontal Cursor Positioning (PCL Units) Command + Esc*pX (default 1/300 inch) + +Vertical Cursor Positioning (PCL Units) Command + Esc*pY (default 1/300 inch) + +Perforation Skip Command + Esc&lL + skip ... 0 disable, 1 enable + +Number of copies + Esc&lX + +Print Direction Command + ESC&aP degree ... 0, 90, 180, 270 + +Job Separation Command + Esc&l1T (before reset at end of job) + +Image Transfer + +Raster Presentation + Esc*rF + mode ... 0 in orientation of logical page + 3 raster image prints along the width + of the physical page +Raster Resolution + Esc*tR + dpi ... 75, 100, 150, 200, 300, 600 +Raster Height + Esc*rT + height ... 0 to logical page length - current Y position +Raster Width + Esc*rS + width ... in pixels of the specified resolution +Start Raster Graphics + Esc*r0A start at default left graphics margin (X position 0) + Esc*r1A start at current X position +{ + Y Offset + Esc*bY + lines ... number of raster lines of vertical movement + Raster Compression + Esc*bM + mode ... 0 unencoded + ... 1 run length encoding + ... 2 tagged image file format (TIFF) rev. 4.0 + ... 3 delta row compression + ... 4 reserved + ... 5 adaptie compression + {Transfer Raster Data + Esc*bW + length ... 0 to 32767 + } +} +End Raster Graphics + Esc*rC + Esc*rB (old) +