📄 qpdf.cpp
字号:
return ret;}QPdfBaseEnginePrivate::QPdfBaseEnginePrivate(QPrinter::PrinterMode m) : clipEnabled(false), allClipped(false), hasPen(true), hasBrush(false), simplePen(false), outDevice(0), fd(-1), duplex(false), collate(false), fullPage(false), embedFonts(true), copies(1), pageOrder(QPrinter::FirstPageFirst), orientation(QPrinter::Portrait), pageSize(QPrinter::A4), colorMode(QPrinter::Color), paperSource(QPrinter::Auto){ resolution = 72; if (m == QPrinter::HighResolution) resolution = 1200; else if (m == QPrinter::ScreenResolution) resolution = qt_defaultDpi(); postscript = false; currentObject = 1; currentPage = 0; stroker.stream = 0;}bool QPdfBaseEngine::begin(QPaintDevice *pdev){ Q_D(QPdfBaseEngine); d->pdev = pdev; d->postscript = false; d->currentObject = 1; d->currentPage = new QPdfPage; d->stroker.stream = d->currentPage; return d->openPrintDevice();}bool QPdfBaseEngine::end(){ Q_D(QPdfBaseEngine); qDeleteAll(d->fonts); d->fonts.clear(); delete d->currentPage; d->currentPage = 0; d->closePrintDevice(); return true;}#ifndef QT_NO_LPRstatic void closeAllOpenFds(){ // hack time... getting the maximum number of open // files, if possible. if not we assume it's the // larger of 256 and the fd we got int i;#if defined(_SC_OPEN_MAX) i = (int)sysconf(_SC_OPEN_MAX);#elif defined(_POSIX_OPEN_MAX) i = (int)_POSIX_OPEN_MAX;#elif defined(OPEN_MAX) i = (int)OPEN_MAX;#else i = 256;#endif // leave stdin/out/err untouched while(--i > 2) ::close(i);}#endifbool QPdfBaseEnginePrivate::openPrintDevice(){ if(outDevice) return false; if (!outputFileName.isEmpty()) { QFile *file = new QFile(outputFileName); outDevice = file; file->open(QFile::WriteOnly|QFile::Truncate);#ifndef QT_NO_LPR } else { QString pr; if (!printerName.isEmpty()) pr = printerName; int fds[2]; if (pipe(fds) != 0) { qWarning("QPSPrinter: Could not open pipe to print"); return false; } pid_t pid = fork(); if (pid == 0) { // child process // if possible, exit quickly, so the actual lp/lpr // becomes a child of init, and ::waitpid() is // guaranteed not to wait. if (fork() > 0) { closeAllOpenFds(); // try to replace this process with "true" - this prevents // global destructors from being called (that could possibly // do wrong things to the parent process) (void)execlp("true", "true", (char *)0); (void)execl("/bin/true", "true", (char *)0); (void)execl("/usr/bin/true", "true", (char *)0); ::exit(0); } dup2(fds[0], 0); closeAllOpenFds(); if (!printProgram.isEmpty()) { if (!selectionOption.isEmpty()) pr.prepend(selectionOption); else pr.prepend(QLatin1String("-P")); (void)execlp(printProgram.toLocal8Bit().data(), printProgram.toLocal8Bit().data(), pr.toLocal8Bit().data(), (char *)0);#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) } else if (QCUPSSupport::isAvailable()) { QList<QByteArray> cupsArgList; cupsArgList << "lpr"; if (!printerName.isEmpty()) { cupsArgList << "-P"; cupsArgList << printerName.toLocal8Bit(); } if (!cupsStringPageSize.isEmpty()) { cupsArgList << "-o"; cupsArgList << QByteArray("media=") + cupsStringPageSize.toLocal8Bit(); } if (copies > 1) { cupsArgList << "-#"; cupsArgList << QByteArray::number(copies); } if (collate) { cupsArgList << "-o"; cupsArgList << "Collate=True"; } if (duplex) { cupsArgList << "-o"; if (orientation == QPrinter::Portrait) cupsArgList << "sides=two-sided-long-edge"; else cupsArgList << "sides=two-sided-short-edge"; } if (QCUPSSupport::cupsVersion() >= 10200 && orientation == QPrinter::Landscape) { cupsArgList << "-o"; cupsArgList << "landscape"; } if (!title.isEmpty()) { cupsArgList << "-J"; cupsArgList << title.toLocal8Bit(); } QStringList::const_iterator it = cupsOptions.constBegin(); while (it != cupsOptions.constEnd()) { cupsArgList << "-o"; cupsArgList << (*it).toLocal8Bit() + "=" + (*(it+1)).toLocal8Bit(); it += 2; } char** lprargs = new char*[cupsArgList.count() + 1]; int i; for (i = 0; i < cupsArgList.count(); ++i) { lprargs[i] = cupsArgList[i].data(); } lprargs[i] = 0; // if the CUPS is available we expect lpr around (void)execvp( "lpr", lprargs ); (void)execv( "/bin/lpr", lprargs); (void)execv( "/usr/bin/lpr", lprargs);#endif } else { // if no print program has been specified, be smart // about the option string too. QList<QByteArray> lprhack; QList<QByteArray> lphack; QByteArray media; if (!pr.isEmpty() || !selectionOption.isEmpty()) { if (!selectionOption.isEmpty()) { QStringList list = selectionOption.split(QLatin1Char(' ')); for (int i = 0; i < list.size(); ++i) lprhack.append(list.at(i).toLocal8Bit()); lphack = lprhack; } else { lprhack.append("-P"); lphack.append("-d"); } lprhack.append(pr.toLocal8Bit()); lphack.append(pr.toLocal8Bit()); } char ** lpargs = new char *[lphack.size()+6]; lpargs[0] = "lp"; int i; for (i = 0; i < lphack.size(); ++i) lpargs[i+1] = (char *)lphack.at(i).constData();#ifndef Q_OS_OSF if (QPdf::paperSizeToString(pageSize)) { lpargs[++i] = "-o"; lpargs[++i] = (char *)QPdf::paperSizeToString(pageSize); lpargs[++i] = "-o"; media = "media="; media += QPdf::paperSizeToString(pageSize); lpargs[++i] = (char *)media.constData(); }#endif lpargs[++i] = 0; char **lprargs = new char *[lprhack.size()+2]; lprargs[0] = "lpr"; for (int i = 0; i < lprhack.size(); ++i) lprargs[i+1] = (char *)lprhack[i].constData(); lprargs[lprhack.size() + 1] = 0; (void)execvp("lp", lpargs); (void)execvp("lpr", lprargs); (void)execv("/bin/lp", lpargs); (void)execv("/bin/lpr", lprargs); (void)execv("/usr/bin/lp", lpargs); (void)execv("/usr/bin/lpr", lprargs); } // if we couldn't exec anything, close the fd, // wait for a second so the parent process (the // child of the GUI process) has exited. then // exit. ::close(0); (void)::sleep(1); ::exit(0); } // parent process ::close(fds[0]); fd = fds[1]; (void)::waitpid(pid, 0, 0); if (fd < 0) return false; outDevice = new QFile(); static_cast<QFile *>(outDevice)->open(fd, QIODevice::WriteOnly);#endif } return true;}void QPdfBaseEnginePrivate::closePrintDevice(){ if (!outDevice) return; outDevice->close(); if (fd >= 0)#if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400 ::_close(fd);#else ::close(fd);#endif fd = -1; delete outDevice; outDevice = 0;}QPdfBaseEnginePrivate::~QPdfBaseEnginePrivate(){ qDeleteAll(fonts); delete currentPage;}void QPdfBaseEnginePrivate::drawTextItem(const QPointF &p, const QTextItemInt &ti){ Q_Q(QPdfBaseEngine); QFontEngine *fe = ti.fontEngine; QFontEngine::FaceId face_id = fe->faceId(); bool noEmbed = false; if (face_id.filename.isEmpty() || (!postscript && ((fe->fsType & 0x200) /* bitmap embedding only */ || (fe->fsType == 2) /* no embedding allowed */))) { *currentPage << "Q\n"; q->QPaintEngine::drawTextItem(p, ti); *currentPage << "q\n"; if (face_id.filename.isEmpty()) return; noEmbed = true; } QFontSubset *font = fonts.value(face_id, 0); if (!font) { font = new QFontSubset(fe, requestObject()); font->noEmbed = noEmbed; } fonts.insert(face_id, font); if (!currentPage->fonts.contains(font->object_id)) currentPage->fonts.append(font->object_id); qreal size;#ifdef Q_WS_WIN size = ti.fontEngine->tm.w.tmHeight;#else size = ti.fontEngine->fontDef.pixelSize;#endif QVarLengthArray<glyph_t> glyphs; QVarLengthArray<QFixedPoint> positions; QTransform m; m.translate(p.x(), p.y()); ti.fontEngine->getGlyphPositions(ti.glyphs, ti.num_glyphs, m, ti.flags, glyphs, positions); if (glyphs.size() == 0) return; int synthesized = ti.fontEngine->synthesized(); qreal stretch = synthesized & QFontEngine::SynthesizedStretch ? ti.fontEngine->fontDef.stretch/100. : 1.; *currentPage << "BT\n" << "/F" << font->object_id << size << "Tf " << stretch << (synthesized & QFontEngine::SynthesizedItalic ? "0 .3 -1 0 0 Tm\n" : "0 0 -1 0 0 Tm\n");#if 0 // #### implement actual text for complex languages const unsigned short *logClusters = ti.logClusters; int pos = 0; do { int end = pos + 1; while (end < ti.num_chars && logClusters[end] == logClusters[pos]) ++end; *currentPage << "/Span << /ActualText <FEFF"; for (int i = pos; i < end; ++i) { s << toHex((ushort)ti.chars[i].unicode(), buf); } *currentPage << "> >>\n" "BDC\n" "<"; int ge = end == ti.num_chars ? ti.num_glyphs : logClusters[end]; for (int gs = logClusters[pos]; gs < ge; ++gs) *currentPage << toHex((ushort)ti.glyphs[gs].glyph, buf); *currentPage << "> Tj\n" "EMC\n"; pos = end; } while (pos < ti.num_chars);#else qreal last_x = 0.; qreal last_y = 0.; for (int i = 0; i < glyphs.size(); ++i) { qreal x = positions[i].x.toReal(); qreal y = positions[i].y.toReal(); if (synthesized & QFontEngine::SynthesizedItalic) x += .3*y; x /= stretch; char buf[5]; int g = font->addGlyph(glyphs[i]); *currentPage << x - last_x << last_y - y << "Td <" << QPdf::toHex((ushort)g, buf) << "> Tj\n"; last_x = x; last_y = y; } if (synthesized & QFontEngine::SynthesizedBold) { *currentPage << stretch << (synthesized & QFontEngine::SynthesizedItalic ? "0 .3 -1 0 0 Tm\n" : "0 0 -1 0 0 Tm\n"); *currentPage << "/Span << /ActualText <> >> BDC\n"; last_x = 0.5*fe->lineThickness().toReal(); last_y = 0.; for (int i = 0; i < glyphs.size(); ++i) { qreal x = positions[i].x.toReal(); qreal y = positions[i].y.toReal(); if (synthesized & QFontEngine::SynthesizedItalic) x += .3*y; x /= stretch; char buf[5]; int g = font->addGlyph(glyphs[i]); *currentPage << x - last_x << last_y - y << "Td <" << QPdf::toHex((ushort)g, buf) << "> Tj\n"; last_x = x; last_y = y; } *currentPage << "EMC\n"; }#endif *currentPage << "ET\n";}QRect QPdfBaseEnginePrivate::paperRect() const{ int w; int h;#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) if (QCUPSSupport::isAvailable() && !cupsPaperRect.isNull()) { QRect r = cupsPaperRect; w = r.width(); h = r.height(); } else#endif { QPdf::PaperSize s = QPdf::paperSize(pageSize); w = s.width; h = s.height; } w = qRound(w*resolution/72.); h = qRound(h*resolution/72.); if (orientation == QPrinter::Portrait) return QRect(0, 0, w, h); else return QRect(0, 0, h, w);}QRect QPdfBaseEnginePrivate::pageRect() const{ if(fullPage) return paperRect(); QRect r;#if !defined(QT_NO_CUPS) && !defined(QT_NO_LIBRARY) if (QCUPSSupport::isAvailable() && !cupsPageRect.isNull()) { r = cupsPageRect; if (r == cupsPaperRect) // if cups doesn't define any margins, give it at least approx 3.5 mm r = QRect(10, 10, r.width() - 20, r.height() - 20); } else#endif { QPdf::PaperSize s = QPdf::paperSize(pageSize); r = QRect(72/3, 72/3, s.width - 2*72/3, s.height - 2*72/3); } int x = qRound(r.left()*resolution/72.); int y = qRound(r.top()*resolution/72.); int w = qRound(r.width()*resolution/72.); int h = qRound(r.height()*resolution/72.); if (orientation == QPrinter::Portrait) return QRect(x, y, w, h); else return QRect(y, x, h, w);}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -