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

📄 qprintengine_ps.cpp

📁 奇趣公司比较新的qt/emd版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** Copyright (C) 1992-2007 Trolltech ASA. All rights reserved.**** This file is part of the QtGui module of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://trolltech.com/products/qt/licenses/licensing/opensource/**** If you are unsure which license is appropriate for your use, please** review the following information:** http://trolltech.com/products/qt/licenses/licensing/licensingoverview** or contact the sales department at sales@trolltech.com.**** In addition, as a special exception, Trolltech gives you certain** additional rights. These rights are described in the Trolltech GPL** Exception version 1.0, which can be found at** http://www.trolltech.com/products/qt/gplexception/ and in the file** GPL_EXCEPTION.txt in this package.**** In addition, as a special exception, Trolltech, as the sole copyright** holder for Qt Designer, grants users of the Qt/Eclipse Integration** plug-in the right for the Qt/Eclipse Integration to link to** functionality provided by Qt Designer and its related libraries.**** Trolltech reserves all rights not expressly granted herein.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "qplatformdefs.h"#include <private/qprintengine_ps_p.h>#include <private/qpainter_p.h>#include <private/qfontengine_p.h>#include <private/qpaintengine_p.h>#include <private/qpdf_p.h>#ifndef QT_NO_PRINTER#include "qprinter.h"#include "qpainter.h"#include "qapplication.h"#include "qpixmap.h"#include "qimage.h"#include "qdatetime.h"#include "qstring.h"#include "qbytearray.h"#include "qhash.h"#include "qbuffer.h"#include "qsettings.h"#include "qmap.h"#include "qbitmap.h"#include "qregion.h"#include "qimagewriter.h"#include <private/qunicodetables_p.h>#include <private/qpainterpath_p.h>#include <qdebug.h>#include <private/qdrawhelper_p.h>#ifndef Q_OS_WIN#include <unistd.h>#endif#include <stdlib.h>#include <limits.h>static bool qt_gen_epsf = false;void qt_generate_epsf(bool b){    qt_gen_epsf = b;}static const char *const ps_header ="/BD{bind def}bind def/d2{dup dup}BD/ED{exch def}BD/D0{0 ED}BD/F{setfont}BD\n""/RL{rlineto}BD/CM{currentmatrix}BD/SM{setmatrix}BD/TR{translate}BD/SD\n""{setdash}BD/SC{aload pop setrgbcolor}BD/CR{currentfile read pop}BD/i{index}\n""BD/scs{setcolorspace}BD/DB{dict dup begin}BD/DE{end def}BD/ie{ifelse}BD/gs\n""{gsave}BD/gr{grestore}BD/w{setlinewidth}BD/d{setdash}BD/J{setlinecap}BD/j\n""{setlinejoin}BD/scn{3 array astore/BCol exch def}BD/SCN{3 array astore/PCol\n""exch def}BD/cm{6 array astore concat}BD/m{moveto}BD/l{lineto}BD/c{curveto}BD\n""/h{closepath}BD/W{clip}BD/W*{eoclip}BD/n{newpath}BD/q{gsave 10 dict begin}BD\n""/Q{end grestore}BD/re{4 2 roll m dup 0 exch RL exch 0 RL 0 exch neg RL h}BD\n""/S{gs PCol SC stroke gr n}BD/BT{gsave 10 dict begin/_m matrix CM def BCol\n""SC}BD/ET{end grestore}BD/Tf{/_fs ED findfont[_fs 0 0 _fs 0 0]makefont F}BD\n""/Tm{6 array astore concat}BD/Td{translate}BD/Tj{0 0 m show}BD/BDC{pop pop}BD\n""/EMC{}BD/BSt 0 def/WFi false def/BCol[1 1 1]def/PCol[0 0 0]def/BDArr[0.94\n""0.88 0.63 0.50 0.37 0.12 0.06]def/level3{/languagelevel where{pop\n""languagelevel 3 ge}{false}ie}BD/QCIgray D0/QCIcolor D0/QCIindex D0/QCI{\n""/colorimage where{pop false 3 colorimage}{exec/QCIcolor ED/QCIgray QCIcolor\n""length 3 idiv string def 0 1 QCIcolor length 3 idiv 1 sub{/QCIindex ED/_x\n""QCIindex 3 mul def QCIgray QCIindex QCIcolor _x get 0.30 mul QCIcolor _x 1\n""add get 0.59 mul QCIcolor _x 2 add get 0.11 mul add add cvi put}for QCIgray\n""image}ie}BD/di{gs TR 1 i 1 eq{pop pop false 3 1 roll BCol SC imagemask}{dup\n""false ne{level3}{false}ie{/_ma ED 8 eq{/_dc[0 1]def/DeviceGray}{/_dc[0 1 0 1\n""0 1]def/DeviceRGB}ie scs/_im ED/_mt ED/_h ED/_w ED <</ImageType 3/DataDict\n""<</ImageType 1/Width _w/Height _h/ImageMatrix _mt/DataSource _im\n""/BitsPerComponent 8/Decode _dc >>/MaskDict <</ImageType 1/Width _w/Height _h\n""/ImageMatrix _mt/DataSource _ma/BitsPerComponent 1/Decode[0 1]>>\n""/InterleaveType 3 >> image}{pop 8 4 1 roll 8 eq{image}{QCI}ie}ie}ie gr}BD/BF\n""{gs BSt 1 eq{BCol SC WFi{fill}{eofill}ie}if BSt 2 ge BSt 8 le and{BDArr BSt\n""2 sub get/_sc ED BCol{1. exch sub _sc mul 1. exch sub}forall 3 array astore\n""SC WFi{fill}{eofill}ie}if BSt 9 ge BSt 14 le and{WFi{W}{W*}ie pathbbox 3 i 3\n""i TR 4 2 roll 3 2 roll exch sub/_h ED sub/_w ED BCol SC 0.3 w n BSt 9 eq BSt\n""11 eq or{0 4 _h{dup 0 exch m _w exch l}for}if BSt 10 eq BSt 11 eq or{0 4 _w{\n""dup 0 m _h l}for}if BSt 12 eq BSt 14 eq or{_w _h gt{0 6 _w _h add{dup 0 m _h\n""sub _h l}for}{0 6 _w _h add{dup 0 exch m _w sub _w exch l}for}ie}if BSt 13\n""eq BSt 14 eq or{_w _h gt{0 6 _w _h add{dup _h m _h sub 0 l}for}{0 6 _w _h\n""add{dup _w exch m _w sub 0 exch l}for}ie}if stroke}if BSt 15 eq{}if BSt 24\n""eq{}if gr}BD/f{/WFi true def BF n}BD/f*{/WFi false def BF n}BD/B{/WFi true\n""def BF S n}BD/B*{/WFi false def BF S n}BD/QI{/C save def pageinit q n}BD/QP{\n""Q C restore showpage}BD/SPD{/setpagedevice where{<< 3 1 roll >>\n""setpagedevice}{pop pop}ie}BD/T1AddMapping{10 dict begin/glyphs ED/fnt ED\n""/current fnt/NumGlyphs get def/CMap fnt/CMap get def 0 1 glyphs length 1 sub\n""{glyphs exch get/gn ED current dup 256 mod/min ED 256 idiv/maj ED CMap dup\n""maj get dup null eq{pop 256 array 0 1 255{1 i exch/.notdef put}for}if dup\n""min gn put maj exch put/current current 1 add def}for fnt/CMap CMap put fnt\n""/NumGlyphs current put end}def/T1AddGlyphs{10 dict begin/glyphs ED/fnt ED\n""/current fnt/NumGlyphs get def/CMap fnt/CMap get def/CharStrings fnt\n""/CharStrings get def 0 1 glyphs length 2 idiv 1 sub{2 mul dup glyphs exch\n""get/gn ED 1 add glyphs exch get/cs ED current dup 256 mod/min ED 256 idiv\n""/maj ED CMap dup maj get dup null eq{pop 256 array 0 1 255{1 i exch/.notdef\n""put}for}if dup min gn put maj exch put CharStrings gn cs put/current current\n""1 add def}for fnt/CharStrings CharStrings put fnt/CMap CMap put fnt\n""/NumGlyphs current put end}def/StringAdd{1 i length 1 i length add string 3\n""1 roll 2 i 0 3 i putinterval 2 i 2 i length 2 i putinterval pop pop}def\n""/T1Setup{10 dict begin dup/FontName ED (-Base) StringAdd cvx cvn/Font ED\n""/MaxPage Font/NumGlyphs get 1 sub 256 idiv def/FDepVector MaxPage 1 add\n""array def/Encoding MaxPage 1 add array def 0 1 MaxPage{dup Encoding exch dup\n""put dup/Page ED FontName (-) StringAdd exch 20 string cvs StringAdd cvn Font\n""0 dict copy d2/CMap get Page get/Encoding exch put definefont FDepVector\n""exch Page exch put}for FontName cvn <</FontType 0/FMapType 2/FontMatrix[1 0\n""0 1 0 0]/Encoding Encoding/FDepVector FDepVector >> definefont pop end}def\n";// ------------------------------End of static data ----------------------------------// make sure DSC comments are not longer than 255 chars per line.static QByteArray wrapDSC(const QByteArray &str){    QByteArray dsc = str.simplified();    const int wrapAt = 254;    QByteArray wrapped;    if (dsc.length() < wrapAt)        wrapped = dsc;    else {        wrapped = dsc.left(wrapAt);        QByteArray tmp = dsc.mid(wrapAt);        while (tmp.length() > wrapAt-3) {            wrapped += "\n%%+" + tmp.left(wrapAt-3);            tmp = tmp.mid(wrapAt-3);        }        wrapped += "\n%%+" + tmp;    }    return wrapped + "\n";}// ----------------------------- Internal class declarations -----------------------------QPSPrintEnginePrivate::QPSPrintEnginePrivate(QPrinter::PrinterMode m)    : QPdfBaseEnginePrivate(m),      printerState(QPrinter::Idle), hugeDocument(false), headerDone(false){    postscript = true;    firstPage = true;#ifndef QT_NO_SETTINGS    QSettings settings(QSettings::UserScope, QLatin1String("Trolltech"));    settings.beginGroup(QLatin1String("Qt"));    embedFonts = settings.value(QLatin1String("embedFonts"), true).toBool();#else    embedFonts = true;#endif}QPSPrintEnginePrivate::~QPSPrintEnginePrivate(){}#include <qdebug.h>static void ps_r7(QPdf::ByteStream& stream, const char * s, int l){    int i = 0;    uchar line[84];    int col = 0;    while(i < l) {        line[col++] = s[i++];        if (i < l - 1 && col >= 76) {            line[col++] = '\n';            line[col++] = '\0';            stream << (const char *)line;            col = 0;        }    }    if (col > 0) {        while((col&3) != 0)            line[col++] = '%'; // use a comment as padding        line[col++] = '\n';        line[col++] = '\0';        stream << (const char *)line;    }}static QByteArray runlengthEncode(const QByteArray &input){    if (!input.length())        return input;    const char *data = input.constData();    QByteArray out;    int start = 0;    char last = *data;    enum State {        Undef,        Equal,        Diff    };    State state = Undef;    int i = 1;    int written = 0;    while (1) {        bool flush = (i == input.size());        if (!flush) {            switch(state) {            case Undef:                state = (last == data[i]) ? Equal : Diff;                break;            case Equal:                if (data[i] != last)                    flush = true;                break;            case Diff:                if (data[i] == last) {                    --i;                    flush = true;                }            }        }        if (flush || i - start == 128) {            int size = i - start;            if (state == Equal) {                out.append((char)(uchar)(257-size));                out.append(last);                written += size;            } else {                out.append((char)(uchar)size-1);                while (start < i)                    out.append(data[start++]);                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 ";        }

⌨️ 快捷键说明

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