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

📄 qprintengine_pdf.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
    QRect r = d->fullPage ? paperRect() : pageRect();    switch (metricType) {    case QPaintDevice::PdmWidth:        val = r.width();        break;    case QPaintDevice::PdmHeight:        val = r.height();        break;    case QPaintDevice::PdmDpiX:    case QPaintDevice::PdmDpiY:        val = d->resolution;        break;    case QPaintDevice::PdmPhysicalDpiX:    case QPaintDevice::PdmPhysicalDpiY:        val = 1200;        break;    case QPaintDevice::PdmWidthMM:        val = qRound(r.width()*25.4/d->resolution);        break;    case QPaintDevice::PdmHeightMM:        val = qRound(r.height()*25.4/d->resolution);        break;    case QPaintDevice::PdmNumColors:        val = INT_MAX;        break;    case QPaintDevice::PdmDepth:        val = 32;        break;    default:        qWarning("QPdfEngine::metric: Invalid metric command");        return 0;    }    return val;}QPaintEngine::Type QPdfEngine::type() const{    return QPaintEngine::User;}bool QPdfEngine::newPage(){    Q_D(QPdfEngine);    if (!isActive())        return false;    d->newPage();    return true;}QPdfEnginePrivate::QPdfEnginePrivate(){    width_ = 0;    height_ = 0;    streampos = 0;    stream = new QDataStream;    pageOrder = QPrinter::FirstPageFirst;    orientation = QPrinter::Portrait;    fullPage = false;}QPdfEnginePrivate::~QPdfEnginePrivate(){    delete stream;}#ifdef USE_NATIVE_GRADIENTSint QPdfEnginePrivate::gradientBrush(const QBrush &b, const QMatrix &matrix, int *gStateObject){    const QGradient *gradient = b.gradient();    if (!gradient)        return 0;    QMatrix inv = matrix.inverted();    QPointF page_rect[4] = { inv.map(QPointF(0, 0)),                             inv.map(QPointF(width_, 0)),                             inv.map(QPointF(0, height_)),                             inv.map(QPointF(width_, height_)) };    bool opaque = b.isOpaque();    QByteArray shader;    QByteArray alphaShader;    if (gradient->type() == QGradient::LinearGradient) {        const QLinearGradient *lg = static_cast<const QLinearGradient *>(gradient);        shader = QPdf::generateLinearGradientShader(lg, page_rect);        if (!opaque)            alphaShader = QPdf::generateLinearGradientShader(lg, page_rect, true);    } else {        // #############        return 0;    }    int shaderObject = addXrefEntry(-1);    write(shader);    QByteArray str;    QPdf::ByteStream s(&str);    s << "<<\n"        "/Type /Pattern\n"        "/PatternType 2\n"        "/Shading " << shaderObject << "0 R\n"        "/Matrix ["      << matrix.m11()      << matrix.m12()      << matrix.m21()      << matrix.m22()      << matrix.dx()      << matrix.dy() << "]\n";    s << ">>\n"        "endobj\n";    int patternObj = addXrefEntry(-1);    write(str);    currentPage->patterns.append(patternObj);    if (!opaque) {        bool ca = true;        QGradientStops stops = gradient->stops();        int a = stops.at(0).second.alpha();        for (int i = 1; i < stops.size(); ++i) {            if (stops.at(i).second.alpha() != a) {                ca = false;                break;            }        }        if (ca) {            *gStateObject = addXrefEntry(-1);            xprintf("<< /ca %f >>\n"                    "endobj\n", stops.at(0).second.alphaF());        } else {            int alphaShaderObject = addXrefEntry(-1);            write(alphaShader);            QByteArray content;            QPdf::ByteStream c(&content);            c << "/Shader" << alphaShaderObject << "sh\n";            QByteArray form;            QPdf::ByteStream f(&form);            f << "<<\n"                "/Type /XObject\n"                "/Subtype /Form\n"                "/BBox [0 0 " << width_ << height_ << "]\n"                "/Group <</S /Transparency >>\n"                "/Resources <<\n"                "/Shading << /Shader" << alphaShaderObject << alphaShaderObject << "0 R >>\n"                ">>\n";            f << "/Length " << content.length() << "\n"                ">>\n"                "stream\n"              << content              << "endstream\n"                "endobj\n";            int softMaskFormObject = addXrefEntry(-1);            write(form);            *gStateObject = addXrefEntry(-1);            xprintf("<< /SMask << /S /Alpha /G %d 0 R >> >>\n"                    "endobj\n", softMaskFormObject);        }        currentPage->graphicStates.append(*gStateObject);    }    return patternObj;}#endifint QPdfEnginePrivate::addBrushPattern(const QMatrix &m, bool *specifyColor, int *gStateObject){    int paintType = 2; // Uncolored tiling    int w = 8;    int h = 8;    *specifyColor = true;    *gStateObject = 0;    QMatrix matrix = m;    matrix.translate(brushOrigin.x(), brushOrigin.y());    matrix = matrix * pageMatrix();    //qDebug() << brushOrigin << matrix;    Qt::BrushStyle style = brush.style();    if (style == Qt::LinearGradientPattern) {// && style <= Qt::ConicalGradientPattern) {#ifdef USE_NATIVE_GRADIENTS        *specifyColor = false;        return gradientBrush(b, matrix, gStateObject);#else        return 0;#endif    }    if (!brush.isOpaque() && brush.style() < Qt::LinearGradientPattern) {        QByteArray brushDef;        QPdf::ByteStream s(&brushDef);        s << "<<";        QColor rgba = brush.color();        s << "/ca " << rgba.alphaF();        s << ">>\n";        *gStateObject = addXrefEntry(-1);        xprintf(brushDef.constData());        xprintf("endobj\n");        currentPage->graphicStates.append(*gStateObject);    }    int imageObject = 0;    QByteArray pattern = QPdf::patternForBrush(brush);    if (pattern.isEmpty()) {        if (brush.style() != Qt::TexturePattern)            return 0;        QImage image = brush.texture().toImage();        bool bitmap = true;        imageObject = addImage(image, &bitmap, qt_pixmap_id(brush.texture()));        QImage::Format f = image.format();        if (f != QImage::Format_MonoLSB && f != QImage::Format_Mono) {            paintType = 1; // Colored tiling            *specifyColor = false;        }        w = image.width();        h = image.height();        QMatrix m(w, 0, 0, -h, 0, h);        QPdf::ByteStream s(&pattern);        s << QPdf::generateMatrix(m);        s << "/Im" << imageObject << " Do\n";    }    QByteArray str;    QPdf::ByteStream s(&str);    s << "<<\n"        "/Type /Pattern\n"        "/PatternType 1\n"        "/PaintType " << paintType << "\n"        "/TilingType 1\n"        "/BBox [0 0 " << w << h << "]\n"        "/XStep " << w << "\n"        "/YStep " << h << "\n"        "/Matrix ["      << matrix.m11()      << matrix.m12()      << matrix.m21()      << matrix.m22()      << matrix.dx()      << matrix.dy() << "]\n"        "/Resources \n<< "; // open resource tree    if (imageObject) {        s << "/XObject << /Im" << imageObject << ' ' << imageObject << "0 R >> ";    }    s << ">>\n"        "/Length " << pattern.length() << "\n"        ">>\n"        "stream\n"      << pattern      << "endstream\n"        "endobj\n";    int patternObj = addXrefEntry(-1);    write(str);    currentPage->patterns.append(patternObj);    return patternObj;}int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_no){    if (img.isNull())        return -1;    int object = imageCache.value(serial_no);    if(object)        return object;    QImage image = img;    QImage::Format format = image.format();    if (image.depth() == 1 && *bitmap) {        if (format == QImage::Format_MonoLSB)            image = image.convertToFormat(QImage::Format_Mono);    } else {        *bitmap = false;        if (format != QImage::Format_RGB32 && format != QImage::Format_ARGB32)            image = image.convertToFormat(QImage::Format_ARGB32);    }    int w = image.width();    int h = image.height();    int d = image.depth();    if (d == 1) {        int bytesPerLine = (w + 7) >> 3;        QByteArray data;        data.resize(bytesPerLine * h);        char *rawdata = data.data();        for (int y = 0; y < h; ++y) {            memcpy(rawdata, image.scanLine(y), bytesPerLine);            rawdata += bytesPerLine;        }        object = writeImage(data, w, h, d, 0, 0);    } else {        QByteArray imageData;        QByteArray softMaskData;        imageData.resize(3 * w * h);        softMaskData.resize(w * h);        uchar *data = (uchar *)imageData.data();        uchar *sdata = (uchar *)softMaskData.data();        bool hasAlpha = false;        bool hasMask = false;        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;            }        }        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);    }    imageCache.insert(serial_no, object);    return object;}QMatrix QPdfEnginePrivate::pageMatrix() const{    qreal scale = 72./resolution;    QMatrix tmp(scale, 0.0, 0.0, -scale, 0.0, height_);    if (!fullPage)        tmp.translate(resolution/3, resolution/3);    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\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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -