⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qprintengine_pdf.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
        QByteArray imageData;        bool hasAlpha = false;        bool hasMask = false;        if (QImageWriter::supportedImageFormats().contains("jpeg")) {            QBuffer buffer(&imageData);            QImageWriter writer(&buffer, "jpeg");            writer.setQuality(94);            writer.write(image);            dct = true;            if (format != QImage::Format_RGB32) {                softMaskData.resize(w * h);                uchar *sdata = (uchar *)softMaskData.data();                for (int y = 0; y < h; ++y) {                    const QRgb *rgb = (const QRgb *)image.scanLine(y);                    for (int x = 0; x < w; ++x) {                        uchar alpha = qAlpha(*rgb);                        *sdata++ = alpha;                        hasMask |= (alpha < 255);                        hasAlpha |= (alpha != 0 && alpha != 255);                        ++rgb;                    }                }            }        } else {            imageData.resize(3 * w * h);            uchar *data = (uchar *)imageData.data();            softMaskData.resize(w * h);            uchar *sdata = (uchar *)softMaskData.data();            for (int y = 0; y < h; ++y) {                const QRgb *rgb = (const QRgb *)image.scanLine(y);                for (int x = 0; x < w; ++x) {                    *(data++) = qRed(*rgb);                    *(data++) = qGreen(*rgb);                    *(data++) = qBlue(*rgb);                    uchar alpha = qAlpha(*rgb);                    *sdata++ = alpha;                    hasMask |= (alpha < 255);                    hasAlpha |= (alpha != 0 && alpha != 255);                    ++rgb;                }            }            if (format == QImage::Format_RGB32)                hasAlpha = hasMask = false;        }        int maskObject = 0;        int softMaskObject = 0;        if (hasAlpha) {            softMaskObject = writeImage(softMaskData, w, h, 8, 0, 0);        } else if (hasMask) {            // dither the soft mask to 1bit and add it. This also helps PDF viewers            // without transparency support            int bytesPerLine = (w + 7) >> 3;            QByteArray mask(bytesPerLine * h, 0);            uchar *mdata = (uchar *)mask.data();            const uchar *sdata = (const uchar *)softMaskData.constData();            for (int y = 0; y < h; ++y) {                for (int x = 0; x < w; ++x) {                    if (*sdata)                        mdata[x>>3] |= (0x80 >> (x&7));                    ++sdata;                }                mdata += bytesPerLine;            }            maskObject = writeImage(mask, w, h, 1, 0, 0);        }        object = writeImage(imageData, w, h, 32, maskObject, softMaskObject, dct);    }    imageCache.insert(serial_no, object);    return object;}QTransform QPdfEnginePrivate::pageMatrix() const{    qreal scale = 72./resolution;    QTransform tmp(scale, 0.0, 0.0, -scale, 0.0, height());    if (!fullPage) {        QRect r = pageRect();        tmp.translate(r.left(), r.top());    }    return tmp;}void QPdfEnginePrivate::newPage(){    writePage();    delete currentPage;    currentPage = new QPdfPage;    stroker.stream = currentPage;    pages.append(requestObject());    *currentPage << "/GSa gs /CSp cs /CSp CS\n"                 << QPdf::generateMatrix(pageMatrix())                 << "q q\n";}// For strings up to 10000 bytes only !void QPdfEnginePrivate::xprintf(const char* fmt, ...){    if (!stream)        return;    const int msize = 10000;    char buf[msize];    va_list args;    va_start(args, fmt);    int bufsize = qvsnprintf(buf, msize, fmt, args);    Q_ASSERT(bufsize<msize);    va_end(args);    stream->writeRawData(buf, bufsize);    streampos += bufsize;}int QPdfEnginePrivate::writeCompressed(const char *src, int len){#ifndef QT_NO_COMPRESS    if(do_compress) {        uLongf destLen = len + len/100 + 13; // zlib requirement        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: Error in compress()");            destLen = 0;        }        delete [] dest;        len = destLen;    } else#endif    {        stream->writeRawData(src,len);    }    streampos += len;    return len;}int QPdfEnginePrivate::writeImage(const QByteArray &data, int width, int height, int depth,                                  int maskObject, int softMaskObject, bool dct){    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");    int len = 0;    if (dct) {        //qDebug() << "DCT";        xprintf("/Filter /DCTDecode\n>>\nstream\n");        write(data);        len = data.length();    } else {        if (do_compress)            xprintf("/Filter /FlateDecode\n>>\nstream\n");        else            xprintf(">>\nstream\n");        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(){    tm *newtime;#if defined(Q_OS_WIN) && defined(_MSC_VER) && _MSC_VER >= 1400    __time32_t now;    _time32(&now);    tm buffer;    _gmtime32_s(&buffer, &now);    newtime = &buffer;#else    time_t now;    time(&now);    newtime = gmtime(&now);#endif    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[i]);    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.end(); ++it) {        embedFont(*it);        delete *it;    }    fonts.clear();}void QPdfEnginePrivate::writePage(){    if (pages.empty())        return;    *currentPage << "Q 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 + -