📄 qprintengine_qws.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file. Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include <private/qprintengine_qws_p.h>#ifndef QT_NO_PRINTER#include <private/qpaintengine_raster_p.h>#include <qimage.h>#include <qfile.h>#include <qdebug.h>#include <QCopChannel>#define MM(n) int((n * 720 + 127) / 254)#define IN(n) int(n * 72)struct PaperSize { int width, height;};static const PaperSize paperSizes[QPrinter::NPageSize] ={ { MM(210), MM(297) }, // A4 { MM(176), MM(250) }, // B5 { IN(8.5), IN(11) }, // Letter { IN(8.5), IN(14) }, // Legal { IN(7.5), IN(10) }, // Executive { MM(841), MM(1189) }, // A0 { MM(594), MM(841) }, // A1 { MM(420), MM(594) }, // A2 { MM(297), MM(420) }, // A3 { MM(148), MM(210) }, // A5 { MM(105), MM(148) }, // A6 { MM(74), MM(105)}, // A7 { MM(52), MM(74) }, // A8 { MM(37), MM(52) }, // A9 { MM(1000), MM(1414) }, // B0 { MM(707), MM(1000) }, // B1 { MM(31), MM(44) }, // B10 { MM(500), MM(707) }, // B2 { MM(353), MM(500) }, // B3 { MM(250), MM(353) }, // B4 { MM(125), MM(176) }, // B6 { MM(88), MM(125) }, // B7 { MM(62), MM(88) }, // B8 { MM(44), MM(62) }, // B9 { MM(162), MM(229) }, // C5E { IN(4.125), IN(9.5) }, // Comm10E { MM(110), MM(220) }, // DLE { IN(8.5), IN(13) }, // Folio { IN(17), IN(11) }, // Ledger { IN(11), IN(17) } // Tabloid};QtopiaPrintEngine::QtopiaPrintEngine(QPrinter::PrinterMode mode) : QPaintEngine(*(new QtopiaPrintEnginePrivate( mode ))){ d_func()->initialize();}bool QtopiaPrintEngine::begin(QPaintDevice *){ Q_D(QtopiaPrintEngine); d->paintEngine->state = state; Q_ASSERT_X(d->printerState == QPrinter::Idle, "QtopiaPrintEngine", "printer already active"); // Create a new off-screen monochrome image to handle the drawing process. QSize size = paperRect().size(); if ( d->pageImage ) delete d->pageImage; d->pageImage = new QImage( size, QImage::Format_RGB32 ); if ( !(d->pageImage) ) return false; // Begin the paint process on the image. if (!d->paintEngine->begin(d->pageImage)) return false; // Clear the first page to all-white. clearPage(); // Clear the print buffer and output the image header. d->buffer.clear(); d->writeG3FaxHeader(); // The print engine is currently active. d->printerState = QPrinter::Active; return true;}bool QtopiaPrintEngine::end(){ Q_D(QtopiaPrintEngine); d->paintEngine->end(); // Flush the last page. flushPage(); // Output the fax data to a file (TODO: send to the print queuing daemon). QString filename; if ( !d->outputFileName.isEmpty() ) filename = QString(::getenv("HOME")) + "/Documents/" + d->outputFileName; else filename = QString(::getenv("HOME")) + "/tmp/" + "qwsfax.tiff"; setProperty(QPrintEngine::PPK_OutputFileName, filename); QFile file( filename ); if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) { qDebug( "Failed to open %s for printer output", filename.toLatin1().constData() ); } else { file.write( d->buffer.data() ); file.close(); } // Free up the memory for the image buffer. d->buffer.clear(); // Finalize the print job. d->printerState = QPrinter::Idle; // call qcop service QMap<QString, QVariant> map; for ( int x = 0; x <= QPrintEngine::PPK_Duplex; x++ ) map.insert( QString::number(x), property((QPrintEngine::PrintEnginePropertyKey)(x))); QVariant variant(map); QByteArray data; QDataStream out(&data, QIODevice::WriteOnly); out << variant; QCopChannel::send("QPE/Service/Print", "print(QVariant)", data); return true;}QPaintEngine *QtopiaPrintEngine::paintEngine() const{ return d_func()->paintEngine;}void QtopiaPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr){ Q_D(QtopiaPrintEngine); Q_ASSERT(d->printerState == QPrinter::Active); d->paintEngine->drawPixmap(r, pm, sr);}void QtopiaPrintEngine::drawTextItem(const QPointF &p, const QTextItem &ti){ Q_D(QtopiaPrintEngine); Q_ASSERT(d->printerState == QPrinter::Active); d->paintEngine->drawTextItem(p, ti);}void QtopiaPrintEngine::updateState(const QPaintEngineState &state){ Q_D(QtopiaPrintEngine); d->paintEngine->updateState(state);}QRect QtopiaPrintEngine::paperRect() const{ PaperSize s = paperSizes[d_func()->pageSize]; int w = qRound(s.width*d_func()->resolution/72.); int h = qRound(s.height*d_func()->resolution/72.); if (d_func()->orientation == QPrinter::Portrait) return QRect(0, 0, w, h); else return QRect(0, 0, h, w);}QRect QtopiaPrintEngine::pageRect() const{ QRect r = paperRect(); if (d_func()->fullPage) return r; // would be nice to get better margins than this. return QRect(d_func()->resolution/3, d_func()->resolution/3, r.width()-2*d_func()->resolution/3, r.height()-2*d_func()->resolution/3);}bool QtopiaPrintEngine::newPage(){ flushPage(); clearPage(); ++(d_func()->pageNumber); return true;}bool QtopiaPrintEngine::abort(){ return false;}QPrinter::PrinterState QtopiaPrintEngine::printerState() const{ return d_func()->printerState;}int QtopiaPrintEngine::metric(QPaintDevice::PaintDeviceMetric metricType) const{ int val; QRect r = d_func()->fullPage ? paperRect() : pageRect(); switch (metricType) { case QPaintDevice::PdmWidth: val = r.width(); break; case QPaintDevice::PdmHeight: val = r.height(); break; case QPaintDevice::PdmDpiX: val = d_func()->resolution; break; case QPaintDevice::PdmDpiY: val = d_func()->resolution; break; case QPaintDevice::PdmPhysicalDpiX: case QPaintDevice::PdmPhysicalDpiY: val = QT_QWS_PRINTER_DEFAULT_DPI; break; case QPaintDevice::PdmWidthMM: val = qRound(r.width()*25.4/d_func()->resolution); break; case QPaintDevice::PdmHeightMM: val = qRound(r.height()*25.4/d_func()->resolution); break; case QPaintDevice::PdmNumColors: val = 2; break; case QPaintDevice::PdmDepth: val = 1; break; default: qWarning("QtopiaPrintEngine::metric: Invalid metric command"); return 0; } return val;}QVariant QtopiaPrintEngine::property(PrintEnginePropertyKey key) const{ Q_D(const QtopiaPrintEngine); QVariant ret; switch (key) { case PPK_CollateCopies: ret = d->collateCopies; break; case PPK_ColorMode: ret = d->colorMode; break; case PPK_Creator: ret = d->creator; break; case PPK_DocumentName: ret = d->docName; break; case PPK_FullPage: ret = d->fullPage; break; case PPK_NumberOfCopies: ret = d->numCopies; break; case PPK_Orientation: ret = d->orientation; break; case PPK_OutputFileName: ret = d->outputFileName; break; case PPK_PageOrder: ret = d->pageOrder; break; case PPK_PageRect: ret = pageRect(); break; case PPK_PageSize: ret = d->pageSize; break; case PPK_PaperRect: ret = paperRect(); break; case PPK_PaperSource: ret = d->paperSource; break; case PPK_PrinterName: ret = d->printerName; break; case PPK_PrinterProgram: ret = d->printProgram; break; case PPK_Resolution: ret = d->resolution; break; case PPK_SupportedResolutions: ret = QList<QVariant>() << QT_QWS_PRINTER_DEFAULT_DPI; break; default: break; } return ret;}void QtopiaPrintEngine::setProperty(PrintEnginePropertyKey key, const QVariant &value){ Q_D(QtopiaPrintEngine); switch (key) { case PPK_CollateCopies: d->collateCopies = value.toBool(); break; case PPK_ColorMode: d->colorMode = QPrinter::ColorMode(value.toInt()); break; case PPK_Creator: d->creator = value.toString(); break; case PPK_DocumentName: d->docName = value.toString(); break; case PPK_FullPage: d->fullPage = value.toBool(); break; case PPK_NumberOfCopies: d->numCopies = value.toInt(); break; case PPK_Orientation: d->orientation = QPrinter::Orientation(value.toInt()); break; case PPK_OutputFileName: d->outputFileName = value.toString(); break; case PPK_PageOrder: d->pageOrder = QPrinter::PageOrder(value.toInt()); break; case PPK_PageSize: d->pageSize = QPrinter::PageSize(value.toInt()); break; case PPK_PaperSource: d->paperSource = QPrinter::PaperSource(value.toInt()); case PPK_PrinterName: d->printerName = value.toString(); break; case PPK_PrinterProgram: d->printProgram = value.toString(); break; case PPK_Resolution: d->resolution = value.toInt(); break; default: break; }}void QtopiaPrintEngine::clearPage(){ d_func()->pageImage->fill(QColor(255, 255, 255).rgb());}void QtopiaPrintEngine::flushPage(){ d_func()->writeG3FaxPage();}QtopiaPrintEnginePrivate::~QtopiaPrintEnginePrivate(){ if ( pageImage ) delete pageImage;}void QtopiaPrintEnginePrivate::initialize(){ paintEngine = new QRasterPaintEngine();}void QtopiaPrintEnginePrivate::writeG3FaxHeader(){ // Write the TIFF file magic number (little-endian TIFF). buffer.append( (char)'I' ); buffer.append( (char)'I' ); buffer.append( (char)42 ); buffer.append( (char)0 ); // Leave a place-holder for the IFD offset of the first page. ifdPatch = buffer.size(); buffer.append( (int)0 );}// Tag values, from RFC 2301.#define TIFF_IFD_NEW_SUB_FILE_TYPE 254#define TIFF_IFD_IMAGE_WIDTH 256#define TIFF_IFD_IMAGE_LENGTH 257#define TIFF_IFD_BITS_PER_SAMPLE 258#define TIFF_IFD_COMPRESSION 259#define TIFF_IFD_PHOTOMETRIC_INTERP 262#define TIFF_IFD_FILL_ORDER 266#define TIFF_IFD_STRIP_OFFSETS 273#define TIFF_IFD_ORIENTATION 274#define TIFF_IFD_SAMPLES_PER_PIXEL 277#define TIFF_IFD_ROWS_PER_STRIP 278#define TIFF_IFD_STRIP_BYTE_COUNTS 279#define TIFF_IFD_X_RESOLUTION 282#define TIFF_IFD_Y_RESOLUTION 283#define TIFF_IFD_PLANAR_CONFIG 284#define TIFF_IFD_T4_OPTIONS 292#define TIFF_IFD_RESOLUTION_UNIT 296#define TIFF_IFD_PAGE_NUMBER 297#define TIFF_IFD_CLEAN_FAX_DATA 327// IFD type values.#define TIFF_TYPE_SHORT 3#define TIFF_TYPE_LONG 4#define TIFF_TYPE_RATIONAL 5// Construct a SHORT pair from two values.#define TIFF_SHORT_PAIR(a,b) (((a) & 0xFFFF) | ((b) << 16))// Width of a FAX page in pixels, in the baseline specification from RFC 2301.// This must be hard-wired, as per the RFC. We truncate any pixels that
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -