📄 qprintengine_pdf.cpp
字号:
Bytef* dest = new Bytef[destLen]; if (Z_OK == ::compress(dest, &destLen, (const Bytef*) src, (uLongf)len)) { stream->writeRawData((const char*)dest, destLen); } else { qWarning("QPdfStream::writeCompressed(): compress error"); destLen = 0; } delete [] dest; len = destLen; } else#endif { stream->writeRawData(src,len); } streampos += len; return len;}void QPdfEnginePrivate::setDevice(QIODevice* device){ stream->setDevice(device); streampos = 0;}void QPdfEnginePrivate::unsetDevice(){ stream->unsetDevice();}int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height, int depth, int maskObject, int softMaskObject){ int image = addXrefEntry(-1); xprintf("<<\n" "/Type /XObject\n" "/Subtype /Image\n" "/Width %d\n" "/Height %d\n", width, height); if (depth == 1) { xprintf("/ImageMask true\n" "/Decode [1 0]\n"); } else { xprintf("/BitsPerComponent 8\n" "/ColorSpace %s\n", (depth == 32) ? "/DeviceRGB" : "/DeviceGray"); } if (maskObject > 0) xprintf("/Mask %d 0 R\n", maskObject); if (softMaskObject > 0) xprintf("/SMask %d 0 R\n", softMaskObject); int lenobj = requestObject(); xprintf("/Length %d 0 R\n", lenobj); if (interpolateImages) xprintf("/Interpolate true\n"); if (do_compress) xprintf("/Filter /FlateDecode\n"); xprintf(">>\nstream\n"); int len = writeCompressed(data); xprintf("endstream\n" "endobj\n"); addXrefEntry(lenobj); xprintf("%d\n" "endobj\n", len); return image;}void QPdfEnginePrivate::writeHeader(){ addXrefEntry(0,false); xprintf("%%PDF-1.4\n"); writeInfo(); catalog = addXrefEntry(-1); pageRoot = requestObject(); xprintf("<<\n" "/Type /Catalog\n" "/Pages %d 0 R\n" ">>\n" "endobj\n", pageRoot); // graphics state graphicsState = addXrefEntry(-1); xprintf("<<\n" "/Type /ExtGState\n" "/SA true\n" "/SM 0.02\n" "/ca 1.0\n" "/CA 1.0\n" "/AIS false\n" "/SMask /None" ">>\n" "endobj\n"); // color space for pattern patternColorSpace = addXrefEntry(-1); xprintf("[/Pattern /DeviceRGB]\n" "endobj\n");}void QPdfEnginePrivate::writeInfo(){ time_t now; tm *newtime; time(&now); newtime = gmtime(&now); QByteArray y; if (newtime && newtime->tm_year+1900 > 1992) y += QByteArray::number(newtime->tm_year+1900); info = addXrefEntry(-1); xprintf("<<\n" "/Title (%s)\n" "/Author (%s)\n" "/Creator (%s)\n" "/Producer (Qt %s (C) 1992-%s Trolltech ASA)\n", title.toUtf8().constData(), author.toUtf8().constData(), creator.toUtf8().constData(), qVersion(), y.constData()); if (newtime) { xprintf("/CreationDate (D:%d%02d%02d%02d%02d%02d)\n", newtime->tm_year+1900, newtime->tm_mon+1, newtime->tm_mday, newtime->tm_hour, newtime->tm_min, newtime->tm_sec); } xprintf(">>\n" "endobj\n");}void QPdfEnginePrivate::writePageRoot(){ addXrefEntry(pageRoot); xprintf("<<\n" "/Type /Pages\n" "/Kids \n" "[\n"); int size = pages.size(); for (int i = 0; i < size; ++i) xprintf("%d 0 R\n", pages[pageOrder == QPrinter::FirstPageFirst ? i : size-i-1]); xprintf("]\n"); //xprintf("/Group <</S /Transparency /I true /K false>>\n"); xprintf("/Count %d\n" "/MediaBox [%d %d %d %d]\n", pages.size(), 0, 0, width_, height_); xprintf("/ProcSet [/PDF /Text /ImageB /ImageC]\n" ">>\n" "endobj\n");}void QPdfEnginePrivate::embedFont(QFontSubset *font){ //qDebug() << "embedFont" << font->object_id; int fontObject = font->object_id; QByteArray fontData = font->toTruetype();#ifdef FONT_DUMP static int i = 0; QString fileName("font%1.ttf"); fileName = fileName.arg(i++); QFile ff(fileName); ff.open(QFile::WriteOnly); ff.write(fontData); ff.close();#endif int fontDescriptor = requestObject(); int fontstream = requestObject(); int cidfont = requestObject(); int toUnicode = requestObject(); QFontEngine::Properties properties = font->fontEngine->properties(); { qreal scale = 1000/properties.emSquare.toReal(); addXrefEntry(fontDescriptor); QByteArray descriptor; QPdf::ByteStream s(&descriptor); s << "<< /Type /FontDescriptor\n" "/FontName /Q"; int tag = fontDescriptor; for (int i = 0; i < 5; ++i) { s << (char)('A' + (tag % 26)); tag /= 26; } s << "+" << properties.postscriptName << "\n" "/Flags " << 4 << "\n" "/FontBBox [" << properties.boundingBox.x()*scale << -(properties.boundingBox.y() + properties.boundingBox.height())*scale << (properties.boundingBox.x() + properties.boundingBox.width())*scale << -properties.boundingBox.y()*scale << "]\n" "/ItalicAngle " << properties.italicAngle.toReal() << "\n" "/Ascent " << properties.ascent.toReal()*scale << "\n" "/Descent -" << properties.descent.toReal()*scale << "\n" "/CapHeight " << properties.capHeight.toReal()*scale << "\n" "/StemV " << properties.lineWidth.toReal()*scale << "\n" "/FontFile2 " << fontstream << "0 R\n" ">> endobj\n"; write(descriptor); } { addXrefEntry(fontstream); QByteArray header; QPdf::ByteStream s(&header); int length_object = requestObject(); s << "<<\n" "/Length1 " << fontData.size() << "\n" "/Length " << length_object << "0 R\n"; if (do_compress) s << "/Filter /FlateDecode\n"; s << ">>\n" "stream\n"; write(header); int len = writeCompressed(fontData); write("endstream\n" "endobj\n"); addXrefEntry(length_object); xprintf("%d\n" "endobj\n", len); } { addXrefEntry(cidfont); QByteArray cid; QPdf::ByteStream s(&cid); s << "<< /Type /Font\n" "/Subtype /CIDFontType2\n" "/BaseFont /" << properties.postscriptName << "\n" "/CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>\n" "/FontDescriptor " << fontDescriptor << "0 R\n" "/CIDToGIDMap /Identity\n" << font->widthArray() << ">>\n" "endobj\n"; write(cid); } { addXrefEntry(toUnicode); QByteArray touc = font->createToUnicodeMap(); xprintf("<< /Length %d >>\n" "stream\n", touc.length()); write(touc); write("endstream\n" "endobj\n"); } { addXrefEntry(fontObject); QByteArray font; QPdf::ByteStream s(&font); s << "<< /Type /Font\n" "/Subtype /Type0\n" "/BaseFont /" << properties.postscriptName << "\n" "/Encoding /Identity-H\n" "/DescendantFonts [" << cidfont << "0 R]\n" "/ToUnicode " << toUnicode << "0 R" ">>\n" "endobj\n"; write(font); }}void QPdfEnginePrivate::writeFonts(){ for (QHash<QFontEngine::FaceId, QFontSubset *>::iterator it = fonts.begin(); it != fonts.constEnd(); ++it) { embedFont(*it); delete *it; } fonts.clear();}void QPdfEnginePrivate::writePage(){ if (pages.empty()) return; *currentPage << "Q\n"; uint pageStream = requestObject(); uint pageStreamLength = requestObject(); uint resources = requestObject(); addXrefEntry(pages.last()); xprintf("<<\n" "/Type /Page\n" "/Parent %d 0 R\n" "/Contents %d 0 R\n" "/Resources %d 0 R\n" ">>\n" "endobj\n", pageRoot, pageStream, resources); addXrefEntry(resources); xprintf("<<\n" "/ColorSpace <<\n" "/PCSp %d 0 R\n" "/CSp /DeviceRGB\n" "/CSpg /DeviceGray\n" ">>\n" "/ExtGState <<\n" "/GSa %d 0 R\n", patternColorSpace, graphicsState); for (int i = 0; i < currentPage->graphicStates.size(); ++i) xprintf("/GState%d %d 0 R\n", currentPage->graphicStates.at(i), currentPage->graphicStates.at(i)); xprintf(">>\n"); xprintf("/Pattern <<\n"); for (int i = 0; i < currentPage->patterns.size(); ++i) xprintf("/Pat%d %d 0 R\n", currentPage->patterns.at(i), currentPage->patterns.at(i)); xprintf(">>\n"); xprintf("/Font <<\n"); for (int i = 0; i < currentPage->fonts.size();++i) xprintf("/F%d %d 0 R\n", currentPage->fonts[i], currentPage->fonts[i]); xprintf(">>\n"); xprintf("/XObject <<\n"); for (int i = 0; i<currentPage->images.size(); ++i) { xprintf("/Im%d %d 0 R\n", currentPage->images.at(i), currentPage->images.at(i)); } xprintf(">>\n"); xprintf(">>\n" "endobj\n"); addXrefEntry(pageStream); xprintf("<<\n" "/Length %d 0 R\n", pageStreamLength); // object number for stream length object if (do_compress) xprintf("/Filter /FlateDecode\n"); xprintf(">>\n"); xprintf("stream\n"); QByteArray content = currentPage->content(); int len = writeCompressed(content); xprintf("endstream\n" "endobj\n"); addXrefEntry(pageStreamLength); xprintf("%d\nendobj\n",len);}void QPdfEnginePrivate::writeTail(){ writePage(); writeFonts(); writePageRoot(); addXrefEntry(xrefPositions.size(),false); xprintf("xref\n" "0 %d\n" "%010d 65535 f \n", xrefPositions.size()-1, xrefPositions[0]); for (int i = 1; i < xrefPositions.size()-1; ++i) xprintf("%010d 00000 n \n", xrefPositions[i]); xprintf("trailer\n" "<<\n" "/Size %d\n" "/Info %d 0 R\n" "/Root %d 0 R\n" ">>\n" "startxref\n%d\n" "%%%%EOF\n", xrefPositions.size()-1, info, catalog, xrefPositions.last());}int QPdfEnginePrivate::addXrefEntry(int object, bool printostr){ if (object < 0) object = requestObject(); if (object>=xrefPositions.size()) xrefPositions.resize(object+1); xrefPositions[object] = streampos; if (printostr) xprintf("%d 0 obj\n",object); return object;}#endif // QT_NO_PRINTER
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -