📄 qprintengine_ps.cpp
字号:
int format; out = ::compress(img, gray, &format); *currentPage << "/sl currentfile/ASCII85Decode filter" << filters[format] << size << " string readstring\n"; ps_r7(*currentPage, out, out.size()); *currentPage << " pop def\n"; *currentPage << width << ' ' << height << "[" << scaleX << " 0 0 " << scaleY << " 0 0]sl " << bits << (!mask.isNull() ? "mask " : "false ") << x << ' ' << y << " di\n"; }}void QPSPrintEnginePrivate::emitHeader(bool finished){ QPSPrintEngine *q = static_cast<QPSPrintEngine *>(q_ptr); QPrinter *printer = static_cast<QPrinter*>(pdev); if (creator.isEmpty()) creator = QLatin1String("Qt " QT_VERSION_STR); QByteArray header; QPdf::ByteStream s(&header); s << "%!PS-Adobe-1.0"; qreal scale = 72. / ((qreal) q->metric(QPaintDevice::PdmDpiY)); QRect pageRect = this->pageRect(); QRect paperRect = this->paperRect(); int mtop = pageRect.top() - paperRect.top(); int mleft = pageRect.left() - paperRect.left(); int mbottom = paperRect.bottom() - pageRect.bottom(); int mright = paperRect.right() - pageRect.right(); int width = pageRect.width(); int height = pageRect.height(); if (finished && pageCount == 1 && copies == 1 && ((fullPage && qt_gen_epsf) || (outputFileName.endsWith(QLatin1String(".eps")))) ) { if (!boundingBox.isValid()) boundingBox.setRect(0, 0, width, height); if (orientation == QPrinter::Landscape) { if (!fullPage) boundingBox.translate(-mleft, -mtop); s << " EPSF-3.0\n%%BoundingBox: " << (int)(printer->height() - boundingBox.bottom())*scale // llx << (int)(printer->width() - boundingBox.right())*scale - 1 // lly << (int)(printer->height() - boundingBox.top())*scale + 1 // urx << (int)(printer->width() - boundingBox.left())*scale; // ury } else { if (!fullPage) boundingBox.translate(mleft, -mtop); s << " EPSF-3.0\n%%BoundingBox: " << (int)(boundingBox.left())*scale << (int)(printer->height() - boundingBox.bottom())*scale - 1 << (int)(boundingBox.right())*scale + 1 << (int)(printer->height() - boundingBox.top())*scale; } } else { int w = width + (fullPage ? 0 : mleft + mright); int h = height + (fullPage ? 0 : mtop + mbottom); w = (int)(w*scale); h = (int)(h*scale); // set a bounding box according to the DSC if (orientation == QPrinter::Landscape) s << "\n%%BoundingBox: 0 0 " << h << w; else s << "\n%%BoundingBox: 0 0 " << w << h; } s << "\n" << wrapDSC("%%Creator: " + creator.toUtf8()); if (!title.isEmpty()) s << wrapDSC("%%Title: " + title.toUtf8());#ifndef QT_NO_DATESTRING s << "%%CreationDate: " << QDateTime::currentDateTime().toString().toUtf8();#endif s << "\n%%Orientation: "; if (orientation == QPrinter::Landscape) s << "Landscape"; else s << "Portrait"; s << "\n%%Pages: (atend)" "\n%%DocumentFonts: (atend)" "\n%%EndComments\n" "%%BeginProlog\n" "% Prolog copyright 1994-2006 Trolltech. You may copy this prolog in any way\n" "% that is directly related to this document. For other use of this prolog,\n" "% see your licensing agreement for Qt.\n" << ps_header << "\n"; s << "/pageinit {\n"; if (!fullPage) { if (orientation == QPrinter::Portrait) s << mleft*scale << mbottom*scale << "translate\n"; else s << mtop*scale << mleft*scale << "translate\n"; } if (orientation == QPrinter::Portrait) { s << "% " << printer->widthMM() << "*" << printer->heightMM() << "mm (portrait)\n0 " << height*scale << "translate " << scale << "-" << scale << "scale } def\n"; } else { s << "% " << printer->heightMM() << "*" << printer->widthMM() << " mm (landscape)\n 90 rotate " << scale << "-" << scale << "scale } def\n"; } s << "%%EndProlog\n"; outDevice->write(header); headerDone = true;}void QPSPrintEnginePrivate::emitPages(){ if (!hugeDocument) { for (QHash<QFontEngine::FaceId, QFontSubset *>::const_iterator it = fonts.constBegin(); it != fonts.constEnd(); ++it) outDevice->write((*it)->toType1()); } outDevice->write(buffer); buffer = QByteArray(); hugeDocument = true;}#ifdef Q_WS_QWSstatic const int max_in_memory_size = 2000000;#elsestatic const int max_in_memory_size = 32000000;#endifvoid QPSPrintEnginePrivate::flushPage(bool last){ if (!last && currentPage->content().isEmpty()) return; QPdf::ByteStream s(&buffer); s << "%%Page: " << pageCount << pageCount << "\n" << "%%BeginPageSetup\n" << "QI\n"; if (hugeDocument) { for (QHash<QFontEngine::FaceId, QFontSubset *>::const_iterator it = fonts.constBegin(); it != fonts.constEnd(); ++it) { if (currentPage->fonts.contains((*it)->object_id)) { if ((*it)->downloaded_glyphs == 0) { s << (*it)->toType1(); (*it)->downloaded_glyphs = 0; } else { s << (*it)->type1AddedGlyphs(); } } } } for (int i = 0; i < currentPage->fonts.size(); ++i) s << "(F" << QByteArray::number(currentPage->fonts.at(i)) << ") T1Setup\n"; s << "%%EndPageSetup\nq\n" << currentPage->content() << "\nQ QP\n"; if (last || hugeDocument || buffer.size() > max_in_memory_size) {// qDebug("emiting header at page %d", pageCount); if (!headerDone) emitHeader(last); emitPages(); } pageCount++;}// ================ PSPrinter class ========================QPSPrintEngine::QPSPrintEngine(QPrinter::PrinterMode m) : QPdfBaseEngine(*(new QPSPrintEnginePrivate(m)), PrimitiveTransform | PatternTransform | PixmapTransform | PainterPaths | PatternBrush ){}static void ignoreSigPipe(bool b){#ifndef QT_NO_LPR static struct sigaction *users_sigpipe_handler = 0; if (b) { if (users_sigpipe_handler != 0) return; // already ignoring sigpipe users_sigpipe_handler = new struct sigaction; struct sigaction tmp_sigpipe_handler; tmp_sigpipe_handler.sa_handler = SIG_IGN; sigemptyset(&tmp_sigpipe_handler.sa_mask); tmp_sigpipe_handler.sa_flags = 0; if (sigaction(SIGPIPE, &tmp_sigpipe_handler, users_sigpipe_handler) == -1) { delete users_sigpipe_handler; users_sigpipe_handler = 0; } } else { if (users_sigpipe_handler == 0) return; // not ignoring sigpipe if (sigaction(SIGPIPE, users_sigpipe_handler, 0) == -1) qWarning("QPSPrintEngine: Could not restore SIGPIPE handler"); delete users_sigpipe_handler; users_sigpipe_handler = 0; }#else Q_UNUSED(b);#endif}QPSPrintEngine::~QPSPrintEngine(){ Q_D(QPSPrintEngine); if (d->fd >= 0)#if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400 ::_close(d->fd);#else ::close(d->fd);#endif}bool QPSPrintEngine::begin(QPaintDevice *pdev){ Q_D(QPSPrintEngine); if (d->fd >= 0) return true; if(!QPdfBaseEngine::begin(pdev)) return false; d->pageCount = 1; // initialize state d->pen = QPen(Qt::black); d->brush = Qt::NoBrush; d->hasPen = true; d->hasBrush = false; d->clipEnabled = false; d->allClipped = false; d->boundingBox = QRect(); d->fontsUsed = ""; d->hugeDocument = false; setActive(true); d->printerState = QPrinter::Active; newPage(); return true;}bool QPSPrintEngine::end(){ Q_D(QPSPrintEngine); // we're writing to lp/lpr through a pipe, we don't want to crash with SIGPIPE // if lp/lpr dies ignoreSigPipe(true); d->flushPage(true); QByteArray trailer; QPdf::ByteStream s(&trailer); s << "%%Trailer\n"; s << "%%Pages: " << d->pageCount - 1 << "\n" << wrapDSC("%%DocumentFonts: " + d->fontsUsed); s << "%%EOF\n"; d->outDevice->write(trailer); QPdfBaseEngine::end(); ignoreSigPipe(false); d->firstPage = true; d->headerDone = false; setActive(false); d->printerState = QPrinter::Idle; d->pdev = 0; return true;}void QPSPrintEngine::setBrush(){ Q_D(QPSPrintEngine);#if 0 bool specifyColor; int gStateObject = 0; int patternObject = d->addBrushPattern(brush, d->stroker.matrix, brushOrigin, &specifyColor, &gStateObject); *d->currentPage << (patternObject ? "/PCSp cs " : "/CSp cs "); if (specifyColor) { QColor rgba = brush.color(); *d->currentPage << rgba.redF() << rgba.greenF() << rgba.blueF(); } if (patternObject) *d->currentPage << "/Pat" << patternObject; *d->currentPage << "scn\n";#endif QColor rgba = d->brush.color(); *d->currentPage << rgba.redF() << rgba.greenF() << rgba.blueF() << "scn\n"; *d->currentPage << "/BSt " << d->brush.style() << "def\n";}void QPSPrintEngine::drawImageInternal(const QRectF &r, QImage image, bool bitmap){ Q_D(QPSPrintEngine); if (d->clipEnabled && d->allClipped) return; if (bitmap && image.depth() != 1) bitmap = false; QImage mask; if (!bitmap) { if (image.format() == QImage::Format_Mono || image.format() == QImage::Format_MonoLSB) image = image.convertToFormat(QImage::Format_Indexed8); if (image.hasAlphaChannel()) { // get better alpha dithering int xscale = image.width(); xscale *= xscale <= 800 ? 4 : (xscale <= 1600 ? 2 : 1); int yscale = image.height(); yscale *= yscale <= 800 ? 4 : (yscale <= 1600 ? 2 : 1); image = image.scaled(xscale, yscale); mask = image.createAlphaMask(Qt::OrderedAlphaDither); } } *d->currentPage << "q\n"; if(!d->simplePen) *d->currentPage << QPdf::generateMatrix(d->stroker.matrix); QBrush b = d->brush; if (image.depth() == 1) { // set current pen as brush d->brush = d->pen.brush(); setBrush(); } d->drawImage(r.x(), r.y(), r.width(), r.height(), image, mask); *d->currentPage << "Q\n"; d->brush = b;}void QPSPrintEngine::drawImage(const QRectF &r, const QImage &img, const QRectF &sr, Qt::ImageConversionFlags){ QImage image = img.copy(sr.toRect()); drawImageInternal(r, image, false);}void QPSPrintEngine::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr){ QImage img = pm.copy(sr.toRect()).toImage(); drawImageInternal(r, img, true);}void QPSPrintEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &p){ Q_D(QPSPrintEngine); if (d->clipEnabled && d->allClipped) return; // ### Optimise implementation! qreal yPos = r.y(); qreal yOff = p.y(); while(yPos < r.y() + r.height()) { qreal drawH = pixmap.height() - yOff; // Cropping first row if (yPos + drawH > r.y() + r.height()) // Cropping last row drawH = r.y() + r.height() - yPos; qreal xPos = r.x(); qreal xOff = p.x(); while(xPos < r.x() + r.width()) { qreal drawW = pixmap.width() - xOff; // Cropping first column if (xPos + drawW > r.x() + r.width()) // Cropping last column drawW = r.x() + r.width() - xPos; // ######## painter()->drawPixmap(QPointF(xPos, yPos).toPoint(), pixmap, QRectF(xOff, yOff, drawW, drawH).toRect()); xPos += drawW; xOff = 0; } yPos += drawH; yOff = 0; }}bool QPSPrintEngine::newPage(){ Q_D(QPSPrintEngine); // we're writing to lp/lpr through a pipe, we don't want to crash with SIGPIPE // if lp/lpr dies ignoreSigPipe(true); if (!d->firstPage) d->flushPage(); d->firstPage = false; ignoreSigPipe(false); delete d->currentPage; d->currentPage = new QPdfPage; d->stroker.stream = d->currentPage; return QPdfBaseEngine::newPage();}bool QPSPrintEngine::abort(){ // ### abort!?! return false;}QPrinter::PrinterState QPSPrintEngine::printerState() const{ Q_D(const QPSPrintEngine); return d->printerState;}#endif // QT_NO_PRINTER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -