📄 qprintengine_ps.cpp
字号:
/******************************************************************************** Copyright (C) 1992-2006 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://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** 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>// <X11/Xlib.h> redefines Status -> int#if defined(Status)# undef Status#endif#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 "qfile.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>#include <unistd.h>#include <stdlib.h>#include <limits.h>#if defined (Q_WS_X11) || defined (Q_WS_QWS)#include <qtextlayout.h>#endif#ifdef Q_WS_X11#include <qx11info_x11.h>#include <private/qt_x11_p.h>#endifstatic bool qt_gen_epsf = false;void qt_generate_epsf(bool b){ qt_gen_epsf = b;}extern int qt_defaultDpi();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/LWi 0 def/WFi false def/BCol[1 1 1]def/PCol[0 0 0]def\n""/BDArr[0.94 0.88 0.63 0.50 0.37 0.12 0.06]def/defM matrix def/level3{\n""/languagelevel where{pop languagelevel 3 ge}{false}ie}BD/QCIgray D0/QCIcolor\n""D0/QCIindex D0/QCI{/colorimage where{pop false 3 colorimage}{exec/QCIcolor\n""ED/QCIgray QCIcolor length 3 idiv string def 0 1 QCIcolor length 3 idiv 1\n""sub{/QCIindex ED/_x QCIindex 3 mul def QCIgray QCIindex QCIcolor _x get 0.30\n""mul QCIcolor _x 1 add get 0.59 mul QCIcolor _x 2 add get 0.11 mul add add\n""cvi put}for QCIgray image}ie}BD/di{gs TR 1 i 1 eq{pop pop false 3 1 roll\n""BCol SC imagemask}{dup false ne{level3}{false}ie{/_ma ED 8 eq{/_dc[0 1]def\n""/DeviceGray}{/_dc[0 1 0 1 0 1]def/DeviceRGB}ie scs/_im ED/_mt ED/_h ED/_w ED\n""<</ImageType 3/DataDict <</ImageType 1/Width _w/Height _h/ImageMatrix _mt\n""/DataSource _im/BitsPerComponent 8/Decode _dc >>/MaskDict <</ImageType 1\n""/Width _w/Height _h/ImageMatrix _mt/DataSource _ma/BitsPerComponent 1/Decode\n""[0 1]>>/InterleaveType 3 >> image}{pop 8 4 1 roll 8 eq{image}{QCI}ie}ie}ie\n""gr}BD/BF{gs BSt 1 eq{BCol SC WFi{fill}{eofill}ie}if BSt 2 ge BSt 8 le and{\n""BDArr BSt 2 sub get/_sc ED BCol{1. exch sub _sc mul 1. exch sub}forall 3\n""array astore SC WFi{fill}{eofill}ie}if BSt 9 ge BSt 14 le and{WFi{W}{W*}ie\n""pathbbox 3 i 3 i TR 4 2 roll 3 2 roll exch sub/_h ED sub/_w ED BCol SC 0.3 w\n""n BSt 9 eq BSt 11 eq or{0 4 _h{dup 0 exch m _w exch l}for}if BSt 10 eq BSt\n""11 eq or{0 4 _w{dup 0 m _h l}for}if BSt 12 eq BSt 14 eq or{_w _h gt{0 6 _w\n""_h add{dup 0 m _h sub _h l}for}{0 6 _w _h add{dup 0 exch m _w sub _w exch l}\n""for}ie}if BSt 13 eq BSt 14 eq or{_w _h gt{0 6 _w _h add{dup _h m _h sub 0 l}\n""for}{0 6 _w _h add{dup _w exch m _w sub 0 exch l}for}ie}if S}if BSt 15 eq{}\n""if BSt 24 eq{}if gr}BD/f{/WFi true def BF n}BD/f*{/WFi false def BF n}BD/B{\n""/WFi true def BF S n}BD/B*{/WFi false def BF S n}BD/MF{true exch true exch{\n""exch pop exch pop dup 0 get dup findfont dup/FontName get 3 -1 roll eq{exit}\n""if}forall exch dup 1 get/fxscale ED 2 get/fslant ED exch/fencoding ED[\n""fxscale 0 fslant 1 0 0]makefont fencoding false eq{}{dup maxlength dict\n""begin{1 i/FID ne{def}{pop pop}ifelse}forall/Encoding fencoding def\n""currentdict end}ie definefont pop}BD/MFEmb{findfont dup length dict begin{1\n""i/FID ne{def}{pop pop}ifelse}forall/Encoding ED currentdict end definefont\n""pop}BD/QI{/C save def pageinit q n}BD/QP{Q C restore showpage}BD/SPD{\n""/setpagedevice where{<< 3 1 roll >> setpagedevice}{pop pop}ie}BD\n";#if 0// ---------------------------------------------------------------------// postscript font substitution dictionary. We assume every postscript printer has at least// Helvetica, Times, Courier and Symbol#if defined (Q_WS_WIN) && defined (Q_CC_MSVC)# pragma warning(disable: 4305)#endifstruct psfont { const char *psname; qreal slant; qreal xscale;};static const psfont Arial[] = { { "Arial", 0, 84.04 }, { "Arial-Italic", 0, 84.04 }, { "Arial-Bold", 0, 88.65 }, { "Arial-BoldItalic", 0, 88.65 }};static const psfont AvantGarde[] = { { "AvantGarde-Book", 0, 87.43 }, { "AvantGarde-BookOblique", 0, 88.09 }, { "AvantGarde-Demi", 0, 88.09 }, { "AvantGarde-DemiOblique", 0, 87.43 },};static const psfont Bookman [] = { { "Bookman-Light", 0, 93.78 }, { "Bookman-LightItalic", 0, 91.42 }, { "Bookman-Demi", 0, 99.86 }, { "Bookman-DemiItalic", 0, 101.54 }};static const psfont Charter [] = { { "CharterBT-Roman", 0, 84.04 }, { "CharterBT-Italic", 0.0, 81.92 }, { "CharterBT-Bold", 0, 88.99 }, { "CharterBT-BoldItalic", 0.0, 88.20 }};static const psfont Courier [] = { { "Courier", 0, 100. }, { "Courier-Oblique", 0, 100. }, { "Courier-Bold", 0, 100. }, { "Courier-BoldOblique", 0, 100. }};static const psfont Garamond [] = { { "Garamond-Antiqua", 0, 78.13 }, { "Garamond-Kursiv", 0, 78.13 }, { "Garamond-Halbfett", 0, 78.13 }, { "Garamond-KursivHalbfett", 0, 78.13 }};static const psfont GillSans [] = { // estimated value for xstretch { "GillSans", 0, 82 }, { "GillSans-Italic", 0, 82 }, { "GillSans-Bold", 0, 82 }, { "GillSans-BoldItalic", 0, 82 }};static const psfont Helvetica [] = { { "Helvetica", 0, 84.04 }, { "Helvetica-Oblique", 0, 84.04 }, { "Helvetica-Bold", 0, 88.65 }, { "Helvetica-BoldOblique", 0, 88.65 }};static const psfont Letter [] = { { "LetterGothic", 0, 83.32 }, { "LetterGothic-Italic", 0, 83.32 }, { "LetterGothic-Bold", 0, 83.32 }, { "LetterGothic-Bold", 0.2, 83.32 }};static const psfont LucidaSans [] = { { "LucidaSans", 0, 94.36 }, { "LucidaSans-Oblique", 0, 94.36 }, { "LucidaSans-Demi", 0, 98.10 }, { "LucidaSans-DemiOblique", 0, 98.08 }};static const psfont LucidaSansTT [] = { { "LucidaSans-Typewriter", 0, 100.50 }, { "LucidaSans-TypewriterOblique", 0, 100.50 }, { "LucidaSans-TypewriterBold", 0, 100.50 }, { "LucidaSans-TypewriterBoldOblique", 0, 100.50 }};static const psfont LucidaBright [] = { { "LucidaBright", 0, 93.45 }, { "LucidaBright-Italic", 0, 91.98 }, { "LucidaBright-Demi", 0, 96.22 }, { "LucidaBright-DemiItalic", 0, 96.98 }};static const psfont Palatino [] = { { "Palatino-Roman", 0, 82.45 }, { "Palatino-Italic", 0, 76.56 }, { "Palatino-Bold", 0, 83.49 }, { "Palatino-BoldItalic", 0, 81.51 }};static const psfont Symbol [] = { { "Symbol", 0, 82.56 }, { "Symbol", 0.2, 82.56 }, { "Symbol", 0, 82.56 }, { "Symbol", 0.2, 82.56 }};static const psfont Tahoma [] = { { "Tahoma", 0, 83.45 }, { "Tahoma", 0.2, 83.45 }, { "Tahoma-Bold", 0, 95.59 }, { "Tahoma-Bold", 0.2, 95.59 }};static const psfont Times [] = { { "Times-Roman", 0, 82.45 }, { "Times-Italic", 0, 82.45 }, { "Times-Bold", 0, 82.45 }, { "Times-BoldItalic", 0, 82.45 }};static const psfont Verdana [] = { { "Verdana", 0, 96.06 }, { "Verdana-Italic", 0, 96.06 }, { "Verdana-Bold", 0, 107.12 }, { "Verdana-BoldItalic", 0, 107.10 }};static const psfont Utopia [] = { { "Utopia-Regular", 0, 84.70 }, { "Utopia-Regular", 0.2, 84.70 }, { "Utopia-Bold", 0, 88.01 }, { "Utopia-Bold", 0.2, 88.01 }};static const psfont * const SansSerifReplacements[] = { Helvetica, 0 };static const psfont * const SerifReplacements[] = { Times, 0 };static const psfont * const FixedReplacements[] = { Courier, 0 };static const psfont * const TahomaReplacements[] = { Verdana, AvantGarde, Helvetica, 0 };static const psfont * const VerdanaReplacements[] = { Tahoma, AvantGarde, Helvetica, 0 };static const struct { const char * input; // spaces are stripped in here, and everything lowercase const psfont * ps; const psfont *const * replacements;} postscriptFonts [] = { { "arial", Arial, SansSerifReplacements }, { "arialmt", Arial, SansSerifReplacements }, { "arialunicodems", Arial, SansSerifReplacements }, { "avantgarde", AvantGarde, SansSerifReplacements }, { "bookman", Bookman, SerifReplacements }, { "charter", Charter, SansSerifReplacements }, { "bitstreamcharter", Charter, SansSerifReplacements }, { "bitstreamcyberbit", Times, SerifReplacements }, { "courier", Courier, 0 }, { "couriernew", Courier, 0 }, { "fixed", Courier, 0 }, { "garamond", Garamond, SerifReplacements }, { "gillsans", GillSans, SansSerifReplacements }, { "helvetica", Helvetica, 0 }, { "letter", Letter, FixedReplacements }, { "lucida", LucidaSans, SansSerifReplacements }, { "lucidasans", LucidaSans, SansSerifReplacements }, { "lucidabright", LucidaBright, SerifReplacements }, { "lucidasanstypewriter", LucidaSansTT, FixedReplacements }, { "luciduxsans", LucidaSans, SansSerifReplacements }, { "luciduxserif", LucidaBright, SerifReplacements }, { "luciduxmono", LucidaSansTT, FixedReplacements }, { "palatino", Palatino, SerifReplacements }, { "symbol", Symbol, 0 }, { "tahoma", Tahoma, TahomaReplacements }, { "terminal", Courier, 0 }, { "times", Times, 0 }, { "timesnewroman", Times, 0 }, { "verdana", Verdana, VerdanaReplacements }, { "utopia", Utopia, SerifReplacements }, { 0, 0, 0 }};#endif// ------------------------------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) : outDevice(0), fd(-1), collate(false), copies(1), orientation(QPrinter::Portrait), pageSize(QPrinter::A4), pageOrder(QPrinter::FirstPageFirst), colorMode(QPrinter::Color), fullPage(false), printerState(QPrinter::Idle), pid(0){ postscript = true; backgroundMode = Qt::TransparentMode; firstPage = true; resolution = 72; if (m == QPrinter::HighResolution) resolution = 1200; else if (m == QPrinter::ScreenResolution) resolution = qt_defaultDpi();#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(){}static void ps_r7(QPdf::ByteStream& stream, const char * s, int l){ int i = 0; uchar line[80]; 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++]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -