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

📄 qprintengine_ps.cpp

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
                written += size;            }            state = Undef;            start = i;            if (i == input.size())                break;        }        last = data[i];        ++i;    };    out.append((char)(uchar)128);    return out;}enum format {    Raw,    Runlength,    DCT};static const char *const filters[3] = {    " ",    "/RunLengthDecode filter ",    "/DCTDecode filter "};static QByteArray compress(const QImage &img, bool gray, int *format){    // we can't use premultiplied here    QImage image = img;    if (image.format() == QImage::Format_ARGB32_Premultiplied)        image = image.convertToFormat(QImage::Format_ARGB32);    QByteArray pixelData;    int depth = image.depth();    if (depth != 1 && !gray && QImageWriter::supportedImageFormats().contains("jpeg")) {        QBuffer buffer(&pixelData);        QImageWriter writer(&buffer, "jpeg");        writer.setQuality(94);        writer.write(img);        *format = DCT;    } else {        int width = image.width();        int height = image.height();        int size = width*height;        if (depth == 1)            size = (width+7)/8*height;        else if (!gray)            size = size*3;        pixelData.resize(size);        uchar *pixel = (uchar *)pixelData.data();        int i = 0;        if (depth == 1) {            QImage::Format format = image.format();            memset(pixel, 0xff, size);            for(int y=0; y < height; y++) {                const uchar * s = image.scanLine(y);                for(int x=0; x < width; x++) {                    // need to copy bit for bit...                    bool b = (format == QImage::Format_MonoLSB) ?                             (*(s + (x >> 3)) >> (x & 7)) & 1 :                             (*(s + (x >> 3)) << (x & 7)) & 0x80 ;                    if (b)                        pixel[i >> 3] ^= (0x80 >> (i & 7));                    i++;                }                // we need to align to 8 bit here                i = (i+7) & 0xffffff8;            }        } else if (depth == 8) {            for(int y=0; y < height; y++) {                const uchar * s = image.scanLine(y);                for(int x=0; x < width; x++) {                    QRgb rgb = image.color(s[x]);                    if (gray) {                        pixel[i] = (unsigned char) qGray(rgb);                        i++;                    } else {                        pixel[i] = (unsigned char) qRed(rgb);                        pixel[i+1] = (unsigned char) qGreen(rgb);                        pixel[i+2] = (unsigned char) qBlue(rgb);                        i += 3;                    }                }            }        } else {            for(int y=0; y < height; y++) {                QRgb * s = (QRgb*)(image.scanLine(y));                for(int x=0; x < width; x++) {                    QRgb rgb = (*s++);                    if (gray) {                        pixel[i] = (unsigned char) qGray(rgb);                        i++;                    } else {                        pixel[i] = (unsigned char) qRed(rgb);                        pixel[i+1] = (unsigned char) qGreen(rgb);                        pixel[i+2] = (unsigned char) qBlue(rgb);                        i += 3;                    }                }            }        }        *format = Raw;        if (depth == 1) {            pixelData = runlengthEncode(pixelData);            *format = Runlength;        }    }    QByteArray outarr = QPdf::ascii85Encode(pixelData);    return outarr;}void QPSPrintEnginePrivate::drawImage(qreal x, qreal y, qreal w, qreal h,                                      const QImage &img, const QImage &mask){    if (!w || !h || img.isNull()) return;    int width  = img.width();    int height = img.height();    qreal scaleX = width/w;    qreal scaleY = height/h;    bool gray = (colorMode == QPrinter::GrayScale) ||                img.allGray();    int splitSize = 21830 * (gray ? 3 : 1);    if (width * height > splitSize) { // 65535/3, tolerance for broken printers        int images, subheight;        images = (width * height + splitSize - 1) / splitSize;        subheight = (height + images-1) / images;        while (subheight * width > splitSize) {            images++;            subheight = (height + images-1) / images;        }        int suby = 0;        while(suby < height) {            drawImage(x, y + suby/scaleY, w, qMin(subheight, height-suby)/scaleY,                      img.copy(0, suby, width, qMin(subheight, height-suby)),                      mask.isNull() ? mask : mask.copy(0, suby, width, qMin(subheight, height-suby)));            suby += subheight;        }    } else {        QByteArray out;        int size = 0;        const char *bits;        if (!mask.isNull()) {            int format;            out = ::compress(mask, true, &format);            size = (width+7)/8*height;            *currentPage << "/mask currentfile/ASCII85Decode filter"                         << filters[format]                         << size << " string readstring\n";            ps_r7(*currentPage, out, out.size());            *currentPage << " pop def\n";        }        if (img.depth() == 1) {            size = (width+7)/8*height;            bits = "1 ";        } else if (gray) {            size = width*height;            bits = "8 ";        } else {            size = width*height*3;            bits = "24 ";        }        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);    outDevice = new QFile();    static_cast<QFile *>(outDevice)->open(fd, QIODevice::WriteOnly);    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();    uint mtop = pageRect.top() - paperRect.top();    uint mleft = pageRect.left() - paperRect.left();    uint mbottom = paperRect.bottom() - pageRect.bottom();    uint 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(".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-2003 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";    s << "%%BeginSetup\n";    if (copies > 1) {        s << "/#copies " << copies << " def\n";        s << "/NumCopies " << copies << " SPD\n";        s << "/Collate " << (collate ? "true" : "false") << " SPD\n";    }    s << "%%EndSetup\n";    outDevice->write(header);}void QPSPrintEnginePrivate::emitPages(){    // ############# fix fonts for huge documents    for (QHash<QFontEngine::FaceId, QFontSubset *>::Iterator it = fonts.begin(); it != fonts.end(); ++it)        outDevice->write((*it)->toType1());    outDevice->write(buffer);    buffer = QByteArray();    qDeleteAll(fonts);    fonts.clear();}#ifdef Q_WS_QWSconst int max_in_memory_size = 50000000;#elseconst int max_in_memory_size = 2000000;#endifvoid QPSPrintEnginePrivate::flushPage(bool last){    if (!last && currentPage->content().isEmpty())        return;    QPdf::ByteStream s(&buffer);    s << "%%Page: "      << pageCount << pageCount << "\n"      << "QI\n"      << currentPage->content()      << "\nQP\n";    if (last) { // ############## || buffer.size() > max_in_memory_size) {//        qDebug("emiting header at page %d", pageCount);        if (!outDevice)            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){    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;    }}QPSPrintEngine::~QPSPrintEngine(){    Q_D(QPSPrintEngine);    if (d->fd >= 0)        ::close(d->fd);}static 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    while(--i > 0)	::close(i);}bool QPSPrintEngine::begin(QPaintDevice *pdev){    Q_D(QPSPrintEngine);    if (d->fd >= 0)        return true;    d->pdev = pdev;    if (!d->outputFileName.isEmpty()) {        d->fd = QT_OPEN(d->outputFileName.toLocal8Bit().constData(), O_CREAT | O_NOCTTY | O_TRUNC | O_WRONLY,#if defined(Q_OS_WIN)            _S_IREAD | _S_IWRITE#else            0666#endif           );    } else {        QString pr;        if (!d->printerName.isEmpty())            pr = d->printerName;        int fds[2];        if (pipe(fds) != 0) {            qWarning("QPSPrinter: could not open pipe to print");            return false;        }        d->pid = fork();        if (d->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 (!d->printProgram.isEmpty()) {                if (!d->selectionOption.isEmpty())                    pr.prepend(d->selectionOption);                else

⌨️ 快捷键说明

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