2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
7
/***************************************************************************
8
pdflib_core.cpp - description
10
begin : Sat Jan 19 2002
11
copyright : (C) 2002 by Franz Schmid
12
email : Franz.Schmid@altmuehlnet.de
13
***************************************************************************/
15
/***************************************************************************
17
* This program is free software; you can redistribute it and/or modify *
18
* it under the terms of the GNU General Public License as published by *
19
* the Free Software Foundation; either version 2 of the License, or *
20
* (at your option) any later version. *
22
***************************************************************************/
25
#define _USE_MATH_DEFINES
28
#include "pdflib_core.h"
43
#include <QDataStream>
49
#include <QPainterPath>
59
#include "bookmarkpalette.h"
60
#include "cmsettings.h"
61
#include "commonstrings.h"
62
#include "multiprogressdialog.h"
65
#include "pageitem_textframe.h"
66
#include "pdfoptions.h"
67
#include "prefscontext.h"
68
#include "prefsmanager.h"
70
#include "sccolorengine.h"
73
#include "scpattern.h"
75
#include "scribuscore.h"
76
#include "scribusdoc.h"
77
#include "scstreamfilter_flate.h"
78
#include "scstreamfilter_rc4.h"
79
#include "text/nlsconfig.h"
81
#include "util_file.h"
82
#include "util_formats.h"
83
#include "util_math.h"
84
#include "util_ghostscript.h"
93
PDFLibCore::PDFLibCore(ScribusDoc & docu)
97
Options(doc.PDF_Options),
117
usingGUI(ScCore->usingGUI())
124
Catalog.Outlines = 2;
125
Catalog.PageTree = 3;
133
int kg_array[] = {0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa,
134
0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe,
135
0x64, 0x53, 0x69, 0x7a};
136
for (int a = 0; a < 32; ++a)
137
KeyGen[a] = kg_array[a];
140
progressDialog = new MultiProgressDialog( tr("Saving PDF"), CommonStrings::tr_Cancel, doc.scMW());
141
Q_CHECK_PTR(progressDialog);
142
QStringList barNames, barTexts;
143
barNames << "EMP" << "EP" << "ECPI";
144
barTexts << tr("Exporting Master Page:") << tr("Exporting Page:") << tr("Exporting Items on Current Page:");
145
QList<bool> barsNumeric;
146
barsNumeric << true << true << false;
147
progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
148
connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
152
PDFLibCore::~PDFLibCore()
154
delete progressDialog;
157
static inline QString FToStr(double c)
159
return QString::number(c, 'f', 5);
162
bool PDFLibCore::doExport(const QString& fn, const QString& nam, int Components,
163
const std::vector<int> & pageNs, const QMap<int,QPixmap> & thumbs)
166
bool ret = false, error = false;
167
int pc_exportpages=0;
168
int pc_exportmasterpages=0;
170
progressDialog->show();
171
QMap<QString, QMap<uint, FPointArray> > usedFonts;
173
doc.getUsedFonts(usedFonts);
174
ucs2Codec = QTextCodec::codecForName("UTF-16");
177
// FIXME : Replace by PDF_Error() after 1.3.5 release
178
qDebug() << "Qt build miss UTF-16 text codec, pdf export is not possible";
181
if (PDF_Begin_Doc(fn, PrefsManager::instance()->appPrefs.AvailFonts, usedFonts, doc.scMW()->bookmarkPalette->BView))
183
QMap<int, int> pageNsMpa;
184
for (uint a = 0; a < pageNs.size(); ++a)
186
pageNsMpa.insert(doc.MasterNames[doc.DocPages.at(pageNs[a]-1)->MPageNam], 0);
190
progressDialog->setOverallTotalSteps(pageNsMpa.count()+pageNs.size());
191
progressDialog->setTotalSteps("EMP", pageNsMpa.count());
192
progressDialog->setTotalSteps("EP", pageNs.size());
193
progressDialog->setOverallProgress(0);
194
progressDialog->setProgress("EMP", 0);
195
progressDialog->setProgress("EP", 0);
197
for (int ap = 0; ap < doc.MasterPages.count() && !abortExport; ++ap)
199
if (doc.MasterItems.count() != 0)
201
if (pageNsMpa.contains(ap))
203
qApp->processEvents();
204
if (!PDF_TemplatePage(doc.MasterPages.at(ap)))
205
error = abortExport = true;
206
++pc_exportmasterpages;
211
progressDialog->setProgress("EMP", pc_exportmasterpages);
212
progressDialog->setOverallProgress(pc_exportmasterpages+pc_exportpages);
215
for (uint a = 0; a < pageNs.size() && !abortExport; ++a)
217
if (doc.PDF_Options.Thumbnails)
218
pm = thumbs[pageNs[a]];
219
qApp->processEvents();
220
if (abortExport) break;
222
PDF_Begin_Page(doc.DocPages.at(pageNs[a]-1), pm);
223
qApp->processEvents();
224
if (abortExport) break;
226
if (!PDF_ProcessPage(doc.DocPages.at(pageNs[a]-1), pageNs[a]-1, doc.PDF_Options.doClip))
227
error = abortExport = true;
228
qApp->processEvents();
229
if (abortExport) break;
235
progressDialog->setProgress("EP", pc_exportpages);
236
progressDialog->setOverallProgress(pc_exportmasterpages+pc_exportpages);
239
ret = true;//Even when aborting we return true. Dont want that "couldnt write msg"
242
if (doc.PDF_Options.Version == PDFOptions::PDFVersion_X3)
243
ret = PDF_End_Doc(ScCore->PrinterProfiles[doc.PDF_Options.PrintProf], nam, Components);
251
progressDialog->close();
252
return (ret && !error);
255
const QString& PDFLibCore::errorMessage(void) const
260
bool PDFLibCore::exportAborted(void) const
265
void PDFLibCore::StartObj(int nr)
267
for (int i=XRef.size(); i < nr; ++i)
269
XRef[nr-1] = bytesWritten();
270
PutDoc(QString::number(nr)+ " 0 obj\n");
273
// Encode a string for inclusion in a
275
static QString PDFEncode(const QString & in)
278
for (int d = 0; d < in.length(); ++d)
281
if ((cc == '(') || (cc == ')') || (cc == '\\'))
288
static QString blendMode(int code)
317
return("Difference");
323
return("ColorDodge");
332
return("Saturation");
338
return("Luminosity");
345
QByteArray PDFLibCore::EncodeUTF16(const QString &in)
348
// for (int d = 0; d < in.length(); ++d)
350
// QChar cc(in.at(d));
351
// if ((cc == '(') || (cc == ')') || (cc == '\\'))
356
QByteArray cres = ucs2Codec->fromUnicode( tmp );
357
#ifndef WORDS_BIGENDIAN
358
// on little endian systems we ned to swap bytes:
360
for(int d = 0; d < cres.size()-1; d += 2)
370
QString PDFLibCore::EncStream(const QString & in, int ObjNum)
374
else if (!Options.Encrypt)
378
QByteArray us(tmp.length(), ' ');
379
QByteArray ou(tmp.length(), ' ');
380
for (int a = 0; a < tmp.length(); ++a)
381
us[a] = QChar(tmp.at(a)).cell();
382
QByteArray step1 = ComputeRC4Key(ObjNum);
383
rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), qMin(KeyLen+5, 16));
384
rc4_encrypt(&rc4, reinterpret_cast<uchar*>(us.data()), reinterpret_cast<uchar*>(ou.data()), tmp.length());
386
for (int cl = 0; cl < tmp.length(); ++cl)
391
QString PDFLibCore::EncString(const QString & in, int ObjNum)
393
if (!Options.Encrypt)
399
tmp = in.mid(1, in.length()-2);
400
QByteArray us(tmp.length(), ' ');
401
QByteArray ou(tmp.length(), ' ');
402
for (int a = 0; a < tmp.length(); ++a)
403
us[a] = static_cast<uchar>(QChar(tmp.at(a)).cell());
404
QByteArray step1 = ComputeRC4Key(ObjNum);
405
rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), qMin(KeyLen+5, 16));
406
rc4_encrypt(&rc4, reinterpret_cast<uchar*>(us.data()), reinterpret_cast<uchar*>(ou.data()), tmp.length());
408
for (int cl = 0; cl < tmp.length(); ++cl)
410
tmp = "<"+String2Hex(&uk, false)+">";
414
QString PDFLibCore::EncStringUTF16(const QString & in, int ObjNum)
418
if (!Options.Encrypt)
420
QString tmp = in.mid(1, in.length()-2);
421
QByteArray us = EncodeUTF16(tmp);
423
for (int cl = 0; cl < us.size(); ++cl)
425
return "<"+String2Hex(&uk, false)+">";
428
QString tmp = in.mid(1, in.length()-2);
429
QByteArray us = EncodeUTF16(tmp);
430
QByteArray ou(us.size(), ' ');
431
QByteArray step1 = ComputeRC4Key(ObjNum);
432
rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), qMin(KeyLen+5, 16));
433
rc4_encrypt(&rc4, reinterpret_cast<uchar*>(us.data()), reinterpret_cast<uchar*>(ou.data()), ou.size());
435
for (int cl = 0; cl < ou.size(); ++cl)
437
tmp = "<"+String2Hex(&uk, false)+">";
441
bool PDFLibCore::EncodeArrayToStream(const QByteArray& in, int ObjNum)
445
bool succeed = false;
448
QByteArray step1 = ComputeRC4Key(ObjNum);
449
ScRC4EncodeFilter rc4Encode(&outStream, step1.data(), qMin(KeyLen+5, 16));
450
if (rc4Encode.openFilter())
452
succeed = rc4Encode.writeData(in.data(), in.size());
453
succeed &= rc4Encode.closeFilter();
457
outStream.writeRawData(in, in.size());
458
return (outStream.status() == QDataStream::Ok);
461
int PDFLibCore::WriteImageToStream(ScImage& image, int ObjNum, bool cmyk, bool gray, bool precal)
463
bool succeed = false;
464
int bytesWritten = 0;
467
QByteArray step1 = ComputeRC4Key(ObjNum);
468
ScRC4EncodeFilter rc4Encode(&outStream, step1.data(), qMin(KeyLen+5, 16));
469
if (rc4Encode.openFilter())
472
succeed = image.writeGrayDataToFilter(&rc4Encode, precal);
474
succeed = image.writeCMYKDataToFilter(&rc4Encode);
476
succeed = image.writeRGBDataToFilter(&rc4Encode);
477
succeed &= rc4Encode.closeFilter();
478
bytesWritten = rc4Encode.writtenToStream();
483
ScNullEncodeFilter nullEncode(&outStream);
484
if (nullEncode.openFilter())
487
succeed = image.writeGrayDataToFilter(&nullEncode, precal);
489
succeed = image.writeCMYKDataToFilter(&nullEncode);
491
succeed = image.writeRGBDataToFilter(&nullEncode);
492
succeed &= nullEncode.closeFilter();
493
bytesWritten = nullEncode.writtenToStream();
496
return (succeed ? bytesWritten : 0);
499
int PDFLibCore::WriteJPEGImageToStream(ScImage& image, const QString& fn, int ObjNum, bool cmyk,
500
bool gray, bool sameFile, bool precal)
503
int bytesWritten = 0;
505
QString ext = fInfo.suffix().toLower();
506
QString jpgFileName, tmpFile;
507
if (extensionIndicatesJPEG(ext) && sameFile)
511
tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.jpg");
512
if ((gray) && (!precal))
513
image.convertToGray();
514
if (image.Convert2JPG(tmpFile, Options.Quality, cmyk, gray))
515
jpgFileName = tmpFile;
517
if (jpgFileName.isEmpty())
522
QByteArray step1 = ComputeRC4Key(ObjNum);
523
ScRC4EncodeFilter rc4Encode(&outStream, step1.data(), qMin(KeyLen+5, 16));
524
if (rc4Encode.openFilter())
526
succeed = copyFileToFilter(jpgFileName, rc4Encode);
527
succeed &= rc4Encode.closeFilter();
528
bytesWritten = rc4Encode.writtenToStream();
533
succeed &= copyFileToStream(jpgFileName, outStream);
534
QFileInfo jpgInfo(jpgFileName);
535
bytesWritten = jpgInfo.size();
537
if (!tmpFile.isEmpty() && QFile::exists(tmpFile))
538
QFile::remove(tmpFile);
539
return (succeed ? bytesWritten : 0);
542
int PDFLibCore::WriteFlateImageToStream(ScImage& image, int ObjNum, bool cmyk, bool gray, bool precal)
544
bool succeed = false;
545
int bytesWritten = 0;
548
QByteArray step1 = ComputeRC4Key(ObjNum);
549
ScRC4EncodeFilter rc4Encode(&outStream, step1.data(), qMin(KeyLen+5, 16));
550
ScFlateEncodeFilter flateEncode(&rc4Encode);
551
if (flateEncode.openFilter())
554
succeed = image.writeGrayDataToFilter(&flateEncode, precal);
556
succeed = image.writeCMYKDataToFilter(&flateEncode);
558
succeed = image.writeRGBDataToFilter(&flateEncode);
559
succeed &= flateEncode.closeFilter();
560
bytesWritten = flateEncode.writtenToStream();
565
ScFlateEncodeFilter flateEncode(&outStream);
566
if (flateEncode.openFilter())
569
succeed = image.writeGrayDataToFilter(&flateEncode, precal);
571
succeed = image.writeCMYKDataToFilter(&flateEncode);
573
succeed = image.writeRGBDataToFilter(&flateEncode);
574
succeed &= flateEncode.closeFilter();
575
bytesWritten = flateEncode.writtenToStream();
578
return (succeed ? bytesWritten : 0);
581
QString PDFLibCore::FitKey(const QString & pass)
584
if (pw.length() < 32)
586
uint l = pw.length();
587
for (uint a = 0; a < 32 - l; ++a)
588
pw += QChar(KeyGen[a]);
595
void PDFLibCore::CalcOwnerKey(const QString & Owner, const QString & User)
598
QString pw(FitKey(User));
599
QString pw2(FitKey(Owner.isEmpty() ? User : Owner));
600
QByteArray step1(16, ' ');
601
step1 = ComputeMD5(pw2);
604
for (int kl = 0; kl < 50; ++kl)
605
step1 = ComputeMD5Sum(&step1);
607
QByteArray us(32, ' ');
608
QByteArray enk(16, ' ');
611
for (uint a2 = 0; a2 < 32; ++a2)
612
OwnerKey[a2] = QChar(pw.at(a2)).cell();
613
for (int rl = 0; rl < 20; rl++)
615
for (int j = 0; j < 16; j ++)
616
enk[j] = step1[j] ^ rl;
617
rc4_init(&rc4, reinterpret_cast<uchar*>(enk.data()), 16);
618
rc4_encrypt(&rc4, reinterpret_cast<uchar*>(OwnerKey.data()),
619
reinterpret_cast<uchar*>(OwnerKey.data()), 32);
624
for (uint a = 0; a < 32; ++a)
625
us[a] = static_cast<uchar>(QChar(pw.at(a)).cell());
626
rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), 5);
627
rc4_encrypt(&rc4, reinterpret_cast<uchar*>(us.data()),
628
reinterpret_cast<uchar*>(OwnerKey.data()), 32);
632
void PDFLibCore::CalcUserKey(const QString & User, int Permission)
635
QString pw(FitKey(User));
636
QByteArray step1(16, ' ');
637
QByteArray perm(4, ' ');
638
uint perm_value = static_cast<uint>(Permission);
639
perm[0] = perm_value;
640
perm[1] = perm_value >> 8;
641
perm[2] = perm_value >> 16;
642
perm[3] = perm_value >> 24;
643
for (uint a = 0; a < 32; ++a)
644
pw += QChar(OwnerKey[a]);
645
for (uint a1 = 0; a1 < 4; ++a1)
646
pw += QChar(perm[a1]);
647
for (uint a3 = 0; a3 < 16; ++a3)
648
pw += QChar(FileID[a3]);
649
step1 = ComputeMD5(pw);
652
for (int kl = 0; kl < 50; ++kl)
653
step1 = ComputeMD5Sum(&step1);
656
for (int a2 = 0; a2 < KeyLen; ++a2)
657
EncryKey[a2] = step1[a2];
661
for (int kl3 = 0; kl3 < 32; ++kl3)
662
pr2 += QChar(KeyGen[kl3]);
663
for (uint a4 = 0; a4 < 16; ++a4)
664
pr2 += QChar(FileID[a4]);
665
step1 = ComputeMD5(pr2);
666
QByteArray enk(16, ' ');
667
for (uint a3 = 0; a3 < 16; ++a3)
668
UserKey[a3] = step1[a3];
669
for (int rl = 0; rl < 20; rl++)
671
for (int j = 0; j < 16; j ++)
672
enk[j] = EncryKey[j] ^ rl;
673
rc4_init(&rc4, reinterpret_cast<uchar*>(enk.data()), 16);
674
rc4_encrypt(&rc4, reinterpret_cast<uchar*>(UserKey.data()), reinterpret_cast<uchar*>(UserKey.data()), 16);
679
rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), 5);
680
rc4_encrypt(&rc4, reinterpret_cast<uchar*>(KeyGen.data()), reinterpret_cast<uchar*>(UserKey.data()), 32);
684
QByteArray PDFLibCore::ComputeMD5(const QString& in)
686
uint inlen=in.length();
687
QByteArray TBytes(inlen, ' ');
688
for (uint a = 0; a < inlen; ++a)
689
TBytes[a] = static_cast<uchar>(QChar(in.at(a)).cell());
690
return ComputeMD5Sum(&TBytes);
693
QByteArray PDFLibCore::ComputeRC4Key(int ObjNum)
696
QByteArray data(10, ' ');
699
for (int cd = 0; cd < KeyLen; ++cd)
701
data[cd] = EncryKey[cd];
704
data[dlen++] = ObjNum;
705
data[dlen++] = ObjNum >> 8;
706
data[dlen++] = ObjNum >> 16;
709
QByteArray rc4Key(16, ' ');
710
rc4Key = ComputeMD5Sum(&data);
711
rc4Key.resize(qMin(KeyLen+5, 16));
715
bool PDFLibCore::PDF_Begin_Doc(const QString& fn, SCFonts &AllFonts, QMap<QString, QMap<uint, FPointArray> > DocFonts, BookMView* vi)
717
Spool.setFileName(fn);
718
if (!Spool.open(QIODevice::WriteOnly))
720
outStream.setDevice(&Spool);
732
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
736
switch (Options.Version)
738
case PDFOptions::PDFVersion_X3:
739
case PDFOptions::PDFVersion_13:
740
PutDoc("%PDF-1.3\n");
742
case PDFOptions::PDFVersion_14:
743
PutDoc("%PDF-1.4\n");
745
case PDFOptions::PDFVersion_15:
746
PutDoc("%PDF-1.5\n");
749
if (Options.Version == PDFOptions::PDFVersion_X3)
751
PutDoc("%\xc7\xec\x8f\xa2\n");
753
PutDoc("<<\n/Type /Catalog\n/Outlines 3 0 R\n/Pages 4 0 R\n/Dests 5 0 R\n/AcroForm 6 0 R\n/Names 7 0 R\n/Threads 8 0 R\n");
754
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
755
PutDoc("/OCProperties 9 0 R\n");
756
if (Options.Version == PDFOptions::PDFVersion_X3)
757
PutDoc("/OutputIntents [ "+QString::number(ObjCounter-1)+" 0 R ]\n");
758
PutDoc("/PageLayout ");
759
switch (Options.PageLayout)
761
case PDFOptions::SinglePage:
762
PutDoc("/SinglePage\n");
764
case PDFOptions::OneColumn:
765
PutDoc("/OneColumn\n");
767
case PDFOptions::TwoColumnLeft:
768
PutDoc("/TwoColumnLeft\n");
770
case PDFOptions::TwoColumnRight:
771
PutDoc("/TwoColumnRight\n");
774
if (Options.displayBookmarks)
775
PutDoc("/PageMode /UseOutlines\n");
776
else if (Options.displayFullscreen)
777
PutDoc("/PageMode /FullScreen\n");
778
else if (Options.displayThumbs)
779
PutDoc("/PageMode /UseThumbs\n");
780
else if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.displayLayers))
781
PutDoc("/PageMode /UseOC\n");
782
if (!Options.openAction.isEmpty())
784
PutDoc("/OpenAction << /S /JavaScript /JS (this."+Options.openAction+"\\(\\)) >>\n");
787
QDate d = QDate::currentDate();
789
tmp.sprintf("%4d", d.year());
790
tmp.replace(QRegExp(" "), "0");
792
tmp.sprintf("%2d", d.month());
793
tmp.replace(QRegExp(" "), "0");
795
tmp.sprintf("%2d", d.day());
796
tmp.replace(QRegExp(" "), "0");
798
tmp = QTime::currentTime().toString();
799
tmp.replace(QRegExp(":"), "");
802
/* The following code makes the resulting PDF "Reader enabled" in Acrobat Reader 8
803
but sadly it doesn't work with newer version, because its based on a bug in AR 8
808
PutDoc("/M ("+Datum+")\n");
809
PutDoc("/Name (Scribus "+QString(VERSION)+")\n");
810
PutDoc("/Reference [\n");
812
PutDoc("/TransformParams\n");
814
PutDoc("/Type /TransformParams\n");
816
PutDoc("/Document [/FullSave]\n");
817
PutDoc("/Annots [/Create/Delete/Modify/Copy/Import/Export]\n");
818
PutDoc("/Form [/Add/Delete/FillIn/Import/Export/SubmitStandalone/SpawnTemplate]\n");
819
PutDoc("/Signature [/Modify]\n");
821
PutDoc("/TransformMethod /UR3\n");
822
PutDoc("/Type /SigRef\n");
825
PutDoc("/Type /Sig\n");
830
PutDoc("/ViewerPreferences\n<<\n/PageDirection ");
831
PutDoc( Options.Binding == 0 ? "/L2R\n" : "/R2L\n");
832
if (Options.hideToolBar)
833
PutDoc("/HideToolbar true\n");
834
if (Options.hideMenuBar)
835
PutDoc("/HideMenubar true\n");
836
if (Options.fitWindow)
837
PutDoc("/FitWindow true\n");
838
PutDoc(" >>\n>>\nendobj\n");
840
IDg += Options.fileName;
841
IDg += "Scribus "+QString(VERSION);
842
IDg += "Scribus PDF Library "+QString(VERSION);
843
IDg += doc.documentInfo.getTitle();
844
IDg += doc.documentInfo.getAuthor();
846
FileID = ComputeMD5(IDg);
849
if ((Options.Version == PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_15))
853
CalcOwnerKey(Options.PassOwner, Options.PassUser);
854
CalcUserKey(Options.PassUser, Options.Permissions);
855
for (uint cl2 = 0; cl2 < 32; ++cl2)
856
ok += QChar(OwnerKey[cl2]);
859
for (uint cl3 = 0; cl3 < 16; ++cl3)
860
uk += QChar(UserKey[cl3]);
861
for (uint cl3r = 0; cl3r < 16; ++cl3r)
862
uk += QChar(KeyGen[cl3r]);
866
for (uint cl = 0; cl < 32; ++cl)
867
uk += QChar(UserKey[cl]);
871
PutDoc("<<\n/Creator "+EncString("(Scribus "+QString(VERSION)+")",2)+"\n");
872
PutDoc("/Producer "+EncString("(Scribus PDF Library "+QString(VERSION)+")",2)+"\n");
873
QString docTitle = doc.documentInfo.getTitle();
874
if ((Options.Version == PDFOptions::PDFVersion_X3) && (docTitle.isEmpty()))
875
PutDoc("/Title "+EncStringUTF16("("+doc.DocName+")",2)+"\n");
877
PutDoc("/Title "+EncStringUTF16("("+doc.documentInfo.getTitle()+")",2)+"\n");
878
PutDoc("/Author "+EncStringUTF16("("+doc.documentInfo.getAuthor()+")",2)+"\n");
879
PutDoc("/Keywords "+EncStringUTF16("("+doc.documentInfo.getKeywords()+")",2)+"\n");
880
PutDoc("/CreationDate "+EncString("("+Datum+")",2)+"\n");
881
PutDoc("/ModDate "+EncString("("+Datum+")",2)+"\n");
882
if (Options.Version == PDFOptions::PDFVersion_X3)
883
PutDoc("/GTS_PDFXVersion (PDF/X-3:2002)\n");
884
PutDoc("/Trapped /False\n>>\nendobj\n");
885
for (int t = 0; t < 6; ++t)
886
XRef.append(bytesWritten());
887
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
888
XRef.append(bytesWritten());
889
if (Options.Version == PDFOptions::PDFVersion_X3)
890
XRef.append(bytesWritten());
893
Encrypt = newObject();
895
PutDoc("<<\n/Filter /Standard\n");
896
PutDoc( KeyLen > 5 ? "/R 3\n/V 2\n/Length 128\n" : "/R 2\n/V 1\n");
897
PutDoc("/O <"+String2Hex(&ok)+">\n");
898
PutDoc("/U <"+String2Hex(&uk)+">\n");
899
PutDoc("/P "+QString::number(Options.Permissions)+"\n>>\nendobj\n");
901
QMap<QString, QMap<uint, FPointArray> > ReallyUsed;
904
QMap<int, QString> ind2PDFabr;
905
const QString tmpf[] = {"/Courier", "/Courier-Bold", "/Courier-Oblique", "/Courier-BoldOblique",
906
"/Helvetica", "/Helvetica-Bold", "/Helvetica-Oblique", "/Helvetica-BoldOblique",
907
"/Times-Roman", "/Times-Bold", "/Times-Italic", "/Times-BoldItalic",
908
"/ZapfDingbats", "/Symbol"};
909
size_t ar = sizeof(tmpf) / sizeof(*tmpf);
910
for (uint ax = 0; ax < ar; ++ax)
911
ind2PDFabr[ax] = tmpf[ax];
912
for (int c = 0; c < doc.FrameItems.count(); ++c)
914
pgit = doc.FrameItems.at(c);
915
if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
917
if (pgit->isAnnotation())
919
int annotType = pgit->annotation().Type();
920
bool mustEmbed = ((annotType >= 2) && (annotType <= 6) && (annotType != 4));
921
if (pgit->annotation().Type() == 4)
922
StdFonts.insert("/ZapfDingbats", "");
923
if (pgit->itemText.length() > 0 || mustEmbed)
925
if (Options.Version < PDFOptions::PDFVersion_14)
926
StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
927
ReallyUsed.insert(pgit->itemText.defaultStyle().charStyle().font().replacementName(), DocFonts[pgit->itemText.defaultStyle().charStyle().font().replacementName()]);
930
for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
932
ReallyUsed.insert(pgit->itemText.charStyle(e).font().replacementName(), DocFonts[pgit->itemText.charStyle(e).font().replacementName()]);
936
for (int c = 0; c < doc.MasterItems.count(); ++c)
938
pgit = doc.MasterItems.at(c);
939
if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
941
if (pgit->isAnnotation())
943
int annotType = pgit->annotation().Type();
944
bool mustEmbed = ((annotType >= 2) && (annotType <= 6) && (annotType != 4));
945
if (pgit->annotation().Type() == 4)
946
StdFonts.insert("/ZapfDingbats", "");
947
if (pgit->itemText.length() > 0 || mustEmbed)
949
if (Options.Version < PDFOptions::PDFVersion_14)
950
StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
951
ReallyUsed.insert(pgit->itemText.defaultStyle().charStyle().font().replacementName(), DocFonts[pgit->itemText.defaultStyle().charStyle().font().replacementName()]);
954
for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
956
ReallyUsed.insert(pgit->itemText.charStyle(e).font().replacementName(), DocFonts[pgit->itemText.charStyle(e).font().replacementName()]);
960
for (int d = 0; d < doc.DocItems.count(); ++d)
962
pgit = doc.DocItems.at(d);
963
if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
965
if (pgit->isAnnotation())
967
int annotType = pgit->annotation().Type();
968
bool mustEmbed = ((annotType >= 2) && (annotType <= 6) && (annotType != 4));
969
if (pgit->annotation().Type() == 4)
970
StdFonts.insert("/ZapfDingbats", "");
971
if (pgit->itemText.length() > 0 || mustEmbed)
973
if (Options.Version < PDFOptions::PDFVersion_14)
974
StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
975
ReallyUsed.insert(pgit->itemText.defaultStyle().charStyle().font().replacementName(), DocFonts[pgit->itemText.defaultStyle().charStyle().font().replacementName()]);
978
for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
980
ReallyUsed.insert(pgit->itemText.charStyle(e).font().replacementName(), DocFonts[pgit->itemText.charStyle(e).font().replacementName()]);
984
/* if (Options.docInfoMarks)
986
StdFonts.insert("/Helvetica", "");
988
QStringList patterns = doc.getUsedPatterns();
989
for (int c = 0; c < patterns.count(); ++c)
991
ScPattern pa = doc.docPatterns[patterns[c]];
992
for (int o = 0; o < pa.items.count(); o++)
994
pgit = pa.items.at(o);
995
if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
997
if (pgit->isAnnotation())
999
if (pgit->annotation().Type() == 4)
1000
StdFonts.insert("/ZapfDingbats", "");
1001
if (pgit->itemText.length() > 0)
1003
if (Options.Version < PDFOptions::PDFVersion_14)
1004
StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
1005
ReallyUsed.insert(pgit->itemText.defaultStyle().charStyle().font().replacementName(), DocFonts[pgit->itemText.defaultStyle().charStyle().font().replacementName()]);
1008
for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
1010
ReallyUsed.insert(pgit->itemText.charStyle(e).font().replacementName(), DocFonts[pgit->itemText.charStyle(e).font().replacementName()]);
1016
QMap<QString, QString>::Iterator itStd;
1017
for (itStd = StdFonts.begin(); itStd != StdFonts.end(); ++itStd)
1019
uint fontObject = newObject();
1020
StartObj(fontObject);
1021
PutDoc("<<\n/Type /Font\n/Subtype /Type1\n");
1022
PutDoc("/Name /FoStd"+QString::number(a)+"\n");
1023
PutDoc("/BaseFont "+itStd.key()+"\n");
1024
if (itStd.key() != "/ZapfDingbats")
1026
PutDoc("/Encoding << \n");
1027
PutDoc("/Differences [ \n");
1028
PutDoc("24 /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek /ring /tilde\n");
1029
PutDoc("39 /quotesingle 96 /grave 128 /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin /fraction /guilsinglleft /guilsinglright\n");
1030
PutDoc("/minus /perthousand /quotedblbase /quotedblleft /quotedblright /quoteleft /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron\n");
1031
PutDoc("/Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron 164 /currency 166 /brokenbar 168 /dieresis /copyright /ordfeminine 172 /logicalnot\n");
1032
PutDoc("/.notdef /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu 183 /periodcentered /cedilla /onesuperior /ordmasculine\n");
1033
PutDoc("188 /onequarter /onehalf /threequarters 192 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex\n");
1034
PutDoc("/Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n");
1035
PutDoc("/Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n");
1036
PutDoc("/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis\n");
1037
PutDoc("/divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis\n");
1040
PutDoc(">>\nendobj\n");
1041
Seite.FObjects["FoStd"+QString::number(a)] = fontObject;
1042
itStd.value() = "FoStd"+QString::number(a);
1045
QMap<QString,QMap<uint, FPointArray> >::Iterator it;
1047
for (it = ReallyUsed.begin(); it != ReallyUsed.end(); ++it)
1049
ScFace& face(AllFonts[it.key()]);
1050
ScFace::FontFormat fformat = face.format();
1051
if ((!face.hasNames()) || (Options.SubsetList.contains(it.key())))
1053
if (face.hasNames())
1055
UsedFontsP.insert(it.key(), "/Fo"+QString::number(a));
1058
double minx = 99999.9;
1059
double miny = 99999.9;
1060
double maxx = -99999.9;
1061
double maxy = -99999.9;
1062
QList<uint> glyphWidths;
1063
QStringList charProcs;
1064
QString encoding = "<< /Type /Encoding\n/Differences [ 0\n";
1066
QMap<uint, uint> glyphMapping;
1067
QMap<uint,std::pair<QChar,QString> > gl;
1068
face.glyphNames(gl);
1069
QMap<uint,FPointArray>& RealGlyphs(it.value());
1070
QMap<uint,FPointArray>::Iterator ig;
1071
for (ig = RealGlyphs.begin(); ig != RealGlyphs.end(); ++ig)
1073
FPoint np, np1, np2;
1076
if (ig.value().size() > 3)
1078
FPointArray gly = ig.value();
1080
mat.scale(100.0, -100.0);
1082
gly.translate(0, 1000);
1083
for (uint poi = 0; poi < gly.size()-3; poi += 4)
1085
if (gly.point(poi).x() > 900000)
1093
np = gly.point(poi);
1094
fon += FToStr(np.x())+" "+FToStr(np.y())+" m\n";
1097
np = gly.point(poi+1);
1098
np1 = gly.point(poi+3);
1099
np2 = gly.point(poi+2);
1100
fon += FToStr(np.x()) + " " + FToStr(np.y()) + " " + FToStr(np1.x()) + " " + FToStr(np1.y()) + " " + FToStr(np2.x()) + " " + FToStr(np2.y()) + " c\n";
1103
np = getMinClipF(&gly);
1104
np1 = getMaxClipF(&gly);
1112
fon.prepend(QString::number(qRound(np1.x())) + " 0 "+QString::number(qRound(np.x()))+" "+QString::number(qRound(np.y()))+" "+QString::number(qRound(np1.x()))+ " "+QString::number(qRound(np1.y()))+" d1\n");
1113
minx = qMin(minx, np.x());
1114
miny = qMin(miny, np.y());
1115
maxx = qMax(maxx, np1.x());
1116
maxy = qMax(maxy, np1.y());
1117
glyphWidths.append(qRound(np1.x()));
1118
uint charProcObject = newObject();
1119
charProcs.append("/"+gl[ig.key()].second+" "+QString::number(charProcObject)+" 0 R\n");
1120
encoding += "/"+gl[ig.key()].second+" ";
1121
glyphMapping.insert(ig.key(), glyphCount + SubFonts * 256);
1122
StartObj(charProcObject);
1123
if (Options.Compress)
1124
fon = CompressStr(&fon);
1125
PutDoc("<< /Length "+QString::number(fon.length()+1));
1126
if (Options.Compress)
1127
PutDoc("\n/Filter /FlateDecode");
1128
PutDoc("\n>>\nstream\n"+EncStream(fon, charProcObject)+"\nendstream\nendobj\n");
1130
int glyphsLeft = RealGlyphs.count() - SubFonts * 256;
1131
if ((glyphCount > 255) || (glyphCount == glyphsLeft))
1133
uint fontWidths = newObject();
1134
StartObj(fontWidths);
1136
for (int ww = 0; ww < glyphWidths.count(); ++ww)
1138
PutDoc(QString::number(qRound(glyphWidths[ww]))+" ");
1140
PutDoc("]\nendobj\n");
1141
uint fontCharProcs = newObject();
1142
StartObj(fontCharProcs);
1144
for (int ww = 0; ww < charProcs.count(); ++ww)
1146
PutDoc(charProcs[ww]);
1148
PutDoc(">>\nendobj\n");
1149
uint fontEncoding = newObject();
1150
StartObj(fontEncoding);
1153
PutDoc(">>\nendobj\n");
1154
uint font3Object = newObject();
1155
StartObj(font3Object);
1156
PutDoc("<<\n/Type /Font\n/Subtype /Type3\n");
1157
PutDoc("/Name /Fo"+QString::number(a)+"S"+QString::number(SubFonts)+"\n");
1158
PutDoc("/FirstChar 0\n");
1159
PutDoc("/LastChar "+QString::number(glyphCount-1)+"\n");
1160
PutDoc("/Widths "+QString::number(fontWidths)+" 0 R\n");
1161
PutDoc("/CharProcs "+QString::number(fontCharProcs)+" 0 R\n");
1162
PutDoc("/FontBBox ["+QString::number(qRound(minx))+" "+QString::number(qRound(miny))+" "+QString::number(qRound(maxx))+ " "+QString::number(qRound(maxy))+"]\n");
1163
PutDoc("/FontMatrix [0.001 0 0 0.001 0 0]\n");
1164
PutDoc("/Encoding "+QString::number(fontEncoding)+" 0 R\n");
1165
PutDoc(">>\nendobj\n");
1166
Seite.FObjects["Fo"+QString::number(a)+"S"+QString::number(SubFonts)] = font3Object;
1168
glyphWidths.clear();
1169
// glyphMapping.clear();
1176
encoding = "<< /Type /Encoding\n/Differences [ 0\n";
1179
Type3Fonts.insert("/Fo"+QString::number(a), glyphMapping);
1184
QMap<uint,FPointArray>& RealGlyphs(it.value());
1185
QMap<uint,FPointArray>::Iterator ig;
1186
for (ig = RealGlyphs.begin(); ig != RealGlyphs.end(); ++ig)
1188
FPoint np, np1, np2;
1191
if (ig.value().size() > 3)
1193
FPointArray gly = ig.value();
1195
mat.scale(0.1, 0.1);
1197
for (uint poi = 0; poi < gly.size()-3; poi += 4)
1199
if (gly.point(poi).x() > 900000)
1207
np = gly.point(poi);
1208
fon += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
1211
np = gly.point(poi+1);
1212
np1 = gly.point(poi+3);
1213
np2 = gly.point(poi+2);
1214
fon += FToStr(np.x()) + " " + FToStr(-np.y()) + " " +
1215
FToStr(np1.x()) + " " + FToStr(-np1.y()) + " " +
1216
FToStr(np2.x()) + " " + FToStr(-np2.y()) + " c\n";
1219
np = getMinClipF(&gly);
1220
np1 = getMaxClipF(&gly);
1228
uint fontGlyphXForm = newObject();
1229
StartObj(fontGlyphXForm);
1230
PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1\n");
1231
PutDoc("/BBox [ "+FToStr(np.x())+" "+FToStr(-np.y())+" "+FToStr(np1.x())+ " "+FToStr(-np1.y())+" ]\n");
1232
PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
1234
if (Options.Compress)
1235
fon = CompressStr(&fon);
1236
PutDoc("/Length "+QString::number(fon.length()+1));
1237
if (Options.Compress)
1238
PutDoc("\n/Filter /FlateDecode");
1239
PutDoc(" >>\nstream\n"+EncStream(fon, fontGlyphXForm)+"\nendstream\nendobj\n");
1240
Seite.XObjects[AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+QString::number(ig.key())] = fontGlyphXForm;
1246
UsedFontsP.insert(it.key(), "/Fo"+QString::number(a));
1247
uint embeddedFontObject = 0;
1248
if ((fformat == ScFace::PFB) && (Options.EmbedList.contains(it.key())))
1251
embeddedFontObject = newObject();
1252
StartObj(embeddedFontObject);
1254
AllFonts[it.key()].RawData(bb);
1256
for (posi = 6; posi < bb.size(); ++posi)
1258
if ((bb[posi] == static_cast<char>(0x80)) && (static_cast<int>(bb[posi+1]) == 2))
1260
fon += QChar(bb[posi]);
1262
int len1 = fon.length();
1264
ulen = bb[posi+2] & 0xff;
1265
ulen |= (bb[posi+3] << 8) & 0xff00;
1266
ulen |= (bb[posi+4] << 16) & 0xff0000;
1267
ulen |= (bb[posi+5] << 24) & 0xff000000;
1268
if (ulen > bb.size())
1271
for (int j = 0; j < ulen; ++j)
1272
fon += QChar(bb[posi++]);
1274
int len2 = fon.length()-len1;
1275
for (int j = posi; j < bb.size(); ++j)
1277
if ((bb[j] == static_cast<char>(0x80)) && (static_cast<int>(bb[j+1]) == 3))
1282
fon += QChar(bb[j]);
1284
int len3 = fon.length()-len2-len1;
1285
if (Options.Compress)
1286
fon = CompressStr(&fon);
1287
PutDoc("<<\n/Length "+QString::number(fon.length()+1)+"\n");
1288
PutDoc("/Length1 "+QString::number(len1)+"\n");
1289
PutDoc("/Length2 "+QString::number(len2)+"\n");
1290
PutDoc("/Length3 "+QString::number(len3)+"\n");
1291
if (Options.Compress)
1292
PutDoc("/Filter /FlateDecode\n");
1293
PutDoc(">>\nstream\n"+EncStream(fon,embeddedFontObject)+"\nendstream\nendobj\n");
1295
if ((fformat == ScFace::PFA) && (Options.EmbedList.contains(it.key())))
1302
embeddedFontObject = newObject();
1303
StartObj(embeddedFontObject);
1304
AllFonts[it.key()].EmbedFont(fon);
1305
int len1 = fon.indexOf("eexec")+5;
1306
fon2 = fon.left(len1)+"\n";
1307
int len2 = fon.indexOf("0000000000000000000000000");
1309
len2 = fon.length()+1;
1311
for (int xx = len1; xx < len2-1; ++xx)
1314
if ((tm == QChar(13)) || (tm == QChar(10)))
1319
value = tm.toUInt(&ok, 16);
1320
fon2 += QChar(value);
1322
fon2 += fon.mid(len2);
1323
if (Options.Compress)
1324
fon2 = CompressStr(&fon2);
1325
PutDoc("<<\n/Length "+QString::number(fon2.length()+1)+"\n");
1326
PutDoc("/Length1 "+QString::number(len1+1)+"\n");
1327
PutDoc("/Length2 "+QString::number(count)+"\n");
1328
PutDoc(static_cast<int>(fon.length()-len2) == -1 ? QString("/Length3 0\n") : "/Length3 "+QString::number(fon.length()-len2)+"\n");
1329
if (Options.Compress)
1330
PutDoc("/Filter /FlateDecode\n");
1331
PutDoc(">>\nstream\n"+EncStream(fon2, embeddedFontObject)+"\nendstream\nendobj\n");
1333
if ((fformat == ScFace::SFNT || fformat == ScFace::TTCF) && (Options.EmbedList.contains(it.key())))
1336
embeddedFontObject = newObject();
1337
StartObj(embeddedFontObject);
1339
AllFonts[it.key()].RawData(bb);
1340
//AV: += and append() dont't work because they stop at '\0' :-(
1341
for (int i=0; i < bb.size(); i++)
1342
fon += QChar(bb[i]);
1343
int len = fon.length();
1344
if (Options.Compress)
1345
fon = CompressStr(&fon);
1346
//qDebug() << QString("sfnt data: size=%1 before=%2 compressed=%3").arg(bb.size()).arg(len).arg(fon.length());
1347
PutDoc("<<\n/Length "+QString::number(fon.length()+1)+"\n");
1348
PutDoc("/Length1 "+QString::number(len)+"\n");
1349
if (Options.Compress)
1350
PutDoc("/Filter /FlateDecode\n");
1351
PutDoc(">>\nstream\n"+EncStream(fon, embeddedFontObject)+"\nendstream\nendobj\n");
1353
uint fontDescriptor = newObject();
1354
StartObj(fontDescriptor);
1355
// TODO: think about QByteArray ScFace::getFontDescriptor() -- AV
1356
PutDoc("<<\n/Type /FontDescriptor\n");
1357
PutDoc("/FontName /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
1358
PutDoc("/FontBBox [ "+AllFonts[it.key()].fontBBoxAsString()+" ]\n");
1360
//FIXME: isItalic() should be queried from ScFace, not from Qt -- AV
1361
//QFontInfo fo = QFontInfo(it.data());
1363
if (AllFonts[it.key()].isFixedPitch())
1366
if (AllFonts[it.key()].italicAngleAsString() != "0")
1370
PutDoc(QString::number(pfl)+"\n");
1371
PutDoc("/Ascent "+AllFonts[it.key()].ascentAsString()+"\n");
1372
PutDoc("/Descent "+AllFonts[it.key()].descentAsString()+"\n");
1373
PutDoc("/CapHeight "+AllFonts[it.key()].capHeightAsString()+"\n");
1374
PutDoc("/ItalicAngle "+AllFonts[it.key()].italicAngleAsString()+"\n");
1375
// PutDoc("/Ascent "+QString::number(static_cast<int>(AllFonts[it.key()].ascent()))+"\n");
1376
// PutDoc("/Descent "+QString::number(static_cast<int>(AllFonts[it.key()].descent()))+"\n");
1377
// PutDoc("/CapHeight "+QString::number(static_cast<int>(AllFonts[it.key()].capHeight()))+"\n");
1378
// PutDoc("/ItalicAngle "+AllFonts[it.key()].italicAngle()+"\n");
1379
// PutDoc("/StemV "+ AllFonts[it.key()].stemV() + "\n");
1380
PutDoc("/StemV 1\n");
1381
if ((fformat == ScFace::SFNT || fformat == ScFace::TTCF) && (Options.EmbedList.contains(it.key())))
1382
PutDoc("/FontFile2 "+QString::number(embeddedFontObject)+" 0 R\n");
1383
if ((fformat == ScFace::PFB) && (Options.EmbedList.contains(it.key())))
1384
PutDoc("/FontFile "+QString::number(embeddedFontObject)+" 0 R\n");
1385
if ((fformat == ScFace::PFA) && (Options.EmbedList.contains(it.key())))
1386
PutDoc("/FontFile "+QString::number(embeddedFontObject)+" 0 R\n");
1387
PutDoc(">>\nendobj\n");
1388
/* if (!FT_Has_PS_Glyph_Names(AllFonts[it.key()])
1390
StartObj(ObjCounter);
1392
PutDoc("[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ");
1393
for (int ww = 31; ww < 256; ++ww)
1395
PutDoc(QString::number(static_cast<int>(AllFonts[it.key()]->CharWidth[itg.key()]*
1397
if (itg == gl.end())
1402
PutDoc("]\nendobj\n");
1404
// put widths object
1405
// encoding dictionary w/ base encoding w/o differences
1406
StartObj(ObjCounter);
1407
PutDoc("<<\n/Type /Font\n/Subtype ");
1408
PutDoc((fformat == ScFace::SFNT || fformat == ScFace::TTCF) ? "/TrueType\n" : "/Type1\n");
1409
PutDoc("/Name /Fo"+QString::number(a)+"\n");
1410
PutDoc("/BaseFont /"+AllFonts[it.key()]->psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "" )+"\n");
1412
PutDoc("/FirstChar 0\n");
1413
PutDoc("/LastChar "+QString::number(chCount-1)+"\n");
1414
PutDoc("/Widths "+QString::number(ObjCounter-1)+" 0 R\n");
1415
PutDoc("/FontDescriptor "+QString::number(ObjCounter-2)+" 0 R\n");
1416
PutDoc(">>\nendobj\n");
1417
Seite.FObjects["Fo"+QString::number(a)] = ObjCounter;
1422
QMap<uint,std::pair<QChar,QString> > gl;
1423
AllFonts[it.key()].glyphNames(gl);
1425
QMap<uint,std::pair<QChar,QString> >::Iterator gli;
1426
for (gli = gl.begin(); gli != gl.end(); ++gli)
1428
if (gli.key() > static_cast<uint>(nglyphs))
1429
nglyphs = gli.key();
1432
// qDebug() << QString("pdflib: nglyphs %1 max %2").arg(nglyphs).arg(AllFonts[it.key()].maxGlyph());
1433
uint FontDes = fontDescriptor;
1434
uint Fcc = nglyphs / 224;
1435
if ((nglyphs % 224) != 0)
1437
for (uint Fc = 0; Fc < Fcc; ++Fc)
1439
uint fontWidths2 = newObject();
1440
StartObj(fontWidths2);
1442
PutDoc("[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ");
1443
for (int ww = 32; ww < 256; ++ww)
1445
uint glyph = 224 * Fc + ww - 32;
1446
if (gl.contains(glyph))
1447
PutDoc(QString::number(static_cast<int>(AllFonts[it.key()].glyphWidth(glyph)* 1000))+" ");
1451
if (signed(glyph) == nglyphs-1)
1454
PutDoc("]\nendobj\n");
1455
uint fontEncoding2 = newObject();
1456
StartObj(fontEncoding2);
1457
QStringList toUnicodeMaps;
1458
QList<int> toUnicodeMapsCount;
1459
QString toUnicodeMap = "";
1460
int toUnicodeMapCounter = 0;
1461
PutDoc("<< /Type /Encoding\n");
1462
PutDoc("/Differences [ \n");
1464
bool startOfSeq = true;
1465
for (int ww2 = 32; ww2 < 256; ++ww2)
1467
uint glyph = 224 * Fc + ww2 - 32;
1468
QMap<uint,std::pair<QChar,QString> >::Iterator glIt = gl.find(glyph);
1469
if (glIt != gl.end() && !glIt.value().second.isEmpty())
1473
PutDoc(QString::number(ww2)+" ");
1476
PutDoc("/"+glIt.value().second+" ");
1478
tmp.sprintf("%02X", ww2);
1479
tmp2.sprintf("%04X", glIt.value().first.unicode());
1480
toUnicodeMap += QString("<%1> <%2>\n").arg(tmp).arg((tmp2));
1481
toUnicodeMapCounter++;
1482
if (toUnicodeMapCounter == 100)
1484
toUnicodeMaps.append(toUnicodeMap);
1485
toUnicodeMapsCount.append(toUnicodeMapCounter);
1487
toUnicodeMapCounter = 0;
1495
if (signed(glyph) == nglyphs-1)
1503
if (toUnicodeMapCounter != 0)
1505
toUnicodeMaps.append(toUnicodeMap);
1506
toUnicodeMapsCount.append(toUnicodeMapCounter);
1509
PutDoc(">>\nendobj\n");
1510
QString toUnicodeMapStream = "";
1511
toUnicodeMapStream += "/CIDInit /ProcSet findresource begin\n";
1512
toUnicodeMapStream += "12 dict begin\n";
1513
toUnicodeMapStream += "begincmap\n";
1514
toUnicodeMapStream += "/CIDSystemInfo <<\n";
1515
toUnicodeMapStream += "/Registry (Adobe)\n";
1516
toUnicodeMapStream += "/Ordering (UCS)\n";
1517
toUnicodeMapStream += "/Supplement 0\n";
1518
toUnicodeMapStream += ">> def\n";
1519
toUnicodeMapStream += "/CMapName /Adobe-Identity-UCS def\n";
1520
toUnicodeMapStream += "/CMapType 2 def\n";
1521
toUnicodeMapStream += "1 begincodespacerange\n";
1522
toUnicodeMapStream += "<0000> <FFFF>\n";
1523
toUnicodeMapStream += "endcodespacerange\n";
1524
for (int uniC = 0; uniC < toUnicodeMaps.count(); uniC++)
1526
toUnicodeMapStream += QString("%1 beginbfchar\n").arg(toUnicodeMapsCount[uniC]);
1527
toUnicodeMapStream += toUnicodeMaps[uniC];
1528
toUnicodeMapStream += "endbfchar\n";
1530
toUnicodeMapStream += "endcmap\n";
1531
toUnicodeMapStream += "CMapName currentdict /CMap defineresource pop\n";
1532
toUnicodeMapStream += "end\n";
1533
toUnicodeMapStream += "end\n";
1534
uint fontToUnicode2 = WritePDFStream(toUnicodeMapStream);
1535
uint fontObject2 = newObject();
1536
StartObj(fontObject2);
1537
PutDoc("<<\n/Type /Font\n/Subtype ");
1538
PutDoc((fformat == ScFace::SFNT || fformat == ScFace::TTCF) ? "/TrueType\n" : "/Type1\n");
1539
PutDoc("/Name /Fo"+QString::number(a)+"S"+QString::number(Fc)+"\n");
1540
PutDoc("/BaseFont /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
1541
PutDoc("/FirstChar 0\n");
1542
PutDoc("/LastChar "+QString::number(chCount-1)+"\n");
1543
PutDoc("/Widths "+QString::number(fontWidths2)+" 0 R\n");
1544
PutDoc("/Encoding "+QString::number(fontEncoding2)+" 0 R\n");
1545
PutDoc("/ToUnicode "+QString::number(fontToUnicode2)+" 0 R\n");
1546
PutDoc("/FontDescriptor "+QString::number(FontDes)+" 0 R\n");
1547
PutDoc(">>\nendobj\n");
1548
Seite.FObjects["Fo"+QString::number(a)+"S"+QString::number(Fc)] = fontObject2;
1550
uint fontWidthsForm = newObject();
1551
StartObj(fontWidthsForm);
1552
PutDoc("[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ");
1553
for (int ww = 32; ww < 256; ++ww)
1555
uint glyph = AllFonts[it.key()].char2CMap(QChar(ww));
1556
if (gl.contains(glyph))
1557
PutDoc(QString::number(static_cast<int>(AllFonts[it.key()].glyphWidth(glyph)* 1000))+" ");
1561
PutDoc("]\nendobj\n");
1562
uint fontObjectForm = newObject();
1563
StartObj(fontObjectForm);
1564
PutDoc("<<\n/Type /Font\n/Subtype ");
1565
PutDoc((fformat == ScFace::SFNT || fformat == ScFace::TTCF) ? "/TrueType\n" : "/Type1\n");
1566
// if (fformat == ScFace::SFNT || fformat == ScFace::TTCF)
1568
// PutDoc("/TrueType\n");
1569
PutDoc("/Name /Fo"+QString::number(a)+"Form"+"\n");
1570
Seite.FObjects["Fo"+QString::number(a)+"Form"] = fontObjectForm;
1571
UsedFontsF.insert(it.key(), "/Fo"+QString::number(a)+"Form");
1576
PutDoc("/Name /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
1577
Seite.FObjects[AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )] = ObjCounter;
1578
UsedFontsF.insert(it.key(), "/"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" ));
1580
PutDoc("/BaseFont /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
1581
PutDoc("/Encoding << \n");
1582
PutDoc("/Differences [ \n");
1583
PutDoc("24 /breve /caron /circumflex /dotaccent /hungarumlaut /ogonek /ring /tilde\n");
1584
PutDoc("39 /quotesingle 96 /grave 128 /bullet /dagger /daggerdbl /ellipsis /emdash /endash /florin /fraction /guilsinglleft /guilsinglright\n");
1585
PutDoc("/minus /perthousand /quotedblbase /quotedblleft /quotedblright /quoteleft /quoteright /quotesinglbase /trademark /fi /fl /Lslash /OE /Scaron\n");
1586
PutDoc("/Ydieresis /Zcaron /dotlessi /lslash /oe /scaron /zcaron 164 /currency 166 /brokenbar 168 /dieresis /copyright /ordfeminine 172 /logicalnot\n");
1587
PutDoc("/.notdef /registered /macron /degree /plusminus /twosuperior /threesuperior /acute /mu 183 /periodcentered /cedilla /onesuperior /ordmasculine\n");
1588
PutDoc("188 /onequarter /onehalf /threequarters 192 /Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla /Egrave /Eacute /Ecircumflex\n");
1589
PutDoc("/Edieresis /Igrave /Iacute /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply /Oslash\n");
1590
PutDoc("/Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls /agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n");
1591
PutDoc("/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis /eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis\n");
1592
PutDoc("/divide /oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis\n");
1594
PutDoc("/FirstChar 0\n");
1595
PutDoc("/LastChar 255\n");
1596
PutDoc("/Widths "+QString::number(fontWidthsForm)+" 0 R\n");
1597
PutDoc("/FontDescriptor "+QString::number(FontDes)+" 0 R\n");
1598
PutDoc(">>\nendobj\n");
1599
// } // FT_Has_PS_Glyph_Names
1605
uint halftones = newObject();
1606
StartObj(halftones);
1607
PutDoc("<<\n/Type /Halftone\n/HalftoneType 5\n");
1608
QMap<QString,LPIData>::const_iterator itlp;
1609
for (itlp = Options.LPISettings.constBegin(); itlp != Options.LPISettings.constEnd(); ++itlp)
1611
PutDoc("/"+itlp.key()+"\n<<\n/Type /Halftone\n/HalftoneType 1\n/Frequency ");
1612
PutDoc(QString::number(itlp.value().Frequency)+"\n/Angle "+QString::number(itlp.value().Angle)+"\n/SpotFunction ");
1614
switch (itlp.value().SpotFunc)
1617
func = "/SimpleDot";
1629
func = "/SimpleDot";
1632
PutDoc(func+"\n>>\n");
1634
PutDoc("/Default\n<<\n/Type /Halftone\n/HalftoneType 1\n/Frequency 50\n/Angle 45\n/SpotFunction /Round\n>>\n");
1635
PutDoc(">>\nendobj\n");
1636
HTName = ResNam+QString::number(ResCount);
1637
Transpar[HTName] = writeGState("/HT "+QString::number(halftones)+" 0 R\n");
1640
if ((doc.HasCMS) && (Options.UseProfiles))
1642
uint iccProfileObject = newObject();
1643
StartObj(iccProfileObject);
1646
loadRawBytes(ScCore->InputProfiles[Options.SolidProf], dataP);
1648
if (Options.Compress)
1650
QByteArray compData = CompressArray(dataP);
1651
if (compData.size() > 0)
1653
PutDoc("/Filter /FlateDecode\n");
1657
PutDoc("/Length "+QString::number(dataP.size()+1)+"\n");
1658
PutDoc("/N "+QString::number(Options.SComp)+"\n");
1659
PutDoc(">>\nstream\n");
1660
EncodeArrayToStream(dataP, iccProfileObject);
1661
PutDoc("\nendstream\nendobj\n");
1662
uint iccColorspace = newObject();
1663
StartObj(iccColorspace);
1664
dataD.ResName = ResNam+QString::number(ResCount);
1665
dataD.ICCArray = "[ /ICCBased "+QString::number(iccProfileObject)+" 0 R ]";
1666
dataD.ResNum = iccColorspace;
1667
dataD.components = Options.SComp;
1668
ICCProfiles[Options.SolidProf] = dataD;
1669
PutDoc("[ /ICCBased "+QString::number(iccProfileObject)+" 0 R ]\n");
1673
if (((Options.isGrayscale == false) && (Options.UseRGB == false)) && (Options.UseSpotColors))
1675
doc.getUsedColors(colorsToUse);
1676
ColorList::Iterator itf;
1677
for (itf = colorsToUse.begin(); itf != colorsToUse.end(); ++itf)
1679
if ((colorsToUse[itf.key()].isSpotColor()) || (colorsToUse[itf.key()].isRegistrationColor()))
1681
CMYKColor cmykValues;
1684
ScColorEngine::getCMYKValues(colorsToUse[itf.key()], &doc, cmykValues);
1685
cmykValues.getValues(cc, cm, cy, ck);
1686
QString colorDesc = "{\ndup "+FToStr(static_cast<double>(cc) / 255)+"\nmul exch dup ";
1687
colorDesc += FToStr(static_cast<double>(cm) / 255)+"\nmul exch dup ";
1688
colorDesc += FToStr(static_cast<double>(cy) / 255)+"\nmul exch ";
1689
colorDesc += FToStr(static_cast<double>(ck) / 255)+" mul }";
1690
uint separationFunction = newObject();
1691
StartObj(separationFunction);
1692
PutDoc("<<\n/FunctionType 4\n");
1693
PutDoc("/Domain [0.0 1.0]\n");
1694
PutDoc("/Range [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]\n");
1695
PutDoc("/Length "+QString::number(colorDesc.length()+1)+"\n");
1696
PutDoc(">>\nstream\n"+EncStream(colorDesc, separationFunction)+"\nendstream\nendobj\n");
1697
uint separationColorspace= newObject();
1698
StartObj(separationColorspace);
1699
PutDoc("[ /Separation /");
1700
if (colorsToUse[itf.key()].isRegistrationColor())
1703
PutDoc(itf.key().simplified().replace("#", "#23").replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "#20" ));
1704
PutDoc(" /DeviceCMYK "+QString::number(separationFunction)+" 0 R ]\nendobj\n");
1705
spotD.ResName = spotNam+QString::number(spotCount);
1706
spotD.ResNum = separationColorspace;
1707
spotMap.insert(itf.key(), spotD);
1712
if ((Options.cropMarks) || (Options.bleedMarks) || (Options.registrationMarks) || (Options.colorMarks) || (Options.docInfoMarks))
1715
uint registrationColorspace = newObject();
1716
StartObj(registrationColorspace);
1717
PutDoc("[ /Separation /All /DeviceCMYK\n");
1718
PutDoc("<<\n/FunctionType 2\n");
1719
PutDoc("/Domain [0.0 1.0]\n");
1720
PutDoc("/Range [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]\n");
1721
PutDoc("/C0 [0 0 0 0] \n");
1722
PutDoc("/C1 [1 1 1 1] \n");
1724
PutDoc(">>\n]\nendobj\n");
1725
spotD.ResName = spotNam+QString::number(spotCount);
1726
spotD.ResNum = registrationColorspace;
1727
spotMapReg.insert("Register", spotD);
1730
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
1734
ll.isPrintable = false;
1737
QString ocgNam("oc");
1738
uint docLayersCount=doc.Layers.count();
1739
for (uint la = 0; la < docLayersCount; ++la)
1741
uint optionalContent = newObject();
1743
doc.Layers.levelToLayer(ll, Lnr);
1744
ocg.Name = ocgNam+tmp.setNum(ll.LNr);
1745
ocg.ObjNum = optionalContent;
1746
ocg.visible = ll.isViewable;
1747
OCGEntries.insert(ll.Name, ocg);
1748
StartObj(optionalContent);
1750
PutDoc("/Type /OCG\n");
1752
PutDoc(EncStringUTF16("("+ll.Name+")", optionalContent));
1754
PutDoc("/Usage <</Print <</PrintState ");
1759
PutDoc(">> /View <</ViewState ");
1766
PutDoc(">>\nendobj\n");
1773
bool PDFLibCore::PDF_TemplatePage(const Page* pag, bool )
1775
QString tmp, tmpOut;
1778
QList<PageItem*> PItems;
1781
ll.isPrintable = false;
1784
Seite.AObjects.clear();
1785
for (int la = 0; la < doc.Layers.count(); ++la)
1787
doc.Layers.levelToLayer(ll, Lnr);
1788
PItems = doc.MasterItems;
1789
if ((ll.isPrintable) || ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers)))
1791
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
1792
PutPage("/OC /"+OCGEntries[ll.Name].Name+" BDC\n");
1793
for (int a = 0; a < PItems.count(); ++a)
1797
if (ite->LayerNr != ll.LNr)
1799
double bLeft, bRight, bBottom, bTop;
1800
getBleeds(pag, bLeft, bRight, bBottom, bTop);
1801
double x = pag->xOffset() - bLeft;
1802
double y = pag->yOffset() - bTop;
1803
double w = pag->width() + bLeft + bRight;
1804
double h1 = pag->height() + bBottom + bTop;
1805
double ilw= ite->lineWidth();
1806
double x2 = ite->BoundingX - ilw / 2.0;
1807
double y2 = ite->BoundingY - ilw / 2.0;
1808
double w2 = ite->BoundingW + ilw;
1809
double h2 = ite->BoundingH + ilw;
1810
if (!( qMax( x, x2 ) <= qMin( x+w, x2+w2 ) && qMax( y, y2 ) <= qMin( y+h1, y2+h2 )))
1812
if (ite->ChangedMasterItem)
1814
if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
1817
if ((ite->doOverprint) && (!Options.UseRGB))
1819
QString ShName = ResNam+QString::number(ResCount);
1821
Transpar[ShName] = writeGState("/OP true\n"
1824
PutPage("/"+ShName+" gs\n");
1826
/* Bookmarks on Master Pages do not make any sense */
1827
// if ((ite->isBookmark) && (Options.Bookmarks))
1828
// PDF_Bookmark(ite, pag->height() - (ite->yPos() - pag->yOffset()));
1829
if (!ite->printEnabled() || ((ite->itemType() == PageItem::TextFrame) && (!pag->pageName().isEmpty())))
1834
if (ite->fillColor() != CommonStrings::None)
1835
PutPage(putColor(ite->fillColor(), ite->fillShade(), true));
1836
if (ite->lineColor() != CommonStrings::None)
1837
PutPage(putColor(ite->lineColor(), ite->lineShade(), false));
1838
Content += FToStr(fabs(ite->lineWidth()))+" w\n";
1839
if (ite->DashValues.count() != 0)
1842
QVector<double>::iterator it;
1843
for ( it = ite->DashValues.begin(); it != ite->DashValues.end(); ++it )
1845
int da = static_cast<int>(*it);
1846
// #8758: Custom dotted lines don't export properly to pdf
1847
// Null values have to be exported if line end != flat
1848
if ((da != 0) || (ite->lineEnd() != Qt::FlatCap))
1849
PutPage(QString::number(da)+" ");
1851
PutPage("] "+QString::number(static_cast<int>(ite->DashOffset))+" d\n");
1854
PutPage("["+getDashString(ite->PLineArt, ite->lineWidth())+"] 0 d\n");
1855
switch (ite->PLineEnd)
1870
switch (ite->PLineJoin)
1885
PutPage("1 0 0 1 "+FToStr(ite->xPos() - pag->xOffset())+" "+FToStr(pag->height() - (ite->yPos() - pag->yOffset()))+" cm\n");
1886
if (ite->rotation() != 0)
1888
double sr = sin(-ite->rotation()* M_PI / 180.0);
1889
double cr = cos(-ite->rotation()* M_PI / 180.0);
1890
if ((cr * cr) < 0.000001)
1892
if ((sr * sr) < 0.000001)
1894
PutPage(FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+" 0 0 cm\n");
1896
switch (ite->itemType())
1898
case PageItem::ImageFrame:
1899
case PageItem::LatexFrame:
1900
// Same functions as for ImageFrames work for LatexFrames too
1901
if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
1902
PutPage(PDF_TransparenzFill(ite));
1903
if ((ite->fillColor() != CommonStrings::None) || (ite->GrType != 0))
1905
if (ite->GrType != 0)
1907
if (!PDF_Gradient(tmpOut, ite))
1913
PutPage(SetClipPath(ite));
1918
if (ite->imageClip.size() != 0)
1920
PutPage(SetClipPathImage(ite));
1921
PutPage("h\nW*\nn\n");
1923
PutPage(SetClipPath(ite));
1924
PutPage("h\nW*\nn\n");
1925
if (ite->imageFlippedH())
1926
PutPage("-1 0 0 1 "+FToStr(ite->width())+" 0 cm\n");
1927
if (ite->imageFlippedV())
1928
PutPage("1 0 0 -1 0 "+FToStr(-ite->height())+" cm\n");
1929
if ((ite->PictureIsAvailable) && (!ite->Pfile.isEmpty()))
1931
if (!PDF_Image(ite, ite->Pfile, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), false, ite->IProfile, ite->UseEmbedded, ite->IRender, &tmpOut))
1936
if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
1938
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
1939
PutPage(PDF_TransparenzStroke(ite));
1940
if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
1942
PutPage(SetClipPath(ite));
1947
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
1948
for (int it = ml.size()-1; it > -1; it--)
1950
if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1952
PutPage(setStrokeMulti(&ml[it]));
1953
PutPage(SetClipPath(ite));
1960
case PageItem::TextFrame:
1962
case PageItem::Line:
1963
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
1964
PutPage(PDF_TransparenzStroke(ite));
1965
if (ite->NamedLStyle.isEmpty())
1968
PutPage(FToStr(ite->width())+" 0 l\n");
1973
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
1974
for (int it = ml.size()-1; it > -1; it--)
1976
if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1978
PutPage(setStrokeMulti(&ml[it]));
1980
PutPage(FToStr(ite->width())+" 0 l\n");
1985
if (ite->startArrowIndex() != 0)
1988
arrowTrans.scale(-1,1);
1989
PutPage(drawArrow(ite, arrowTrans, ite->startArrowIndex()));
1991
if (ite->endArrowIndex() != 0)
1994
arrowTrans.translate(ite->width(), 0);
1995
PutPage(drawArrow(ite, arrowTrans, ite->endArrowIndex()));
1998
case PageItem::ItemType1:
1999
case PageItem::ItemType3:
2000
case PageItem::Polygon:
2001
if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2002
PutPage(PDF_TransparenzFill(ite));
2003
if (ite->GrType != 0)
2005
if (!PDF_Gradient(tmpOut, ite))
2011
if (ite->fillColor() != CommonStrings::None)
2013
PutPage(SetClipPath(ite));
2017
if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
2019
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2020
PutPage(PDF_TransparenzStroke(ite));
2021
if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
2023
PutPage(SetClipPath(ite));
2028
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
2029
for (int it = ml.size()-1; it > -1; it--)
2031
if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
2033
PutPage(setStrokeMulti(&ml[it]));
2034
PutPage(SetClipPath(ite));
2041
case PageItem::PolyLine:
2042
if (ite->PoLine.size() > 4) // && ((ite->PoLine.point(0) != ite->PoLine.point(1)) || (ite->PoLine.point(2) != ite->PoLine.point(3))))
2044
if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2045
PutPage(PDF_TransparenzFill(ite));
2046
if (ite->GrType != 0)
2048
if (!PDF_Gradient(tmpOut, ite))
2054
if (ite->fillColor() != CommonStrings::None)
2056
PutPage(SetClipPath(ite));
2061
if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
2063
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2064
PutPage(PDF_TransparenzStroke(ite));
2065
if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
2067
PutPage(SetClipPath(ite, false));
2072
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
2073
for (int it = ml.size()-1; it > -1; it--)
2075
if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
2077
PutPage(setStrokeMulti(&ml[it]));
2078
PutPage(SetClipPath(ite, false));
2084
if (ite->startArrowIndex() != 0)
2086
FPoint Start = ite->PoLine.point(0);
2087
for (uint xx = 1; xx < ite->PoLine.size(); xx += 2)
2089
FPoint Vector = ite->PoLine.point(xx);
2090
if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
2092
double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
2094
arrowTrans.translate(Start.x(), Start.y());
2095
arrowTrans.rotate(r);
2096
PutPage(drawArrow(ite, arrowTrans, ite->startArrowIndex()));
2101
if (ite->endArrowIndex() != 0)
2103
FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
2104
for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
2106
FPoint Vector = ite->PoLine.point(xx);
2107
if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
2109
double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
2111
arrowTrans.translate(End.x(), End.y());
2112
arrowTrans.rotate(r);
2113
PutPage(drawArrow(ite, arrowTrans, ite->endArrowIndex()));
2119
case PageItem::PathText:
2122
if (ite->PoLine.size() > 3)
2125
if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
2127
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2128
PutPage(PDF_TransparenzStroke(ite));
2129
if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
2131
PutPage(SetClipPath(ite, false));
2136
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
2137
for (int it = ml.size()-1; it > -1; it--)
2139
if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
2141
PutPage(setStrokeMulti(&ml[it]));
2142
PutPage(SetClipPath(ite, false));
2151
if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2152
PutPage(PDF_TransparenzFill(ite));
2153
PutPage(setTextSt(ite, pag->pageNr(), pag));
2155
case PageItem::Multiple:
2160
uint templateObject = newObject();
2161
StartObj(templateObject);
2162
PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1\n");
2163
double bleedRight = 0.0;
2164
double bleedLeft = 0.0;
2165
getBleeds(ActPageP, bleedLeft, bleedRight);
2166
double maxBoxX = ActPageP->width()+bleedRight+bleedLeft;
2167
double maxBoxY = ActPageP->height()+Options.bleeds.Top+Options.bleeds.Bottom;
2168
PutDoc("/BBox [ "+FToStr(-bleedLeft)+" "+FToStr(-Options.bleeds.Bottom)+" "+FToStr(maxBoxX)+" "+FToStr(maxBoxY)+" ]\n");
2169
// PutDoc("/BBox [ 0 0 "+FToStr(ActPageP->width())+" "+FToStr(ActPageP->height())+" ]\n");
2170
PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
2171
if (Seite.ImgObjects.count() != 0)
2173
PutDoc("/XObject <<\n");
2174
QMap<QString,int>::Iterator it;
2175
for (it = Seite.ImgObjects.begin(); it != Seite.ImgObjects.end(); ++it)
2176
PutDoc("/"+it.key()+" "+QString::number(it.value())+" 0 R\n");
2179
if (Seite.FObjects.count() != 0)
2181
PutDoc("/Font << \n");
2182
QMap<QString,int>::Iterator it2;
2183
for (it2 = Seite.FObjects.begin(); it2 != Seite.FObjects.end(); ++it2)
2184
PutDoc("/"+it2.key()+" "+QString::number(it2.value())+" 0 R\n");
2187
if (Shadings.count() != 0)
2189
PutDoc("/Shading << \n");
2190
QMap<QString,int>::Iterator it3;
2191
for (it3 = Shadings.begin(); it3 != Shadings.end(); ++it3)
2192
PutDoc("/"+it3.key()+" "+QString::number(it3.value())+" 0 R\n");
2195
if (Patterns.count() != 0)
2197
PutDoc("/Pattern << \n");
2198
QMap<QString,int>::Iterator it3p;
2199
for (it3p = Patterns.begin(); it3p != Patterns.end(); ++it3p)
2200
PutDoc("/"+it3p.key()+" "+QString::number(it3p.value())+" 0 R\n");
2203
if (Transpar.count() != 0)
2205
PutDoc("/ExtGState << \n");
2206
QMap<QString,int>::Iterator it3t;
2207
for (it3t = Transpar.begin(); it3t != Transpar.end(); ++it3t)
2208
PutDoc("/"+it3t.key()+" "+QString::number(it3t.value())+" 0 R\n");
2211
if ((ICCProfiles.count() != 0) || (spotMap.count() != 0))
2213
PutDoc("/ColorSpace << \n");
2214
QMap<QString,ICCD>::Iterator it3c;
2215
if (ICCProfiles.count() != 0)
2217
for (it3c = ICCProfiles.begin(); it3c != ICCProfiles.end(); ++it3c)
2218
PutDoc("/"+it3c.value().ResName+" "+QString::number(it3c.value().ResNum)+" 0 R\n");
2220
QMap<QString,SpotC>::Iterator it3sc;
2221
if (spotMap.count() != 0)
2223
for (it3sc = spotMap.begin(); it3sc != spotMap.end(); ++it3sc)
2224
PutDoc("/"+it3sc.value().ResName+" "+QString::number(it3sc.value().ResNum)+" 0 R\n");
2229
if (Options.Compress)
2230
Content = CompressStr(&Content);
2231
PutDoc("/Length "+QString::number(Content.length()+1));
2232
if (Options.Compress)
2233
PutDoc("\n/Filter /FlateDecode");
2234
PutDoc(" >>\nstream\n"+EncStream(Content, templateObject)+"\nendstream\nendobj\n");
2235
int pIndex = doc.MasterPages.indexOf((Page* const) pag) + 1;
2236
QString name = QString("master_page_obj_%1_%2").arg(pIndex).arg(ite->ItemNr);
2237
Seite.XObjects[name] = templateObject;
2239
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
2247
void PDFLibCore::PDF_Begin_Page(const Page* pag, QPixmap pm)
2252
Seite.AObjects.clear();
2253
if (Options.Thumbnails)
2255
ScImage img(pm.toImage());
2256
bool compDataAvail = false;
2257
QByteArray array = img.ImageToArray();
2258
if (Options.Compress)
2260
QByteArray compArray = CompressArray(array);
2261
if (compArray.size() > 0)
2264
compDataAvail = true;
2267
uint thumbnail = newObject();
2268
StartObj(thumbnail);
2269
PutDoc("<<\n/Width "+QString::number(img.width())+"\n");
2270
PutDoc("/Height "+QString::number(img.height())+"\n");
2271
PutDoc("/ColorSpace /DeviceRGB\n/BitsPerComponent 8\n");
2273
PutDoc("/Length "+QString::number(array.size()+1)+"\n");
2274
if (Options.Compress && compDataAvail)
2275
PutDoc("/Filter /FlateDecode\n");
2276
PutDoc(">>\nstream\n");
2277
EncodeArrayToStream(array, thumbnail);
2278
PutDoc("\nendstream\nendobj\n");
2279
Seite.Thumb = thumbnail;
2283
void PDFLibCore::PDF_End_Page(int physPage)
2285
uint PgNr = ActPageP->pageNr();
2286
double markOffs = 0.0;
2287
if ((Options.cropMarks) || (Options.bleedMarks) || (Options.registrationMarks) || (Options.colorMarks) || (Options.docInfoMarks))
2288
markOffs = 20.0 + Options.markOffset;
2289
double bleedRight, bleedLeft;
2290
getBleeds(ActPageP, bleedLeft, bleedRight);
2291
double maxBoxX = ActPageP->width()+bleedLeft+bleedRight+markOffs*2.0;
2292
double maxBoxY = ActPageP->height()+Options.bleeds.Bottom+Options.bleeds.Top+markOffs*2.0;
2293
// (JG) Fix #5977 and #6075 (invalid restore)
2295
if ((Options.cropMarks) || (Options.bleedMarks) || (Options.registrationMarks) || (Options.colorMarks) || (Options.docInfoMarks))
2297
PutPage("0.5 w 0 j 0 J [] 0 d\n");
2298
PutPage("/"+spotMapReg["Register"].ResName+" CS 1 SCN\n");
2299
if (Options.cropMarks)
2302
PutPage("0 "+FToStr(markOffs+Options.bleeds.Bottom)+" m\n");
2303
PutPage(FToStr(20.0)+" "+FToStr(markOffs+Options.bleeds.Bottom)+" l\n");
2305
PutPage(FToStr(markOffs+bleedLeft)+" 0 m\n");
2306
PutPage(FToStr(markOffs+bleedLeft)+" 20 l\n");
2309
PutPage("0 "+FToStr(maxBoxY-Options.bleeds.Top-markOffs)+" m\n");
2310
PutPage(FToStr(20.0)+" "+FToStr(maxBoxY-Options.bleeds.Top-markOffs)+" l\n");
2312
PutPage(FToStr(markOffs+bleedLeft)+" "+FToStr(maxBoxY)+" m\n");
2313
PutPage(FToStr(markOffs+bleedLeft)+" "+FToStr(maxBoxY-20.0)+" l\n");
2316
PutPage(FToStr(maxBoxX)+" "+FToStr(markOffs+Options.bleeds.Bottom)+" m\n");
2317
PutPage(FToStr(maxBoxX-20.0)+" "+FToStr(markOffs+Options.bleeds.Bottom)+" l\n");
2319
PutPage(FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(0.0)+" m\n");
2320
PutPage(FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(20.0)+" l\n");
2323
PutPage(FToStr(maxBoxX)+" "+FToStr(maxBoxY-Options.bleeds.Top-markOffs)+" m\n");
2324
PutPage(FToStr(maxBoxX-20.0)+" "+FToStr(maxBoxY-Options.bleeds.Top-markOffs)+" l\n");
2326
PutPage(FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(maxBoxY)+" m\n");
2327
PutPage(FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(maxBoxY-20.0)+" l\n");
2330
if (Options.bleedMarks)
2333
PutPage("[3 1 1 1] 0 d\n");
2335
PutPage("0 "+FToStr(markOffs)+" m\n");
2336
PutPage(FToStr(20.0)+" "+FToStr(markOffs)+" l\n");
2338
PutPage(FToStr(markOffs)+" 0 m\n");
2339
PutPage(FToStr(markOffs)+" 20 l\n");
2342
PutPage("0 "+FToStr(maxBoxY-markOffs)+" m\n");
2343
PutPage(FToStr(20.0)+" "+FToStr(maxBoxY-markOffs)+" l\n");
2345
PutPage(FToStr(markOffs)+" "+FToStr(maxBoxY)+" m\n");
2346
PutPage(FToStr(markOffs)+" "+FToStr(maxBoxY-20.0)+" l\n");
2349
PutPage(FToStr(maxBoxX)+" "+FToStr(markOffs)+" m\n");
2350
PutPage(FToStr(maxBoxX-20.0)+" "+FToStr(markOffs)+" l\n");
2352
PutPage(FToStr(maxBoxX-markOffs)+" "+FToStr(0.0)+" m\n");
2353
PutPage(FToStr(maxBoxX-markOffs)+" "+FToStr(20.0)+" l\n");
2356
PutPage(FToStr(maxBoxX)+" "+FToStr(maxBoxY-markOffs)+" m\n");
2357
PutPage(FToStr(maxBoxX-20.0)+" "+FToStr(maxBoxY-markOffs)+" l\n");
2359
PutPage(FToStr(maxBoxX-markOffs)+" "+FToStr(maxBoxY)+" m\n");
2360
PutPage(FToStr(maxBoxX-markOffs)+" "+FToStr(maxBoxY-20.0)+" l\n");
2364
if (Options.registrationMarks)
2366
QString regCross = "0 7 m\n14 7 l\nh\n7 0 m\n7 14 l\nh\n13 7 m\n13 10.31383 10.31383 13 7 13 c\n3.68629 13 1 10.31383 1 7 c\n1 3.68629 3.68629 1 7 1 c\n";
2367
regCross += "10.31383 1 13 3.68629 13 7 c\nh\n10.5 7 m\n10.5 8.93307 8.93307 10.5 7 10.5 c\n5.067 10.5 3.5 8.93307 3.5 7 c\n";
2368
regCross += "3.5 5.067 5.067 3.5 7 3.5 c\n8.93307 3.5 10.5 5.067 10.5 7 c\nh\nS\n";
2370
PutPage("1 0 0 1 "+FToStr(maxBoxX / 2.0 - 7.0)+" 3 cm\n");
2374
PutPage("1 0 0 1 3 "+FToStr(maxBoxY / 2.0 - 7.0)+" cm\n");
2378
PutPage("1 0 0 1 "+FToStr(maxBoxX / 2.0 - 7.0)+" "+FToStr(maxBoxY - 17.0)+" cm\n");
2382
PutPage("1 0 0 1 "+FToStr(maxBoxX - 17.0)+" "+FToStr(maxBoxY / 2.0 - 7.0)+" cm\n");
2386
if (Options.colorMarks)
2388
double startX = markOffs+bleedLeft+6.0;
2389
double startY = maxBoxY - 18.0;
2390
PutPage("0 0 0 1 K\n");
2392
for (int bl = 0; bl < 11; bl++)
2394
PutPage("0 0 0 "+FToStr(col)+" k\n");
2395
PutPage(FToStr(startX+bl*14.0)+" "+FToStr(startY)+" 14 14 re B\n");
2398
if (!Options.isGrayscale)
2400
startX = maxBoxX-bleedRight-markOffs-20.0;
2401
PutPage("0 0 0 0.5 k\n");
2402
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2404
PutPage("0 0 0.5 0 k\n");
2405
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2407
PutPage("0 0.5 0 0 k\n");
2408
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2410
PutPage("0.5 0 0 0 k\n");
2411
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2413
PutPage("1 1 0 0 k\n");
2414
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2416
PutPage("1 0 1 0 k\n");
2417
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2419
PutPage("0 1 1 0 k\n");
2420
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2422
PutPage("0 0 0 1 k\n");
2423
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2425
PutPage("0 0 1 0 k\n");
2426
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2428
PutPage("0 1 0 0 k\n");
2429
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2431
PutPage("1 0 0 0 k\n");
2432
PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2435
if (Options.docInfoMarks)
2437
// QString tmp = "";
2438
// double startX = markOffs+bleedLeft+10.0;
2439
FPointArray textPath;
2440
QPainterPath painter1, painter2;
2441
QFont infoFont("Helvetica", 7);
2442
double startX = markOffs+bleedLeft+10.0;
2443
QString docTitle = doc.documentInfo.getTitle();
2444
if (docTitle.isEmpty())
2446
QFileInfo fi(doc.DocName);
2447
docTitle = fi.fileName();
2449
// docTitle += " "+ tr("Page:")+" "+tmp.setNum(PgNr+1);
2450
docTitle += " "+ tr("Page:")+" "+ QString::number(PgNr+1);
2451
PutPage("/"+spotMapReg["Register"].ResName+" cs 1 scn\n");
2453
PutPage("1 0 0 1 "+FToStr(startX)+" 6 cm\n");
2455
// PutPage("/"+StdFonts["/Helvetica"]+" 7 Tf\n");
2456
// PutPage(EncString("("+docTitle+")",ObjCounter)+" Tj\nET\n");
2457
painter1.addText( QPointF(0.0,0.0), infoFont, docTitle );
2458
textPath.fromQPainterPath(painter1);
2459
PutPage(SetClipPathArray(&textPath, true));
2462
QDate d = QDate::currentDate();
2463
QString docDate = tr("Date:")+" "+d.toString(Qt::TextDate);
2465
PutPage("1 0 0 1 "+FToStr(maxBoxX / 2.0 + 20.0)+" 6 cm\n");
2467
// PutPage("/"+StdFonts["/Helvetica"]+" 7 Tf\n");
2468
// QDate d = QDate::currentDate();
2469
// PutPage(EncString("("+ tr("Date:")+" "+d.toString(Qt::TextDate)+")",ObjCounter)+" Tj\nET\n");
2470
painter2.addText( QPointF(0.0,0.0), infoFont, docDate );
2471
textPath.fromQPainterPath(painter2);
2472
PutPage(SetClipPathArray(&textPath, true));
2477
Seite.ObjNum = WritePDFStream(Content);
2479
if (Options.Version >= 14)
2483
PutDoc("<< /S /Transparency\n");
2485
PutDoc("/CS /DeviceRGB\n");
2488
if (Options.isGrayscale)
2489
PutDoc("/CS /DeviceGray\n");
2492
if ((doc.HasCMS) && (Options.UseProfiles))
2493
PutDoc("/CS "+ICCProfiles[Options.SolidProf].ICCArray+"\n");
2495
PutDoc("/CS /DeviceCMYK\n");
2498
PutDoc(">>\nendobj\n");
2500
uint pageObject = newObject();
2501
StartObj(pageObject);
2502
PutDoc("<<\n/Type /Page\n/Parent 4 0 R\n");
2503
PutDoc("/MediaBox [0 0 "+FToStr(maxBoxX)+" "+FToStr(maxBoxY)+"]\n");
2504
PutDoc("/BleedBox ["+FToStr(markOffs)+" "+FToStr(markOffs)+" "+FToStr(maxBoxX-markOffs)+" "+FToStr(maxBoxY-markOffs)+"]\n");
2505
PutDoc("/CropBox [0 0 "+FToStr(maxBoxX)+" "+FToStr(maxBoxY)+"]\n");
2506
PutDoc("/TrimBox ["+FToStr(bleedLeft+markOffs)+" "+FToStr(Options.bleeds.Bottom+markOffs)+" "+FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(maxBoxY-Options.bleeds.Top-markOffs)+"]\n");
2507
if (Options.Version >= PDFOptions::PDFVersion_13) // PDF/X forbids having both art and trim box!
2508
PutDoc("/ArtBox ["+FToStr(bleedLeft+markOffs)+" "+FToStr(Options.bleeds.Bottom+markOffs)+" "+FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(maxBoxY-Options.bleeds.Top-markOffs)+"]\n");
2509
PutDoc("/Rotate "+QString::number(Options.RotateDeg)+"\n");
2510
PutDoc("/Contents "+QString::number(Seite.ObjNum)+" 0 R\n");
2511
if (Options.Version >= PDFOptions::PDFVersion_14) // && (Transpar.count() != 0))
2512
PutDoc("/Group "+QString::number(Gobj)+" 0 R\n");
2513
if (Options.Thumbnails)
2514
PutDoc("/Thumb "+QString::number(Seite.Thumb)+" 0 R\n");
2515
if (Seite.AObjects.count() != 0)
2517
PutDoc("/Annots [ ");
2518
for (int b = 0; b < Seite.AObjects.count(); ++b)
2519
PutDoc(QString::number(Seite.AObjects[b])+" 0 R ");
2522
if (Options.PresentMode)
2524
if (Options.PresentVals[PgNr].pageViewDuration > 0)
2525
PutDoc("/Dur "+QString::number(Options.PresentVals[PgNr].pageViewDuration)+"\n");
2526
if (Options.PresentVals[PgNr].effectType != 0)
2528
PutDoc("/Trans << /Type /Trans\n");
2529
PutDoc("/D "+QString::number(Options.PresentVals[PgNr].pageEffectDuration)+"\n");
2530
switch (Options.PresentVals[PgNr].effectType)
2533
PutDoc("/S /Blinds\n");
2534
PutDoc(Options.PresentVals[PgNr].Dm == 0 ? "/Dm /H\n" : "/Dm /V\n");
2537
PutDoc("/S /Box\n");
2538
PutDoc(Options.PresentVals[PgNr].M == 0 ? "/M /I\n" : "/M /O\n");
2541
PutDoc("/S /Dissolve\n");
2544
PutDoc("/S /Glitter\n");
2546
switch (Options.PresentVals[PgNr].Di)
2564
PutDoc("/S /Split\n");
2565
PutDoc(Options.PresentVals[PgNr].Dm == 0 ? "/Dm /H\n" : "/Dm /V\n");
2566
PutDoc(Options.PresentVals[PgNr].M == 0 ? "/M /I\n" : "/M /O\n");
2569
PutDoc("/S /Wipe\n");
2571
switch (Options.PresentVals[PgNr].Di)
2592
PutDoc("/S /Push\n");
2594
switch (Options.PresentVals[PgNr].Di)
2615
PutDoc("/S /Cover\n");
2617
switch (Options.PresentVals[PgNr].Di)
2638
PutDoc("/S /Uncover\n");
2640
switch (Options.PresentVals[PgNr].Di)
2661
PutDoc("/S /Fade\n");
2667
PutDoc(">>\nendobj\n");
2669
PageTree.Kids[physPage] = pageObject;
2673
void PDFLibCore::writeXObject(uint objNr, QString dictionary, QByteArray stream)
2678
PutDoc(">>\nstream\n");
2679
EncodeArrayToStream(stream, objNr);
2680
PutDoc("\nendstream\nendobj\n");
2684
uint PDFLibCore::writeObject(QString type, QString dictionary)
2686
uint result = newObject();
2689
if (!type.isEmpty())
2690
PutDoc("/Type " + type + "\n");
2692
PutDoc(">>\nendobj\n");
2697
bool PDFLibCore::PDF_ProcessPage(const Page* pag, uint PNr, bool clip)
2699
QStack<PageItem*> groupStack;
2700
QStack<PageItem*> groupStackS;
2701
QStack<QString> groupDataStack;
2702
QString tmp, output;
2705
QList<PageItem*> PItems;
2708
ll.isPrintable = false;
2711
PutPage("/"+HTName+" gs\n");
2712
double bleedRight = 0.0;
2713
double bleedLeft = 0.0;
2714
double markOffs = 0.0;
2715
bleedDisplacementX = 0.0;
2716
bleedDisplacementY = 0.0;
2717
PutPage("q\n"); // Save
2718
if ((Options.cropMarks) || (Options.bleedMarks) || (Options.registrationMarks) || (Options.colorMarks) || (Options.docInfoMarks))
2719
markOffs = 20.0 + Options.markOffset;
2720
// #8773 - incorrect page position if MPageNam.isEmpty()
2721
/*if (!pag->MPageNam.isEmpty())
2723
getBleeds(ActPageP, bleedLeft, bleedRight);
2724
PutPage("1 0 0 1 "+FToStr(bleedLeft+markOffs)+" "+FToStr(Options.bleeds.Bottom+markOffs)+" cm\n");
2725
bleedDisplacementX = bleedLeft+markOffs;
2726
bleedDisplacementY = Options.bleeds.Bottom+markOffs;
2728
if ( (Options.MirrorH) && (!pag->MPageNam.isEmpty()) )
2729
PutPage("-1 0 0 1 "+FToStr(ActPageP->width())+" 0 cm\n");
2730
if ( (Options.MirrorV) && (!pag->MPageNam.isEmpty()) )
2731
PutPage("1 0 0 -1 0 "+FToStr(ActPageP->height())+" cm\n");
2734
double maxBoxX = ActPageP->width() - ActPageP->Margins.Right - ActPageP->Margins.Left;
2735
double maxBoxY = ActPageP->height() - ActPageP->Margins.Top - ActPageP->Margins.Bottom;
2736
PutPage(FToStr(ActPageP->Margins.Left)+" "+FToStr(ActPageP->Margins.Bottom)+" "+FToStr(maxBoxX)+" "+FToStr(maxBoxY)+" re W n\n");
2737
// PutPage("0 0 "+FToStr(ActPageP->width())+" "+FToStr(ActPageP->height())+" re W n\n");
2739
if (!pag->MPageNam.isEmpty())
2741
const Page* mPage = doc.MasterPages.at(doc.MasterNames[doc.DocPages.at(PNr)->MPageNam]);
2742
int mPageIndex = doc.MasterPages.indexOf((Page* const) mPage) + 1;
2743
if (doc.MasterItems.count() != 0)
2745
if (!Options.MirrorH)
2746
PutPage("1 0 0 1 0 0 cm\n");
2747
for (int lam = 0; lam < doc.Layers.count() && !abortExport; ++lam)
2749
doc.Layers.levelToLayer(ll, Lnr);
2751
if ((ll.isPrintable) || ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers)))
2753
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
2754
PutPage("/OC /"+OCGEntries[ll.Name].Name+" BDC\n");
2755
for (int am = 0; am < pag->FromMaster.count() && !abortExport; ++am)
2757
ite = pag->FromMaster.at(am);
2759
qApp->processEvents();
2760
if ((ite->LayerNr != ll.LNr) || (!ite->printEnabled()))
2762
if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
2764
QString name = QString("/master_page_obj_%1_%2").arg(mPageIndex).arg(ite->ItemNr);
2765
if (ite->isGroupControl)
2768
FPointArray cl = ite->PoLine.copy();
2769
FPointArray clb = ite->PoLine.copy();
2771
mm.translate(ite->xPos() - mPage->xOffset(), (ite->yPos() - mPage->yOffset()) - mPage->height());
2772
mm.rotate(ite->rotation());
2775
PutPage(SetClipPath(ite));
2776
PutPage("h W* n\n");
2777
groupStack.push(ite->groupsLastItem);
2778
ite->PoLine = clb.copy();
2781
if (! ite->asTextFrame())
2782
PutPage(name+" Do\n");
2785
double oldX = ite->xPos();
2786
double oldY = ite->yPos();
2787
double OldBX = ite->BoundingX;
2788
double OldBY = ite->BoundingY;
2789
ite->setXPos(ite->xPos() - mPage->xOffset() + pag->xOffset(), true);
2790
ite->setYPos(ite->yPos() - mPage->yOffset() + pag->yOffset(), true);
2791
if (!PDF_ProcessItem(output, ite, pag, pag->pageNr()))
2794
ite->setXYPos(oldX, oldY, true);
2795
ite->BoundingX = OldBX;
2796
ite->BoundingY = OldBY;
2798
if (groupStack.count() != 0)
2800
while (ite == groupStack.top())
2804
if (groupStack.count() == 0)
2809
for (int am = 0; am < pag->FromMaster.count(); ++am)
2811
ite = pag->FromMaster.at(am);
2812
if ((ite->LayerNr != ll.LNr) || (!ite->printEnabled()))
2814
if (ite->ChangedMasterItem)
2816
if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
2818
if (!ite->isTableItem)
2820
double oldX = ite->xPos();
2821
double oldY = ite->yPos();
2822
double OldBX = ite->BoundingX;
2823
double OldBY = ite->BoundingY;
2824
ite->setXPos(ite->xPos() - mPage->xOffset() + pag->xOffset(), true);
2825
ite->setYPos(ite->yPos() - mPage->yOffset() + pag->yOffset(), true);
2826
PutPage(PDF_ProcessTableItem(ite, pag));
2827
ite->setXYPos(oldX, oldY, true);
2828
ite->BoundingX = OldBX;
2829
ite->BoundingY = OldBY;
2831
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
2837
ll.isPrintable = false;
2840
//CB *2 because the Pitems count loop runs twice.. y.. dunno.
2841
if (usingGUI && pag->pageName().isEmpty())
2842
progressDialog->setProgress("ECPI", 0, doc.DocItems.count()*2);
2843
int pc_exportpagesitems=0;
2844
PItems = (pag->pageName().isEmpty()) ? doc.DocItems : doc.MasterItems;
2845
for (int la = 0; la < doc.Layers.count() && !abortExport; ++la)
2847
doc.Layers.levelToLayer(ll, Lnr);
2848
if ((ll.isPrintable) || ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers)))
2851
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
2852
PutPage("/OC /"+OCGEntries[ll.Name].Name+" BDC\n");
2853
for (int a = 0; a < PItems.count() && !abortExport; ++a)
2857
progressDialog->setProgress("ECPI", ++pc_exportpagesitems);
2858
qApp->processEvents();
2861
if (ite->LayerNr != ll.LNr)
2864
if (ite->isGroupControl)
2867
FPointArray cl = ite->PoLine.copy();
2868
FPointArray clb = ite->PoLine.copy();
2870
mm.translate(ite->xPos() - pag->xOffset(), (ite->yPos() - pag->yOffset()) - pag->height());
2871
mm.rotate(ite->rotation());
2874
grcon += SetClipPath(ite);
2875
grcon += "h W* n\n";
2876
groupStack.push(ite->groupsLastItem);
2877
groupStackS.push(ite);
2878
if (((ll.transparency != 1) || (ll.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2881
groupDataStack.push(inh);
2887
groupDataStack.push(Content);
2890
ite->PoLine = clb.copy();
2893
if (!PDF_ProcessItem(output, ite, pag, PNr))
2895
if (((ll.transparency != 1) || (ll.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2899
if (groupStack.count() != 0)
2901
while (ite == groupStack.top())
2904
PageItem *controlItem = groupStackS.pop();
2905
if (((ll.transparency != 1) || (ll.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2908
inh = groupDataStack.pop();
2909
if (Options.Version >= PDFOptions::PDFVersion_14)
2910
inh += Write_TransparencyGroup(controlItem->fillTransparency(), controlItem->fillBlendmode(), tmpData);
2918
Content = groupDataStack.pop();
2919
if (Options.Version >= PDFOptions::PDFVersion_14)
2920
Content += Write_TransparencyGroup(controlItem->fillTransparency(), controlItem->fillBlendmode(), tmpData);
2926
if (groupStack.count() == 0)
2931
for (int a = 0; a < PItems.count() && !abortExport; ++a)
2935
progressDialog->setProgress("ECPI", ++pc_exportpagesitems);
2936
qApp->processEvents();
2939
if (ite->LayerNr != ll.LNr)
2941
if (!ite->isTableItem)
2943
double bLeft, bRight, bBottom, bTop;
2944
getBleeds(ActPageP, bLeft, bRight, bBottom, bTop);
2945
double x = pag->xOffset() - bLeft;
2946
double y = pag->yOffset() - bTop;
2947
double w = pag->width() + bLeft + bRight;
2948
double h1 = pag->height() + bBottom + bTop;
2949
double ilw= ite->lineWidth();
2950
double x2 = ite->BoundingX - ilw / 2.0;
2951
double y2 = ite->BoundingY - ilw / 2.0;
2952
double w2 = qMax(ite->BoundingW + ilw, 1.0);
2953
double h2 = qMax(ite->BoundingH + ilw, 1.0);
2954
if (!( qMax( x, x2 ) <= qMin( x+w, x2+w2 ) && qMax( y, y2 ) <= qMin( y+h1, y2+h2 )))
2956
if (ite->ChangedMasterItem)
2958
if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
2960
if (!ite->printEnabled())
2962
if (((ll.transparency != 1) || (ll.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2963
inh += PDF_ProcessTableItem(ite, pag);
2965
PutPage(PDF_ProcessTableItem(ite, pag));
2967
if (((ll.transparency != 1) || (ll.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2969
int Gobj = newObject();
2971
PutDoc("<< /Type /Group\n");
2972
PutDoc("/S /Transparency\n");
2973
PutDoc("/I false\n");
2974
PutDoc("/K false\n");
2975
PutDoc(">>\nendobj\n");
2976
QString ShName = ResNam+QString::number(ResCount);
2978
Transpar[ShName] = writeGState("/CA "+FToStr(ll.transparency)+"\n"
2979
+ "/ca "+FToStr(ll.transparency)+"\n"
2980
+ "/SMask /None\n/AIS false\n/OPM 1\n"
2981
+ "/BM /" + blendMode(ll.blendMode) + "\n");
2982
uint formObject = newObject();
2983
StartObj(formObject);
2984
PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1\n");
2985
double bleedRight = 0.0;
2986
double bleedLeft = 0.0;
2987
getBleeds(ActPageP, bleedLeft, bleedRight);
2988
double maxBoxX = ActPageP->width()+bleedRight+bleedLeft;
2989
double maxBoxY = ActPageP->height()+Options.bleeds.Top+Options.bleeds.Bottom;
2990
PutDoc("/BBox [ "+FToStr(-bleedLeft)+" "+FToStr(-Options.bleeds.Bottom)+" "+FToStr(maxBoxX)+" "+FToStr(maxBoxY)+" ]\n");
2991
PutDoc("/Group "+QString::number(Gobj)+" 0 R\n");
2992
if (Options.Compress)
2993
inh = CompressStr(&inh);
2994
PutDoc("/Length "+QString::number(inh.length()+1));
2995
if (Options.Compress)
2996
PutDoc("\n/Filter /FlateDecode");
2997
PutDoc(" >>\nstream\n"+EncStream(inh, formObject)+"\nendstream\nendobj\n");
2998
QString name = ll.Name.simplified().replace(QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_") + QString::number(ll.LNr) + QString::number(PNr);
2999
Seite.XObjects[name] = formObject;
3001
PutPage("/"+ShName+" gs\n");
3002
PutPage("/"+name+" Do\n");
3005
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
3010
PutPage("Q\n"); // Restore
3014
QString PDFLibCore::Write_TransparencyGroup(double trans, int blend, QString &data)
3016
QString retString = "";
3017
int Gobj = newObject();
3019
PutDoc("<< /Type /Group\n");
3020
PutDoc("/S /Transparency\n");
3021
PutDoc("/I false\n");
3022
PutDoc("/K false\n");
3023
PutDoc(">>\nendobj\n");
3024
QString ShName = ResNam+QString::number(ResCount);
3026
Transpar[ShName] = writeGState("/CA "+FToStr(1.0 - trans)+"\n"
3027
+ "/ca "+FToStr(1.0 - trans)+"\n"
3028
+ "/SMask /None\n/AIS false\n/OPM 1\n"
3029
+ "/BM /" + blendMode(blend) + "\n");
3030
uint formObject = newObject();
3031
StartObj(formObject);
3032
PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1\n");
3033
double bleedRight = 0.0;
3034
double bleedLeft = 0.0;
3035
getBleeds(ActPageP, bleedLeft, bleedRight);
3036
double maxBoxX = ActPageP->width()+bleedRight+bleedLeft;
3037
double maxBoxY = ActPageP->height()+Options.bleeds.Top+Options.bleeds.Bottom;
3038
PutDoc("/BBox [ "+FToStr(-bleedLeft)+" "+FToStr(-Options.bleeds.Bottom)+" "+FToStr(maxBoxX)+" "+FToStr(maxBoxY)+" ]\n");
3039
PutDoc("/Group "+QString::number(Gobj)+" 0 R\n");
3040
if (Options.Compress)
3041
data = CompressStr(&data);
3042
PutDoc("/Length "+QString::number(data.length()+1));
3043
if (Options.Compress)
3044
PutDoc("\n/Filter /FlateDecode");
3045
PutDoc(" >>\nstream\n"+EncStream(data, formObject)+"\nendstream\nendobj\n");
3046
QString name = ResNam+QString::number(ResCount);
3048
Seite.XObjects[name] = formObject;
3050
retString += "/"+ShName+" gs\n";
3051
retString += "/"+name+" Do\n";
3056
QString PDFLibCore::PDF_ProcessTableItem(PageItem* ite, const Page* pag)
3058
if ((ite->lineColor() == CommonStrings::None) || (ite->lineWidth() == 0.0))
3062
if ((ite->doOverprint) && (!Options.UseRGB))
3064
QString ShName = ResNam+QString::number(ResCount);
3066
Transpar[ShName] = writeGState("/OP true\n"
3069
tmp += "/"+ShName+" gs\n";
3071
// if (((ite->fillTransparency() != 0) || (ite->lineTransparency() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3072
// tmp += PDF_Transparenz(ite);
3073
// if (ite->fillColor() != CommonStrings::None)
3074
// tmp += putColor(ite->fillColor(), ite->fillShade(), true);
3075
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3076
tmp += PDF_TransparenzStroke(ite);
3077
if (ite->lineColor() != CommonStrings::None)
3078
tmp += putColor(ite->lineColor(), ite->lineShade(), false);
3079
tmp += FToStr(fabs(ite->lineWidth()))+" w\n";
3080
if (ite->DashValues.count() != 0)
3083
QVector<double>::iterator it;
3084
for ( it = ite->DashValues.begin(); it != ite->DashValues.end(); ++it )
3086
int da = static_cast<int>(*it);
3087
// #8758: Custom dotted lines don't export properly to pdf
3088
// Null values have to be exported if line end != flat
3089
if ((da != 0) || (ite->lineEnd() != Qt::FlatCap))
3090
tmp += QString::number(da)+" ";
3092
tmp += "] "+QString::number(static_cast<int>(ite->DashOffset))+" d\n";
3095
tmp += "["+getDashString(ite->PLineArt, ite->lineWidth())+"] 0 d\n";
3097
switch (ite->PLineJoin)
3112
tmp += "1 0 0 1 "+FToStr(ite->xPos() - pag->xOffset())+" "+FToStr(pag->height() - (ite->yPos() - pag->yOffset()))+" cm\n";
3113
if (ite->rotation() != 0)
3115
double sr = sin(-ite->rotation()* M_PI / 180.0);
3116
double cr = cos(-ite->rotation()* M_PI / 180.0);
3117
if ((cr * cr) < 0.000001)
3119
if ((sr * sr) < 0.000001)
3121
tmp += FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+ " 0 0 cm\n";
3123
if ((ite->TopLine) || (ite->RightLine) || (ite->BottomLine) || (ite->LeftLine))
3128
tmp += FToStr(ite->width())+" 0 l\n";
3132
tmp += FToStr(ite->width())+" 0 m\n";
3133
tmp += FToStr(ite->width())+" "+FToStr(-ite->height())+" l\n";
3135
if (ite->BottomLine)
3137
tmp += "0 "+FToStr(-ite->height())+" m\n";
3138
tmp += FToStr(ite->width())+" "+FToStr(-ite->height())+" l\n";
3143
tmp += "0 "+FToStr(-ite->height())+" l\n";
3151
bool PDFLibCore::PDF_ProcessItem(QString& output, PageItem* ite, const Page* pag, uint PNr, bool embedded, bool pattern)
3153
QString tmp(""), tmpOut;
3154
ite->setRedrawBounding();
3155
double bLeft, bRight, bBottom, bTop;
3156
getBleeds(pag, bLeft, bRight, bBottom, bTop);
3157
double x = pag->xOffset() - bLeft;
3158
double y = pag->yOffset() - bTop;
3159
double w = pag->width() + bLeft + bRight;
3160
double h1 = pag->height()+ bBottom + bTop;
3161
double ilw=ite->lineWidth();
3162
double x2 = ite->BoundingX - ilw / 2.0;
3163
double y2 = ite->BoundingY - ilw / 2.0;
3164
double w2 = qMax(ite->BoundingW + ilw, 1.0);
3165
double h2 = qMax(ite->BoundingH + ilw, 1.0);
3169
// qDebug() << QString("pdflib process item: pagename=%1 ownpage=%2 pagenr=%3 changedMP=%4").arg(pag->pageName()).arg(ite->OwnPage).arg(pag->pageNr()).arg(ite->ChangedMasterItem);
3170
// qDebug() << QString("pdflib process item: x=%1 x2=%2 y=%3 y2=%4 w=%5 w2=%6 h1=%7 h2=%8 ilw=%9").arg(x).arg(x2).arg(y).arg(y2).arg(w).arg(w2).arg(h1).arg(h2).arg(ilw);
3171
if (!( qMax( x, x2 ) <= qMin( x+w, x2+w2 ) && qMax( y, y2 ) <= qMin( y+h1, y2+h2 )) && !embedded)
3176
// qDebug() << "bb test done";
3177
if (ite->ChangedMasterItem)
3182
if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
3190
if ((ite->doOverprint) && (!Options.UseRGB))
3192
QString ShName = ResNam+QString::number(ResCount);
3194
Transpar[ShName] = writeGState("/OP true\n"
3197
tmp += "/"+ShName+" gs\n";
3199
// if (((ite->fillTransparency() != 0) || (ite->lineTransparency() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3200
// tmp += PDF_Transparenz(ite);
3201
if ((ite->isBookmark) && (Options.Bookmarks))
3202
PDF_Bookmark(ite, pag->height() - (ite->yPos() - pag->yOffset()));
3205
if (!ite->printEnabled() || ((ite->itemType() == PageItem::TextFrame) && (!pag->pageName().isEmpty())))
3207
// qDebug() << "Q exit";
3213
if (ite->fillColor() != CommonStrings::None)
3214
tmp += putColor(ite->fillColor(), ite->fillShade(), true);
3215
if (ite->lineColor() != CommonStrings::None)
3216
tmp += putColor(ite->lineColor(), ite->lineShade(), false);
3217
tmp += FToStr(fabs(ite->lineWidth()))+" w\n";
3218
if (ite->DashValues.count() != 0)
3221
QVector<double>::iterator it;
3222
for ( it = ite->DashValues.begin(); it != ite->DashValues.end(); ++it )
3224
int da = static_cast<int>(*it);
3225
// #8758: Custom dotted lines don't export properly to pdf
3226
// Null values have to be exported if line end != flat
3227
if ((da != 0) || (ite->lineEnd() != Qt::FlatCap))
3228
tmp += QString::number(da)+" ";
3230
tmp += "] "+QString::number(static_cast<int>(ite->DashOffset))+" d\n";
3233
tmp += "["+getDashString(ite->PLineArt, ite->lineWidth())+"] 0 d\n";
3234
switch (ite->PLineEnd)
3249
switch (ite->PLineJoin)
3266
tmp += "1 0 0 1 "+FToStr(ite->xPos() - pag->xOffset())+" "+FToStr(pag->height() - (ite->yPos() - pag->yOffset()))+" cm\n";
3268
if (ite->rotation() != 0)
3270
double sr = sin(-ite->rotation()* M_PI / 180.0);
3271
double cr = cos(-ite->rotation()* M_PI / 180.0);
3272
if ((cr * cr) < 0.000001)
3274
if ((sr * sr) < 0.000001)
3276
tmp += FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+" 0 0 cm\n";
3278
switch (ite->itemType())
3280
case PageItem::ImageFrame:
3281
case PageItem::LatexFrame:
3282
// Same functions as for ImageFrames work for LatexFrames too
3283
if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3284
tmp += PDF_TransparenzFill(ite);
3285
if ((ite->fillColor() != CommonStrings::None) || (ite->GrType != 0))
3287
if (ite->GrType != 0)
3289
if (!PDF_Gradient(tmpOut, ite))
3295
tmp += SetClipPath(ite);
3300
if (ite->imageClip.size() != 0)
3302
tmp += SetClipPathImage(ite);
3303
tmp += "h\nW*\nn\n";
3305
tmp += SetClipPath(ite);
3306
tmp += "h\nW*\nn\n";
3307
if (ite->imageFlippedH())
3308
tmp += "-1 0 0 1 "+FToStr(ite->width())+" 0 cm\n";
3309
if (ite->imageFlippedV())
3310
tmp += "1 0 0 -1 0 "+FToStr(-ite->height())+" cm\n";
3311
if ((ite->PictureIsAvailable) && (!ite->Pfile.isEmpty()))
3313
if (!PDF_Image(ite, ite->Pfile, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), false, ite->IProfile, ite->UseEmbedded, ite->IRender, &tmpOut))
3318
if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
3320
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3321
tmp += PDF_TransparenzStroke(ite);
3322
if (ite->NamedLStyle.isEmpty()) //&& (ite->lineWidth() != 0.0))
3324
if (ite->lineColor() != CommonStrings::None)
3326
tmp += SetClipPath(ite);
3332
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3333
for (int it = ml.size()-1; it > -1; it--)
3335
if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3337
tmp += setStrokeMulti(&ml[it]);
3338
tmp += SetClipPath(ite);
3345
case PageItem::TextFrame:
3346
// qDebug() << "case TextFrame";
3347
if ((ite->isAnnotation()) && (Options.Version != PDFOptions::PDFVersion_X3))
3349
// qDebug() << "Annotation";
3350
if (!PDF_Annotation(ite, PNr))
3354
if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3355
tmp += PDF_TransparenzFill(ite);
3356
if ((ite->fillColor() != CommonStrings::None) || (ite->GrType != 0))
3358
if (ite->GrType != 0)
3360
if (!PDF_Gradient(tmpOut, ite))
3366
tmp += SetClipPath(ite);
3371
if (ite->imageFlippedH())
3372
tmp += "-1 0 0 1 "+FToStr(ite->width())+" 0 cm\n";
3373
if (ite->imageFlippedV())
3374
tmp += "1 0 0 -1 0 "+FToStr(-ite->height())+" cm\n";
3375
tmp += setTextSt(ite, PNr, pag);
3377
if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
3379
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3380
tmp += PDF_TransparenzStroke(ite);
3381
if (ite->NamedLStyle.isEmpty()) //&& (ite->lineWidth() != 0.0))
3383
if (ite->lineColor() != CommonStrings::None)
3385
tmp += SetClipPath(ite);
3391
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3392
for (int it = ml.size()-1; it > -1; it--)
3394
if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3396
tmp += setStrokeMulti(&ml[it]);
3397
tmp += SetClipPath(ite);
3404
case PageItem::Line:
3405
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3406
tmp += PDF_TransparenzStroke(ite);
3407
if (ite->NamedLStyle.isEmpty())
3409
if (ite->lineColor() != CommonStrings::None)
3412
tmp += FToStr(ite->width())+" 0 l\n";
3418
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3419
for (int it = ml.size()-1; it > -1; it--)
3421
if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3423
tmp += setStrokeMulti(&ml[it]);
3425
tmp += FToStr(ite->width())+" 0 l\n";
3430
if (ite->startArrowIndex() != 0)
3433
arrowTrans.scale(-1,1);
3434
tmp += drawArrow(ite, arrowTrans, ite->startArrowIndex());
3436
if (ite->endArrowIndex() != 0)
3439
arrowTrans.translate(ite->width(), 0);
3440
tmp += drawArrow(ite, arrowTrans, ite->endArrowIndex());
3443
case PageItem::ItemType1:
3444
case PageItem::ItemType3:
3445
case PageItem::Polygon:
3446
if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3447
tmp += PDF_TransparenzFill(ite);
3448
if (ite->GrType != 0)
3450
if (!PDF_Gradient(tmpOut, ite))
3456
if (ite->fillColor() != CommonStrings::None)
3458
tmp += SetClipPath(ite);
3465
if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3467
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3468
tmp += PDF_TransparenzStroke(ite);
3469
if (ite->NamedLStyle.isEmpty()) //&& (ite->lineWidth() != 0.0))
3471
if (ite->lineColor() != CommonStrings::None)
3473
tmp += SetClipPath(ite);
3479
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3480
for (int it = ml.size()-1; it > -1; it--)
3482
if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3484
tmp += setStrokeMulti(&ml[it]);
3485
tmp += SetClipPath(ite);
3492
case PageItem::PolyLine:
3493
if (ite->PoLine.size() > 4) // && ((ite->PoLine.point(0) != ite->PoLine.point(1)) || (ite->PoLine.point(2) != ite->PoLine.point(3))))
3495
if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3496
tmp += PDF_TransparenzFill(ite);
3497
if (ite->GrType != 0)
3499
if (!PDF_Gradient(tmpOut, ite))
3505
if (ite->fillColor() != CommonStrings::None)
3507
tmp += SetClipPath(ite);
3512
if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3514
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3515
tmp += PDF_TransparenzStroke(ite);
3516
if (ite->NamedLStyle.isEmpty()) //&& (ite->lineWidth() != 0.0))
3518
if (ite->lineColor() != CommonStrings::None)
3520
tmp += SetClipPath(ite, false);
3526
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3527
for (int it = ml.size()-1; it > -1; it--)
3529
if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3531
tmp += setStrokeMulti(&ml[it]);
3532
tmp += SetClipPath(ite, false);
3538
if (ite->startArrowIndex() != 0)
3540
FPoint Start = ite->PoLine.point(0);
3541
for (uint xx = 1; xx < ite->PoLine.size(); xx += 2)
3543
FPoint Vector = ite->PoLine.point(xx);
3544
if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
3546
double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
3548
arrowTrans.translate(Start.x(), Start.y());
3549
arrowTrans.rotate(r);
3550
tmp += drawArrow(ite, arrowTrans, ite->startArrowIndex());
3555
if (ite->endArrowIndex() != 0)
3557
FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
3558
for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
3560
FPoint Vector = ite->PoLine.point(xx);
3561
if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
3563
double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
3565
arrowTrans.translate(End.x(), End.y());
3566
arrowTrans.rotate(r);
3567
tmp += drawArrow(ite, arrowTrans, ite->endArrowIndex());
3573
case PageItem::PathText:
3576
if (ite->PoLine.size() > 3)
3579
if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3581
if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3582
tmp += PDF_TransparenzStroke(ite);
3583
if (ite->NamedLStyle.isEmpty()) //&& (ite->lineWidth() != 0.0))
3585
if (ite->lineColor() != CommonStrings::None)
3587
tmp += SetClipPath(ite, false);
3593
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3594
for (int it = ml.size()-1; it > -1; it--)
3596
if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3598
tmp += setStrokeMulti(&ml[it]);
3599
tmp += SetClipPath(ite, false);
3608
if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3609
tmp += PDF_TransparenzFill(ite);
3610
tmp += setTextSt(ite, PNr, pag);
3612
case PageItem::Multiple:
3621
QString PDFLibCore::drawArrow(PageItem *ite, QMatrix &arrowTrans, int arrowIndex)
3624
FPointArray arrow = doc.arrowStyles.at(arrowIndex-1).points.copy();
3625
if (ite->NamedLStyle.isEmpty())
3627
if (ite->lineWidth() != 0.0)
3628
arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3632
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3633
if (ml[ml.size()-1].Width != 0.0)
3634
arrowTrans.scale(ml[ml.size()-1].Width, ml[ml.size()-1].Width);
3636
arrow.map(arrowTrans);
3637
if ((ite->lineTransparency() != 0) && (Options.Version >= PDFOptions::PDFVersion_14))
3639
QString ShName = ResNam+QString::number(ResCount);
3641
Transpar[ShName] = writeGState("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n"
3642
+ "/ca "+FToStr(1.0 - ite->lineTransparency())+"\n"
3643
+ "/SMask /None\n/AIS false\n/OPM 1\n"
3645
tmp += "/"+ShName+" gs\n";
3647
if (ite->NamedLStyle.isEmpty())
3649
if (ite->lineColor() != CommonStrings::None)
3651
tmp += putColor(ite->lineColor(), ite->lineShade(), true);
3652
tmp += SetClipPathArray(&arrow);
3658
multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3659
if (ml[0].Color != CommonStrings::None)
3661
tmp += putColor(ml[0].Color, ml[0].Shade, true);
3662
tmp += SetClipPathArray(&arrow);
3665
for (int it = ml.size()-1; it > 0; it--)
3667
if (ml[it].Color != CommonStrings::None)
3669
tmp += setStrokeMulti(&ml[it]);
3670
tmp += SetClipPathArray(&arrow);
3678
QString PDFLibCore::putColor(const QString& color, double shade, bool fill)
3681
QString colString = SetColor(color, shade);
3683
tmpC = doc.PageColors[color];
3684
if (((tmpC.isSpotColor()) || (tmpC.isRegistrationColor())) && ((Options.isGrayscale == false) && (Options.UseRGB == false)) && (Options.UseSpotColors))
3686
if ((color != CommonStrings::None) && (spotMap.contains(color)))
3690
tmp += "/"+spotMap[color].ResName+" cs\n";
3691
tmp += FToStr(shade / 100.0)+" scn\n";
3695
tmp += "/"+spotMap[color].ResName+" CS\n";
3696
tmp += FToStr(shade / 100.0)+" SCN\n";
3701
if (Options.isGrayscale)
3703
if (color != CommonStrings::None)
3706
tmp += colString+" g\n";
3708
tmp += colString+" G\n";
3714
if (color != CommonStrings::None)
3717
tmp += colString+" rg\n";
3719
tmp += colString+" RG\n";
3724
if ((doc.HasCMS) && (Options.UseProfiles))
3726
if (tmpC.getColorModel() == colorModelCMYK)
3728
if (color != CommonStrings::None)
3731
tmp += colString+" k\n";
3733
tmp += colString+" K\n";
3738
QString tmp2[] = {"/Perceptual", "/RelativeColorimetric", "/Saturation", "/AbsoluteColorimetric"};
3739
tmp += tmp2[Options.Intent]+ " ri\n";
3740
if (color != CommonStrings::None)
3744
tmp += "/"+ICCProfiles[Options.SolidProf].ResName+" cs\n";
3745
tmp += colString+" scn\n";
3749
tmp += "/"+ICCProfiles[Options.SolidProf].ResName+" CS\n";
3750
tmp += colString+" SCN\n";
3757
if (color != CommonStrings::None)
3760
tmp += colString+" k\n";
3762
tmp += colString+" K\n";
3769
/*CB 2982: cache code is borked somehow, original function is above
3770
QString PDFLibCore::putColor(const QString & colorName, int shade, bool fill)
3772
// Cache of last foreground and background colours We cache fg and bg
3773
// separately because they're alternated so much. The primary purpose of
3774
// this cache is to avoid re-caculating the fg and bg colors on each char
3775
// of text when the color doens't change.
3776
static QString lastFGColorName, lastFGOutput, lastBGColorName, lastBGOutput;
3777
static int lastFGShade = -1, lastBGShade = -1;
3778
if (fill && colorName == lastBGColorName && shade == lastBGShade)
3779
return lastBGOutput;
3780
else if (colorName == lastFGColorName && shade == lastFGShade)
3781
return lastFGOutput;
3782
// Cache miss, generate the color
3785
lastBGColorName = colorName;
3786
lastBGShade = shade;
3787
lastBGOutput = putColorUncached(colorName, shade, fill);
3788
return lastBGOutput;
3792
lastFGColorName = colorName;
3793
lastFGShade = shade;
3794
lastFGOutput = putColorUncached(colorName, shade, fill);
3795
return lastFGOutput;
3800
QString PDFLibCore::putColorUncached(const QString& color, int shade, bool fill)
3802
ScColor tmpC(doc.PageColors[color]);
3803
if (((tmpC.isSpotColor()) || (tmpC.isRegistrationColor())) && ((Options.isGrayscale == false) && (Options.UseRGB == false)) && (Options.UseSpotColors))
3805
QString tmpSpot("");
3806
if ((color != CommonStrings::None) && (spotMap.contains(color)))
3810
tmpSpot += "/"+spotMap[color].ResName+" cs\n";
3811
tmpSpot += FToStr(shade / 100.0)+" scn\n";
3815
tmpSpot += "/"+spotMap[color].ResName+" CS\n";
3816
tmpSpot += FToStr(shade / 100.0)+" SCN\n";
3821
QString colString(SetColor(color, shade));
3822
if (Options.isGrayscale)
3824
QString tmpGray("");
3825
if (color != CommonStrings::None)
3828
tmpGray += colString+" g\n";
3830
tmpGray += colString+" G\n";
3837
if (color != CommonStrings::None)
3840
tmp += colString+" rg\n";
3842
tmp += colString+" RG\n";
3847
if ((doc.HasCMS) && (Options.UseProfiles))
3849
if (tmpC.getColorModel() == colorModelCMYK)
3851
if (color != CommonStrings::None)
3854
tmp += colString+" k\n";
3856
tmp += colString+" K\n";
3861
QString tmp2[] = {"/Perceptual", "/RelativeColorimetric", "/Saturation", "/AbsoluteColorimetric"};
3862
tmp += tmp2[Options.Intent]+ " ri\n";
3863
if (color != CommonStrings::None)
3867
tmp += "/"+ICCProfiles[Options.SolidProf].ResName+" cs\n";
3868
tmp += colString+" scn\n";
3872
tmp += "/"+ICCProfiles[Options.SolidProf].ResName+" CS\n";
3873
tmp += colString+" SCN\n";
3880
if (color != CommonStrings::None)
3883
tmp += colString+" k\n";
3885
tmp += colString+" K\n";
3892
QString PDFLibCore::setStrokeMulti(struct SingleLine *sl)
3895
putColor(sl->Color, sl->Shade, false) +
3896
FToStr(sl->Width)+" w\n"
3898
QString Dt = FToStr(qMax(1*sl->Width, 1.0));
3899
QString Sp = FToStr(qMax(2*sl->Width, 1.0));
3900
QString Da = FToStr(qMax(4*sl->Width, 1.0));
3901
switch (static_cast<Qt::PenStyle>(sl->Dash))
3907
tmp += "["+Da+" "+Sp+"] 0 d\n";
3910
tmp += "["+Dt+" "+Sp+"] 0 d\n";
3912
case Qt::DashDotLine:
3913
tmp += "["+Da+" "+Sp+" "+Dt+" "+Sp+"] 0 d\n";
3915
case Qt::DashDotDotLine:
3916
tmp += "["+Da+" "+Sp+" "+Dt+" "+Sp+" "+Dt+" "+Sp+"] 0 d\n";
3922
switch (static_cast<Qt::PenCapStyle>(sl->LineEnd))
3937
switch (static_cast<Qt::PenJoinStyle>(sl->LineJoin))
3955
// Return a PDF substring representing a PageItem's text
3956
QString PDFLibCore::setTextSt(PageItem *ite, uint PNr, const Page* pag)
3959
int savedOwnPage = ite->OwnPage;
3960
double tabDist = ite->textToFrameDistLeft();
3961
double colLeft = 0.0;
3962
QString tmp(""), tmp2("");
3963
QList<ParagraphStyle::TabRecord> tTabValues;
3966
ite->OwnPage = savedOwnPage;
3967
if (ite->lineColor() != CommonStrings::None)
3968
tabDist += ite->lineWidth() / 2.0;
3970
// Loop over each character (!) in the pageItem...
3971
if (ite->itemType() == PageItem::TextFrame)
3974
for (uint ll=0; ll < ite->itemText.lines(); ++ll)
3976
LineSpec ls = ite->itemText.line(ll);
3977
colLeft = ls.colLeft;
3980
for (int d = ls.firstItem; d <= ls.lastItem; ++d)
3982
const ScText * const hl = ite->itemText.item(d);
3983
const QChar ch = hl->ch;
3984
const CharStyle& chstyle(ite->itemText.charStyle(d));
3985
const ParagraphStyle& pstyle(ite->itemText.paragraphStyle(d));
3986
if ((ch == SpecialChars::PARSEP) || (ch == QChar(10)) || (ch == SpecialChars::LINEBREAK) || (ch == SpecialChars::FRAMEBREAK) || (ch == SpecialChars::COLBREAK))
3988
if (chstyle.effects() & ScStyle_SuppressSpace)
3990
tTabValues = pstyle.tabValues();
3991
if (chstyle.effects() & ScStyle_StartOfLine)
3993
if ((ch == SpecialChars::TAB) && (tTabValues.count() != 0))
3996
const TabLayout* tabLayout = dynamic_cast<const TabLayout*>(hl->glyph.more);
3998
tabFillChar = tabLayout->fillChar;
3999
if (!tabFillChar.isNull())
4002
static_cast<CharStyle&>(hl2) = static_cast<const CharStyle&>(*hl);
4003
const GlyphLayout * const gl = hl->glyph.more;
4004
double scale = gl ? gl->scaleV : 1.0;
4005
double wt = chstyle.font().charWidth(tabFillChar, chstyle.fontSize() * scale / 10.0);
4006
double len = hl->glyph.xadvance;
4007
int coun = static_cast<int>(len / wt);
4008
// #6728 : update code according to fillInTabLeaders() and PageItem::layout() - JG
4009
double sPos = 0.0 /*CurX - len + chstyle.fontSize() / 10.0 * 0.7 + 1*/;
4010
hl2.ch = tabFillChar;
4012
hl2.setScaleH(1000);
4013
hl2.setScaleV(1000);
4014
hl2.glyph.glyph = chstyle.font().char2CMap(tabFillChar);
4015
hl2.glyph.yoffset = hl->glyph.yoffset;
4016
for (int cx = 0; cx < coun; ++cx)
4018
hl2.glyph.xoffset = sPos + wt * cx;
4019
if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
4022
static_cast<CharStyle&>(hl3) = static_cast<const CharStyle&>(hl2);
4023
// Hack to workaround #8446, remove when we can subset OpenType fonts in other
4024
// format as Type 3 (and consequently apply stroke correctly)
4025
hl3.setEffects(hl3.effects() & (~ScStyle_Outline));
4027
hl3.glyph.glyph = hl2.glyph.glyph;
4028
hl3.setFillColor(hl2.strokeColor());
4029
hl3.setFillShade(hl2.strokeShade());
4030
hl3.glyph.yoffset = hl2.glyph.yoffset - (chstyle.fontSize() * chstyle.shadowYOffset() / 10000.0);
4031
hl3.glyph.xoffset = hl2.glyph.xoffset + (chstyle.fontSize() * chstyle.shadowXOffset() / 10000.0);
4032
setTextCh(ite, PNr, CurX, ls.y, d, tmp, tmp2, &hl3, pstyle, pag);
4034
setTextCh(ite, PNr, CurX, ls.y, d, tmp, tmp2, &hl2, pstyle, pag);
4039
if (ch == SpecialChars::TAB)
4041
CurX += hl->glyph.wide();
4044
if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
4048
hl2.glyph.glyph = hl->glyph.glyph;
4049
const GlyphLayout *gl1 = &hl->glyph;
4050
GlyphLayout *gl2 = &hl2.glyph;
4053
gl2->more = new GlyphLayout(*gl1->more);
4054
gl2->more->yoffset -= (chstyle.fontSize() * chstyle.shadowYOffset() / 10000.0);
4055
gl2->more->xoffset += (chstyle.fontSize() * chstyle.shadowXOffset() / 10000.0);
4056
gl2->more->more = NULL;
4060
static_cast<CharStyle&>(hl2) = static_cast<const CharStyle&>(*hl);
4061
// Hack to workaround #8446, remove when we can subset OpenType fonts in other
4062
// format as Type 3 (and consequently apply stroke correctly)
4063
hl2.setEffects(hl2.effects() & (~ScStyle_Outline));
4064
hl2.setFillColor(hl->strokeColor());
4065
hl2.setFillShade(hl->strokeShade());
4066
hl2.glyph.xadvance = hl->glyph.xadvance;
4067
hl2.glyph.yadvance = hl->glyph.yadvance;
4068
hl2.glyph.yoffset = hl->glyph.yoffset - (chstyle.fontSize() * chstyle.shadowYOffset() / 10000.0);
4069
hl2.glyph.xoffset = hl->glyph.xoffset + (chstyle.fontSize() * chstyle.shadowXOffset() / 10000.0);
4070
hl2.glyph.scaleH = hl->glyph.scaleH;
4071
hl2.glyph.scaleV = hl->glyph.scaleV;
4072
setTextCh(ite, PNr, CurX, ls.y, d, tmp, tmp2, &hl2, pstyle, pag);
4074
setTextCh(ite, PNr, CurX, ls.y, d, tmp, tmp2, hl, pstyle, pag);
4075
if (hl->ch == SpecialChars::OBJECT)
4077
InlineFrame& embedded(const_cast<InlineFrame&>(hl->embedded));
4078
CurX += (embedded.getItem()->gWidth + embedded.getItem()->lineWidth()) * hl->glyph.scaleH;
4081
CurX += hl->glyph.wide();
4089
for (int d = ite->firstInFrame(); d <= ite->lastInFrame(); ++d)
4091
const ScText * const hl = ite->itemText.item(d);
4092
const QChar ch = hl->ch;
4093
const CharStyle& chstyle(ite->itemText.charStyle(d));
4094
const ParagraphStyle& pstyle(ite->itemText.paragraphStyle(d));
4095
if ((ch == SpecialChars::PARSEP) || (ch == QChar(10)) || (ch == SpecialChars::LINEBREAK) || (ch == SpecialChars::FRAMEBREAK) || (ch == SpecialChars::COLBREAK))
4097
if (chstyle.effects() & ScStyle_SuppressSpace)
4099
tTabValues = pstyle.tabValues();
4100
if (chstyle.effects() & ScStyle_StartOfLine)
4102
if ((ch == SpecialChars::TAB) && (tTabValues.count() != 0))
4104
if ((tabCc < tTabValues.count()) && (!tTabValues[tabCc].tabFillChar.isNull()))
4107
static_cast<CharStyle&>(hl2) = static_cast<const CharStyle&>(*hl);
4108
double wt = chstyle.font().charWidth(tTabValues[tabCc].tabFillChar, chstyle.fontSize());
4109
int coun = static_cast<int>((CurX+hl->glyph.xoffset - tabDist) / wt);
4110
// #6728 : update code according to fillInTabLeaders() and PageItem::layout() - JG
4111
double sPos = 0.0 /* CurX+hl->glyph.xoffset - (CurX+hl->glyph.xoffset - tabDist) + 1 */;
4112
hl2.ch = tTabValues[tabCc].tabFillChar;
4114
hl2.setScaleH(1000);
4115
hl2.setScaleV(1000);
4116
hl2.glyph.yoffset = hl->glyph.yoffset;
4117
for (int cx = 0; cx < coun; ++cx)
4119
hl2.glyph.xoffset = sPos + wt * cx;
4120
if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
4123
static_cast<CharStyle&>(hl3) = static_cast<const CharStyle&>(hl2);
4124
// Hack to workaround #8446, remove when we can subset OpenType fonts in other
4125
// format as Type 3 (and consequently apply stroke correctly)
4126
hl3.setEffects(hl3.effects() & (~ScStyle_Outline));
4128
hl3.glyph.glyph = hl2.glyph.glyph;
4129
hl3.setFillColor(hl2.strokeColor());
4130
hl3.setFillShade(hl2.strokeShade());
4131
hl3.glyph.yoffset = hl2.glyph.yoffset - (chstyle.fontSize() * chstyle.shadowYOffset() / 10000.0);
4132
hl3.glyph.xoffset = hl2.glyph.xoffset + (chstyle.fontSize() * chstyle.shadowXOffset() / 10000.0);
4133
setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, &hl3, pstyle, pag);
4135
setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, &hl2, pstyle, pag);
4144
if (ch == SpecialChars::TAB)
4146
CurX += hl->glyph.wide();
4149
if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
4153
hl2.glyph.glyph = hl->glyph.glyph;
4154
static_cast<CharStyle&>(hl2) = static_cast<const CharStyle&>(*hl);
4155
// Hack to workaround #8446, remove when we can subset OpenType fonts in other
4156
// format as Type 3 (and consequently apply stroke correctly)
4157
hl2.setEffects(hl2.effects() & (~ScStyle_Outline));
4158
hl2.setFillColor(hl->strokeColor());
4159
hl2.setFillShade(hl->strokeShade());
4160
hl2.glyph.yoffset = hl->glyph.yoffset - (chstyle.fontSize() * chstyle.shadowYOffset() / 10000.0);
4161
hl2.glyph.xoffset = hl->glyph.xoffset + (chstyle.fontSize() * chstyle.shadowXOffset() / 10000.0);
4162
hl2.glyph.scaleH = hl->glyph.scaleH;
4163
hl2.glyph.scaleV = hl->glyph.scaleV;
4164
hl2.PtransX = hl->PtransX;
4165
hl2.PtransY = hl->PtransY;
4166
hl2.PRot = hl->PRot;
4168
setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, &hl2, pstyle, pag);
4170
setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, hl, pstyle, pag);
4171
CurX += hl->glyph.wide();
4176
if (ite->itemType() == PageItem::TextFrame)
4181
bool PDFLibCore::setTextCh(PageItem *ite, uint PNr, double x, double y, uint d, QString &tmp, QString &tmp2, const ScText *hl, const ParagraphStyle& pstyle, const Page* pag)
4185
QString FillColor = "";
4186
QString StrokeColor = "";
4187
if (ite->asPathText())
4190
QPointF tangt = QPointF( cos(hl->PRot), sin(hl->PRot) );
4191
QMatrix trafo = QMatrix( 1, 0, 0, -1, -hl->PDx, 0 );
4192
if (ite->textPathFlipped)
4193
trafo *= QMatrix(1, 0, 0, -1, 0, 0);
4194
if (ite->textPathType == 0)
4195
trafo *= QMatrix( tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), hl->PtransX, -hl->PtransY );
4196
else if (ite->textPathType == 1)
4197
trafo *= QMatrix(1, 0, 0, -1, hl->PtransX, -hl->PtransY );
4198
else if (ite->textPathType == 2)
4207
if (fabs(tangt.x()) > 0.1)
4208
trafo *= QMatrix( a, (tangt.y() / tangt.x()) * b, 0, -1, hl->PtransX, -hl->PtransY ); // ID's Skew mode
4210
trafo *= QMatrix( a, 6 * b, 0, -1, hl->PtransX, -hl->PtransY );
4212
tmp += FToStr(trafo.m11())+" "+FToStr(trafo.m12())+" "+FToStr(trafo.m21())+" "+FToStr(trafo.m22())+" "+FToStr(trafo.dx())+" "+FToStr(trafo.dy())+" cm\n";
4213
if (ite->BaseOffs != 0)
4214
tmp += "1 0 0 1 0 "+ FToStr( -ite->BaseOffs)+" cm\n";
4215
if (hl->glyph.xoffset != 0.0 || hl->glyph.yoffset != 0.0)
4216
tmp += "1 0 0 1 " + FToStr( hl->glyph.xoffset)+ " " + FToStr( -hl->glyph.yoffset)+" cm\n";
4217
if (hl->ch != SpecialChars::OBJECT)
4220
double tsz = hl->fontSize();
4221
QChar chstr = hl->ch;
4222
const CharStyle& style(*hl);
4224
/* if (hl->effects() & ScStyle_DropCap)
4226
if (pstyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
4227
tsz = qRound(10 * ((doc.typographicSettings.valueBaseGrid * (pstyle.dropCapLines()-1)+(hl->font().ascent(pstyle.charStyle().fontSize() / 10.0))) / (hl->font().realCharHeight(chstr, 10))));
4230
if (pstyle.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
4231
tsz = qRound(10 * ((pstyle.lineSpacing() * (pstyle.dropCapLines()-1)+(hl->font().ascent(pstyle.charStyle().fontSize() / 10.0))) / (hl->font().realCharHeight(chstr, 10))));
4234
double currasce = hl->font().height(pstyle.charStyle().fontSize());
4235
tsz = qRound(10 * ((currasce * (pstyle.dropCapLines()-1)+(hl->font().ascent(pstyle.charStyle().fontSize() / 10.0))) / hl->font().realCharHeight(chstr, 10)));
4240
InlineFrame& embedded(const_cast<InlineFrame&>(hl->embedded));
4241
if ((hl->ch == SpecialChars::OBJECT) && (embedded.hasItem()))
4243
if (!ite->asPathText())
4248
QList<PageItem*> emG = embedded.getGroupedItems();
4249
QStack<PageItem*> groupStack;
4250
for (int em = 0; em < emG.count(); ++em)
4252
PageItem* embedded = emG.at(em);
4253
if (embedded->isGroupControl)
4256
FPointArray cl = embedded->PoLine.copy();
4257
FPointArray clb = embedded->PoLine.copy();
4259
if (ite->asPathText())
4260
mm.translate(embedded->gXpos * (style.scaleH() / 1000.0), ((embedded->gHeight * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0)) * -1);
4262
mm.translate(x + hl->glyph.xoffset + embedded->gXpos * (style.scaleH() / 1000.0), (y + hl->glyph.yoffset - (embedded->gHeight * (style.scaleV() / 1000.0)) + embedded->gYpos * (style.scaleV() / 1000.0)));
4263
if (style.baselineOffset() != 0)
4264
mm.translate(0, embedded->gHeight * (style.baselineOffset() / 1000.0));
4265
if (style.scaleH() != 1000)
4266
mm.scale(style.scaleH() / 1000.0, 1);
4267
if (style.scaleV() != 1000)
4268
mm.scale(1, style.scaleV() / 1000.0);
4269
mm.rotate(embedded->rotation());
4271
embedded->PoLine = cl;
4272
tmp2 += SetClipPath(embedded);
4274
groupStack.push(embedded->groupsLastItem);
4275
embedded->PoLine = clb.copy();
4279
if (ite->asPathText())
4280
tmp2 += FToStr(style.scaleH() / 1000.0)+" 0 0 "+FToStr(style.scaleV() / 1000.0)+" "+FToStr(embedded->gXpos * (style.scaleH() / 1000.0))+" "+FToStr((embedded->gHeight * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0)+embedded->gHeight * (style.baselineOffset() / 1000.0))+" cm\n";
4282
tmp2 += FToStr(style.scaleH() / 1000.0)+" 0 0 "+FToStr(style.scaleV() / 1000.0)+" "+FToStr(x+hl->glyph.xoffset + embedded->gXpos * (style.scaleH() / 1000.0))+" "+FToStr(-y-hl->glyph.yoffset + (embedded->gHeight * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0)+embedded->gHeight * (style.baselineOffset() / 1000.0))+" cm\n";
4283
if (!PDF_ProcessItem(output, embedded, pag, PNr, true))
4287
if (groupStack.count() != 0)
4289
while (embedded == groupStack.top())
4293
if (groupStack.count() == 0)
4298
for (int em = 0; em < emG.count(); ++em)
4300
PageItem* embedded = emG.at(em);
4301
if (!embedded->isTableItem)
4303
if ((embedded->lineColor() == CommonStrings::None) || (embedded->lineWidth() == 0.0))
4306
if (ite->asPathText())
4307
tmp2 += FToStr(style.scaleH() / 1000.0)+" 0 0 "+FToStr(style.scaleV() / 1000.0)+" "+FToStr(embedded->gXpos * (style.scaleH() / 1000.0))+" "+FToStr((embedded->gHeight * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0)+embedded->gHeight * (style.baselineOffset() / 1000.0))+" cm\n";
4309
tmp2 += FToStr(style.scaleH() / 1000.0)+" 0 0 "+FToStr(style.scaleV() / 1000.0)+" "+FToStr(x+hl->glyph.xoffset + embedded->gXpos * (style.scaleH() / 1000.0))+" "+FToStr(-y-hl->glyph.yoffset + (embedded->gHeight * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0)+embedded->gHeight * (style.baselineOffset() / 1000.0))+" cm\n";
4311
if ((embedded->doOverprint) && (!Options.UseRGB))
4313
QString ShName = ResNam+QString::number(ResCount);
4315
Transpar[ShName] = writeGState("/OP true\n"
4318
tmp2 += "/"+ShName+" gs\n";
4320
if (((embedded->lineTransparency() != 0) || (embedded->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
4321
tmp2 += PDF_TransparenzStroke(embedded);
4322
if (embedded->lineColor() != CommonStrings::None)
4323
tmp2 += putColor(embedded->lineColor(), embedded->lineShade(), false);
4324
tmp2 += FToStr(fabs(embedded->lineWidth()))+" w\n";
4325
if (embedded->DashValues.count() != 0)
4328
QVector<double>::iterator it;
4329
for ( it = embedded->DashValues.begin(); it != embedded->DashValues.end(); ++it )
4331
int da = static_cast<int>(*it);
4332
// #8758: Custom dotted lines don't export properly to pdf
4333
// Null values have to be exported if line end != flat
4334
if ((da != 0) || (embedded->lineEnd() != Qt::FlatCap))
4335
tmp2 += QString::number(da)+" ";
4337
tmp2 += "] "+QString::number(static_cast<int>(embedded->DashOffset))+" d\n";
4340
tmp2 += "["+getDashString(embedded->PLineArt, embedded->lineWidth())+"] 0 d\n";
4342
switch (embedded->PLineJoin)
4357
if ((embedded->TopLine) || (embedded->RightLine) || (embedded->BottomLine) || (embedded->LeftLine))
4359
if (embedded->TopLine)
4362
tmp2 += FToStr(embedded->width())+" 0 l\n";
4364
if (embedded->RightLine)
4366
tmp2 += FToStr(embedded->width())+" 0 m\n";
4367
tmp2 += FToStr(embedded->width())+" "+FToStr(-embedded->height())+" l\n";
4369
if (embedded->BottomLine)
4371
tmp2 += "0 "+FToStr(-embedded->height())+" m\n";
4372
tmp2 += FToStr(embedded->width())+" "+FToStr(-embedded->height())+" l\n";
4374
if (embedded->LeftLine)
4377
tmp2 += "0 "+FToStr(-embedded->height())+" l\n";
4385
if (ite->asPathText())
4392
uint glyph = hl->glyph.glyph;
4394
if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode()) ||
4395
glyph == (ScFace::CONTROL_GLYPHS + 32))
4397
glyph = style.font().char2CMap(QChar(' '));
4400
else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode()))
4402
glyph = style.font().char2CMap(QChar('-'));
4406
if (glyph < ScFace::CONTROL_GLYPHS)
4408
if (style.strokeColor() != CommonStrings::None)
4411
StrokeColor += putColor(style.strokeColor(), style.strokeShade(), false);
4413
if (style.fillColor() != CommonStrings::None)
4416
FillColor += putColor(style.fillColor(), style.fillShade(), true);
4418
if (((style.effects() & ScStyle_Underline) && (chstr != SpecialChars::PARSEP)) || ((style.effects() & ScStyle_UnderlineWords) && (!chstr.isSpace())))
4420
// double Ulen = style.font().charWidth(chstr, style.fontSize()) * (hl->glyph.scaleH);
4421
double Ulen = hl->glyph.xadvance;
4422
double Upos, Uwid, kern;
4423
if (style.effects() & ScStyle_StartOfLine)
4426
kern = style.fontSize() * style.tracking() / 10000.0;
4427
if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
4429
if (style.underlineOffset() != -1)
4430
Upos = (style.underlineOffset() / 1000.0) * (style.font().descent(style.fontSize() / 10.0));
4432
Upos = style.font().underlinePos(style.fontSize() / 10.0);
4433
if (style.underlineWidth() != -1)
4434
Uwid = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
4436
Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
4440
Upos = style.font().underlinePos(style.fontSize() / 10.0);
4441
Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
4443
if (style.baselineOffset() != 0)
4444
Upos += (style.fontSize() / 10.0) * hl->glyph.scaleV * (style.baselineOffset() / 1000.0);
4445
if (style.fillColor() != CommonStrings::None)
4446
tmp2 += putColor(style.fillColor(), style.fillShade(), false);
4447
tmp2 += FToStr(Uwid)+" w\n";
4448
if (ite->itemType() == PageItem::PathText)
4450
if (style.effects() & ScStyle_Subscript)
4452
tmp2 += FToStr(x+hl->glyph.xoffset) +" "+FToStr(-y+Upos)+" m\n";
4453
tmp2 += FToStr(x+hl->glyph.xoffset+Ulen)+" "+FToStr(-y+Upos)+" l\n";
4457
tmp2 += FToStr(x+hl->glyph.xoffset) +" "+FToStr(-y+hl->glyph.yoffset+Upos)+" m\n";
4458
tmp2 += FToStr(x+hl->glyph.xoffset+Ulen)+" "+FToStr(-y+hl->glyph.yoffset+Upos)+" l\n";
4463
if (style.effects() & ScStyle_Subscript)
4465
tmp2 += FToStr(x+hl->glyph.xoffset) + " " + FToStr(-y-hl->glyph.yoffset+Upos)+" m\n";
4466
tmp2 += FToStr(x+hl->glyph.xoffset+Ulen)+ " " + FToStr(-y-hl->glyph.yoffset+Upos)+" l\n";
4470
tmp2 += FToStr(x+hl->glyph.xoffset) +" "+FToStr(-y+Upos)+" m\n";
4471
tmp2 += FToStr(x+hl->glyph.xoffset+Ulen)+" "+FToStr(-y+Upos)+" l\n";
4476
if (!style.font().hasNames())
4478
if (glyph != style.font().char2CMap(QChar(' ')))
4480
if ((style.strokeColor() != CommonStrings::None) && (style.effects() & ScStyle_Outline))
4482
tmp2 += FToStr((tsz * style.outlineWidth() / 1000.0) / tsz)+" w\n[] 0 d\n0 J\n0 j\n";
4483
tmp2 += StrokeColor;
4485
if (style.fillColor() != CommonStrings::None)
4488
// #see 8257 : transform is already computed at beginning of the function
4489
/*if (ite->itemType() == PageItem::PathText)
4491
QPointF tangt = QPointF( cos(hl->PRot), sin(hl->PRot) );
4492
QMatrix trafo = QMatrix( 1, 0, 0, -1, -hl->PDx, 0 );
4493
if (ite->textPathFlipped)
4494
trafo *= QMatrix(1, 0, 0, -1, 0, 0);
4495
if (ite->textPathType == 0)
4496
trafo *= QMatrix(tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), hl->PtransX, -hl->PtransY);
4497
else if (ite->textPathType == 1)
4498
trafo *= QMatrix(1, 0, 0, -1, hl->PtransX, -hl->PtransY );
4499
tmp2 += FToStr(trafo.m11())+" "+FToStr(trafo.m12())+" "+FToStr(trafo.m21())+" "+FToStr(trafo.m22())+" "+FToStr(trafo.dx())+" "+FToStr(trafo.dy())+" cm\n";
4501
if (!ite->asPathText())
4503
if (ite->reversed())
4505
double wid = style.font().charWidth(chstr, style.fontSize()) * (hl->glyph.scaleH);
4506
tmp2 += "1 0 0 1 "+FToStr(x+hl->glyph.xoffset)+" "+FToStr((y+hl->glyph.yoffset - (tsz / 10.0)) * -1 + ((tsz / 10.0) * (style.baselineOffset() / 1000.0)))+" cm\n";
4507
tmp2 += "-1 0 0 1 0 0 cm\n";
4508
tmp2 += "1 0 0 1 "+FToStr(-wid)+" 0 cm\n";
4509
tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" 0 0 cm\n";
4513
tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" "+FToStr(x+hl->glyph.xoffset)+" "+FToStr((y+hl->glyph.yoffset - (tsz / 10.0)) * -1 + ((tsz / 10.0) * (style.baselineOffset() / 1000.0)))+" cm\n";
4518
if (ite->BaseOffs != 0)
4519
tmp2 += "1 0 0 1 0 "+FToStr( -ite->BaseOffs)+" cm\n";
4520
tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" 0 "+FToStr(tsz / 10.0)+" cm\n";
4522
if (hl->glyph.scaleV != 1.0)
4523
tmp2 += "1 0 0 1 0 "+FToStr( (((tsz / 10.0) - (tsz / 10.0) * (hl->glyph.scaleV)) / (tsz / 10.0)) * -1)+" cm\n";
4524
tmp2 += FToStr(qMax(hl->glyph.scaleH, 0.1))+" 0 0 "+FToStr(qMax(hl->glyph.scaleV, 0.1))+" 0 0 cm\n";
4525
if (style.fillColor() != CommonStrings::None)
4526
tmp2 += "/"+style.font().psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+QString::number(glyph)+" Do\n";
4527
if (style.effects() & ScStyle_Outline)
4529
FPointArray gly = style.font().glyphOutline(glyph);
4531
mat.scale(0.1, 0.1);
4537
for (uint poi=0; poi<gly.size()-3; poi += 4)
4539
if (gly.point(poi).x() > 900000)
4547
np = gly.point(poi);
4548
tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
4551
np = gly.point(poi+1);
4552
tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" ";
4553
np = gly.point(poi+3);
4554
tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" ";
4555
np = gly.point(poi+2);
4556
tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" c\n";
4566
if (style.strokeColor() != CommonStrings::None)
4568
if ((style.effects() & ScStyle_Underline) || (style.effects() & ScStyle_Strikethrough) || (style.effects() & ScStyle_Outline))
4569
tmp2 += StrokeColor;
4571
if (style.fillColor() != CommonStrings::None)
4573
if ((style.effects() & ScStyle_Underline) || (style.effects() & ScStyle_Strikethrough))
4576
if (glyph != style.font().char2CMap(QChar(' ')))
4578
uint idx = hl->glyph.glyph;
4580
if (Options.SubsetList.contains(style.font().replacementName()))
4581
idx1 = Type3Fonts[UsedFontsP[style.font().replacementName()]][idx] / 256;
4584
tmp += UsedFontsP[style.font().replacementName()]+"S"+QString::number(idx1)+" "+FToStr(tsz / 10.0)+" Tf\n";
4585
if (style.strokeColor() != CommonStrings::None)
4587
if (style.fillColor() != CommonStrings::None)
4589
if ((Options.SubsetList.contains(style.font().replacementName())) && (style.effects() & ScStyle_Outline) && (style.strokeColor() != CommonStrings::None))
4592
tmp2 += FToStr((tsz * style.outlineWidth() / 1000.0) / tsz)+" w\n[] 0 d\n0 J\n0 j\n";
4593
// #see 8257 : transform is already computed at beginning of the function
4594
/*if (ite->itemType() == PageItem::PathText)
4596
QPointF tangt = QPointF( cos(hl->PRot), sin(hl->PRot) );
4597
QMatrix trafo = QMatrix( 1, 0, 0, -1, -hl->PDx, 0 );
4598
if (ite->textPathFlipped)
4599
trafo *= QMatrix(1, 0, 0, -1, 0, 0);
4600
if (ite->textPathType == 0)
4601
trafo *= QMatrix(tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), hl->PtransX, -hl->PtransY);
4602
else if (ite->textPathType == 1)
4603
trafo *= QMatrix(1, 0, 0, -1, hl->PtransX, -hl->PtransY );
4604
tmp2 += FToStr(trafo.m11())+" "+FToStr(trafo.m12())+" "+FToStr(trafo.m21())+" "+FToStr(trafo.m22())+" "+FToStr(trafo.dx())+" "+FToStr(trafo.dy())+" cm\n";
4606
if (!ite->asPathText())
4608
if (ite->reversed())
4610
double wid = style.font().charWidth(chstr, style.fontSize()) * (hl->glyph.scaleH);
4611
tmp2 += "1 0 0 1 "+FToStr(x+hl->glyph.xoffset)+" "+FToStr((y+hl->glyph.yoffset - (tsz / 10.0)) * -1 + ((tsz / 10.0) * (style.baselineOffset() / 1000.0)))+" cm\n";
4612
tmp2 += "-1 0 0 1 0 0 cm\n";
4613
tmp2 += "1 0 0 1 "+FToStr(-wid)+" 0 cm\n";
4614
tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" 0 0 cm\n";
4618
tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" "+FToStr(x+hl->glyph.xoffset)+" "+FToStr((y+hl->glyph.yoffset - (tsz / 10.0)) * -1 + ((tsz / 10.0) * (style.baselineOffset() / 1000.0)))+" cm\n";
4623
if (ite->BaseOffs != 0)
4624
tmp2 += "1 0 0 1 0 "+FToStr( -ite->BaseOffs)+" cm\n";
4625
tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" 0 "+FToStr(tsz / 10.0)+" cm\n";
4627
if (hl->glyph.scaleV != 1.0)
4628
tmp2 += "1 0 0 1 0 "+FToStr( (((tsz / 10.0) - (tsz / 10.0) * (hl->glyph.scaleV)) / (tsz / 10.0)) * -1)+" cm\n";
4629
tmp2 += FToStr(qMax(hl->glyph.scaleH, 0.1))+" 0 0 "+FToStr(qMax(hl->glyph.scaleV, 0.1))+" 0 0 cm\n";
4630
FPointArray gly = style.font().glyphOutline(glyph);
4632
mat.scale(0.1, 0.1);
4638
for (uint poi=0; poi<gly.size()-3; poi += 4)
4640
if (gly.point(poi).x() > 900000)
4648
np = gly.point(poi);
4649
tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
4652
np = gly.point(poi+1);
4653
tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" ";
4654
np = gly.point(poi+3);
4655
tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" ";
4656
np = gly.point(poi+2);
4657
tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" c\n";
4665
if (style.effects() & ScStyle_Outline)
4666
tmp += FToStr(tsz * style.outlineWidth() / 10000.0) + (style.fillColor() != CommonStrings::None ? " w 2 Tr\n" : " w 1 Tr\n");
4670
if (!ite->asPathText())
4672
if (ite->reversed())
4674
double wtr = hl->glyph.xadvance;
4675
tmp += FToStr(-qMax(hl->glyph.scaleH, 0.1))+" 0 0 "+FToStr(qMax(hl->glyph.scaleV, 0.1)) +" "+FToStr(x+hl->glyph.xoffset+wtr)+" "+FToStr(-y-hl->glyph.yoffset+(style.fontSize() / 10.0) * (style.baselineOffset() / 1000.0))+" Tm\n";
4678
tmp += FToStr(qMax(hl->glyph.scaleH, 0.1))+" 0 0 "+FToStr(qMax(hl->glyph.scaleV, 0.1))+" "+FToStr(x+hl->glyph.xoffset)+" "+FToStr(-y-hl->glyph.yoffset+(style.fontSize() / 10.0) * (style.baselineOffset() / 1000.0))+" Tm\n";
4681
tmp += FToStr(qMax(hl->glyph.scaleH, 0.1))+" 0 0 "+FToStr(qMax(hl->glyph.scaleV, 0.1))+" 0 0 Tm\n";
4683
if (Options.SubsetList.contains(style.font().replacementName()))
4685
if (style.fillColor() != CommonStrings::None)
4687
idx2 = Type3Fonts[UsedFontsP[style.font().replacementName()]][idx] % 256;
4688
tmp += "<"+QString(toHex(idx2))+"> Tj\n";
4693
idx2 = idx % 224 + 32;
4694
tmp += "<"+QString(toHex(idx2))+"> Tj\n";
4698
if ((style.effects() & ScStyle_Strikethrough) && (chstr != SpecialChars::PARSEP))
4700
// double Ulen = style.font().charWidth(chstr, style.fontSize()) * (hl->glyph.scaleH);
4701
double Ulen = hl->glyph.xadvance;
4702
double Upos, Uwid, kern;
4703
if (hl->effects() & ScStyle_StartOfLine)
4706
kern = style.fontSize() * style.tracking() / 10000.0;
4707
if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
4709
if (style.strikethruOffset() != -1)
4710
Upos = (style.strikethruOffset() / 1000.0) * (style.font().ascent(style.fontSize() / 10.0));
4712
Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
4713
if (style.strikethruWidth() != -1)
4714
Uwid = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
4716
Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
4720
Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
4721
Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
4723
if (style.baselineOffset() != 0)
4724
Upos += (style.fontSize() / 10.0) * hl->glyph.scaleV * (style.baselineOffset() / 1000.0);
4725
if (style.fillColor() != CommonStrings::None)
4726
tmp2 += putColor(style.fillColor(), style.fillShade(), false);
4727
tmp2 += FToStr(Uwid)+" w\n";
4728
if (ite->itemType() == PageItem::PathText)
4730
tmp2 += FToStr(x+hl->glyph.xoffset) +" "+FToStr(-y+Upos)+" m\n";
4731
tmp2 += FToStr(x+hl->glyph.xoffset+Ulen)+" "+FToStr(-y+Upos)+" l\n";
4735
tmp2 += FToStr(x+hl->glyph.xoffset) +" "+FToStr(-y-hl->glyph.yoffset+Upos)+" m\n";
4736
tmp2 += FToStr(x+hl->glyph.xoffset+Ulen)+" "+FToStr(-y-hl->glyph.yoffset+Upos)+" l\n";
4740
if (ite->asPathText())
4742
tmp += "ET\n"+tmp2+"Q\n";
4746
if (hl->glyph.more) {
4747
// ugly hack until setTextCh interface is changed
4749
hl2.glyph = *(hl->glyph.more);
4750
if (!setTextCh(ite, PNr, x + hl->glyph.xadvance, y, d, tmp, tmp2, &hl2, pstyle, pag))
4752
// don't let hl2's destructor delete these!
4759
QString PDFLibCore::SetColor(const QString& farbe, double Shade)
4761
const ScColor& col = doc.PageColors[farbe];
4762
return SetColor(col, Shade);
4765
QString PDFLibCore::SetColor(const ScColor& farbe, double Shade)
4771
ScColor tmpC(farbe);
4773
if (Options.isGrayscale)
4775
bool kToGray = false;
4776
if (tmpC.getColorModel() == colorModelCMYK)
4778
ScColorEngine::getShadeColorCMYK(tmpC, &doc, cmyk, Shade);
4779
cmyk.getValues(h, s, v, k);
4780
kToGray = (h == 0 && s == 0 && v == 0);
4783
tmp = FToStr(1.0 - k / 255.0);
4786
tmpR = ScColorEngine::getShadeColor(tmpC, &doc, Shade);
4787
tmpR.getRgb(&h, &s, &v);
4788
tmp = FToStr((0.3 * h + 0.59 * s + 0.11 * v) / 255.0);
4794
tmpR = ScColorEngine::getShadeColor(tmpC, &doc, Shade);
4795
tmpR.getRgb(&h, &s, &v);
4796
tmp = FToStr(h / 255.0)+" "+FToStr(s / 255.0)+" "+FToStr(v / 255.0);
4800
if ((doc.HasCMS) && (Options.UseProfiles))
4802
if (tmpC.getColorModel() == colorModelCMYK)
4804
ScColorEngine::getShadeColorCMYK(tmpC, &doc, cmyk, Shade);
4805
cmyk.getValues(h, s, v, k);
4806
tmp = FToStr(h / 255.0)+" "+FToStr(s / 255.0)+" "+FToStr(v / 255.0)+" "+FToStr(k / 255.0);
4810
if (Options.SComp == 3)
4812
ScColorEngine::getShadeColorRGB(tmpC, &doc, rgb, Shade);
4813
rgb.getValues(h, s, v);
4814
tmp = FToStr(h / 255.0)+" "+FToStr(s / 255.0)+" "+FToStr(v / 255.0);
4818
ScColorEngine::getShadeColorCMYK(tmpC, &doc, cmyk, Shade);
4819
cmyk.getValues(h, s, v, k);
4820
tmp = FToStr(h / 255.0)+" "+FToStr(s / 255.0)+" "+FToStr(v / 255.0)+" "+FToStr(k / 255.0);
4826
ScColorEngine::getShadeColorCMYK(tmpC, &doc, cmyk, Shade);
4827
cmyk.getValues(h, s, v, k);
4828
tmp = FToStr(h / 255.0)+" "+FToStr(s / 255.0)+" "+FToStr(v / 255.0)+" "+FToStr(k / 255.0);
4834
QString PDFLibCore::SetGradientColor(const QString& farbe, double Shade)
4840
ScColor tmpC(doc.PageColors[farbe]);
4842
if (Options.isGrayscale)
4844
bool kToGray = false;
4845
if (tmpC.getColorModel() == colorModelCMYK)
4847
ScColorEngine::getShadeColorCMYK(tmpC, &doc, cmyk, Shade);
4848
cmyk.getValues(h, s, v, k);
4849
kToGray = (h == 0 && s == 0 && v == 0);
4852
tmp = FToStr(1.0 - k / 255.0);
4855
tmpR = ScColorEngine::getShadeColor(tmpC, &doc, Shade);
4856
tmpR.getRgb(&h, &s, &v);
4857
tmp = FToStr((0.3 * h + 0.59 * s + 0.11 * v) / 255.0);
4863
tmpR = ScColorEngine::getShadeColor(tmpC, &doc, Shade);
4864
tmpR.getRgb(&h, &s, &v);
4865
tmp = FToStr(h / 255.0)+" "+FToStr(s / 255.0)+" "+FToStr(v / 255.0);
4869
if ((doc.HasCMS) && (Options.UseProfiles))
4871
if (Options.SComp == 3)
4873
ScColorEngine::getShadeColorRGB(tmpC, &doc, rgb, Shade);
4874
rgb.getValues(h, s, v);
4875
tmp = FToStr(h / 255.0)+" "+FToStr(s / 255.0)+" "+FToStr(v / 255.0);
4879
ScColorEngine::getShadeColorCMYK(tmpC, &doc, cmyk, Shade);
4880
cmyk.getValues(h, s, v, k);
4881
tmp = FToStr(h / 255.0)+" "+FToStr(s / 255.0)+" "+FToStr(v / 255.0)+" "+FToStr(k / 255.0);
4886
ScColorEngine::getShadeColorCMYK(tmpC, &doc, cmyk, Shade);
4887
cmyk.getValues(h, s, v, k);
4888
tmp = FToStr(h / 255.0)+" "+FToStr(s / 255.0)+" "+FToStr(v / 255.0)+" "+FToStr(k / 255.0);
4894
QString PDFLibCore::SetClipPathImage(PageItem *ite)
4897
if (ite->imageClip.size() > 3)
4900
for (uint poi=0; poi<ite->imageClip.size()-3; poi += 4)
4902
if (ite->imageClip.point(poi).x() > 900000)
4908
FPoint np, np1, np2, np3;
4911
np = ite->imageClip.point(poi);
4912
tmp += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
4915
np = ite->imageClip.point(poi);
4916
np1 = ite->imageClip.point(poi+1);
4917
np2 = ite->imageClip.point(poi+3);
4918
np3 = ite->imageClip.point(poi+2);
4919
if ((np == np1) && (np2 == np3))
4920
tmp += FToStr(np3.x())+" "+FToStr(-np3.y())+" l\n";
4923
tmp += FToStr(np1.x())+" "+FToStr(-np1.y())+" ";
4924
tmp += FToStr(np2.x())+" "+FToStr(-np2.y())+" ";
4925
tmp += FToStr(np3.x())+" "+FToStr(-np3.y())+" c\n";
4932
QString PDFLibCore::SetClipPath(PageItem *ite, bool poly)
4935
if (ite->PoLine.size() > 3)
4938
for (uint poi=0; poi<ite->PoLine.size()-3; poi += 4)
4940
if (ite->PoLine.point(poi).x() > 900000)
4947
FPoint np, np1, np2, np3;
4950
np = ite->PoLine.point(poi);
4951
tmp += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
4954
np = ite->PoLine.point(poi);
4955
np1 = ite->PoLine.point(poi+1);
4956
np2 = ite->PoLine.point(poi+3);
4957
np3 = ite->PoLine.point(poi+2);
4958
if ((np == np1) && (np2 == np3))
4959
tmp += FToStr(np3.x())+" "+FToStr(-np3.y())+" l\n";
4962
tmp += FToStr(np1.x())+" "+FToStr(-np1.y())+" ";
4963
tmp += FToStr(np2.x())+" "+FToStr(-np2.y())+" ";
4964
tmp += FToStr(np3.x())+" "+FToStr(-np3.y())+" c\n";
4971
QString PDFLibCore::SetClipPathArray(FPointArray *ite, bool poly)
4974
if (ite->size() > 3)
4977
for (uint poi=0; poi<ite->size()-3; poi += 4)
4979
if (ite->point(poi).x() > 900000)
4986
FPoint np, np1, np2, np3;
4989
np = ite->point(poi);
4990
tmp += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
4993
np = ite->point(poi);
4994
np1 = ite->point(poi+1);
4995
np2 = ite->point(poi+3);
4996
np3 = ite->point(poi+2);
4997
if ((np == np1) && (np2 == np3))
4998
tmp += FToStr(np3.x())+" "+FToStr(-np3.y())+" l\n";
5001
tmp += FToStr(np1.x())+" "+FToStr(-np1.y())+" ";
5002
tmp += FToStr(np2.x())+" "+FToStr(-np2.y())+" ";
5003
tmp += FToStr(np3.x())+" "+FToStr(-np3.y())+" c\n";
5010
void PDFLibCore::getBleeds(const Page* page, double &left, double &right)
5012
MarginStruct values;
5013
doc.getBleeds(page, Options.bleeds, values);
5015
right = values.Right;
5018
void PDFLibCore::getBleeds(const Page* page, double &left, double &right, double &bottom, double& top)
5020
MarginStruct values;
5021
doc.getBleeds(page, Options.bleeds, values);
5023
right = values.Right;
5024
bottom = values.Bottom;
5028
QString PDFLibCore::PDF_TransparenzFill(PageItem *currItem)
5030
QString ShName = ResNam+QString::number(ResCount);
5032
Transpar[ShName] = writeGState("/ca "+FToStr(1.0 - currItem->fillTransparency())+"\n"
5033
+ "/SMask /None\n/AIS false\n/OPM 1\n"
5034
+ "/BM /" + blendMode(currItem->fillBlendmode()) + "\n");
5035
QString tmp("/"+ShName+" gs\n");
5039
QString PDFLibCore::PDF_TransparenzStroke(PageItem *currItem)
5041
QString ShName = ResNam+QString::number(ResCount);
5043
Transpar[ShName] = writeGState("/CA "+FToStr(1.0 - currItem->lineTransparency())+"\n"
5044
+ "/SMask /None\n/AIS false\n/OPM 1\n"
5045
+ "/BM /" + blendMode(currItem->lineBlendmode()) + "\n");
5046
QString tmp("/"+ShName+" gs\n");
5050
bool PDFLibCore::PDF_Gradient(QString& output, PageItem *currItem)
5052
if (currItem->GrType == 8)
5054
QStack<PageItem*> groupStack;
5055
QString tmp2 = "", tmpOut;
5056
ScPattern *pat = &doc.docPatterns[currItem->pattern()];
5057
for (int em = 0; em < pat->items.count(); ++em)
5059
PageItem* item = pat->items.at(em);
5060
if (item->isGroupControl)
5063
FPointArray cl = item->PoLine.copy();
5064
FPointArray clb = item->PoLine.copy();
5066
mm.translate(item->gXpos, item->gYpos - pat->height);
5067
mm.rotate(item->rotation());
5070
tmp2 += SetClipPath(item);
5072
groupStack.push(item->groupsLastItem);
5073
item->PoLine = clb.copy();
5077
tmp2 += "1 0 0 1 "+FToStr(item->gXpos)+" "+FToStr(-(item->gYpos - pat->height))+" cm\n";
5078
item->setXYPos(item->xPos() + ActPageP->xOffset(), item->yPos() + ActPageP->yOffset(), true);
5080
if (!PDF_ProcessItem(tmpOut, item, doc.DocPages.at(0), 0, true, true))
5083
item->setXYPos(item->xPos() - ActPageP->xOffset(), item->yPos() - ActPageP->yOffset(), true);
5086
if (groupStack.count() != 0)
5088
while (item == groupStack.top())
5092
if (groupStack.count() == 0)
5097
for (int em = 0; em < pat->items.count(); ++em)
5099
PageItem* item = pat->items.at(em);
5100
if (!item->isTableItem)
5102
if ((item->lineColor() == CommonStrings::None) || (item->lineWidth() == 0.0))
5105
if ((item->doOverprint) && (!Options.UseRGB))
5107
QString ShName = ResNam+QString::number(ResCount);
5109
Transpar[ShName] = writeGState("/OP true\n"
5112
tmp2 += "/"+ShName+" gs\n";
5114
if (((item->lineTransparency() != 0) || (item->lineBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
5115
tmp2 += PDF_TransparenzStroke(item);
5116
if (item->lineColor() != CommonStrings::None)
5117
tmp2 += putColor(item->lineColor(), item->lineShade(), false);
5118
tmp2 += FToStr(fabs(item->lineWidth()))+" w\n";
5119
if (item->DashValues.count() != 0)
5122
QVector<double>::iterator it;
5123
for ( it = item->DashValues.begin(); it != item->DashValues.end(); ++it )
5125
int da = static_cast<int>(*it);
5126
// #8758: Custom dotted lines don't export properly to pdf
5127
// Null values have to be exported if line end != flat
5128
if ((da != 0) || (item->lineEnd() != Qt::FlatCap))
5129
tmp2 += QString::number(da)+" ";
5131
tmp2 += "] "+QString::number(static_cast<int>(item->DashOffset))+" d\n";
5134
tmp2 += "["+getDashString(item->PLineArt, item->lineWidth())+"] 0 d\n";
5136
switch (item->PLineJoin)
5151
tmp2 += "1 0 0 1 "+FToStr(item->gXpos)+" "+FToStr(-(item->gYpos - pat->height))+" cm\n";
5152
if (item->rotation() != 0)
5154
double sr = sin(-item->rotation()* M_PI / 180.0);
5155
double cr = cos(-item->rotation()* M_PI / 180.0);
5156
if ((cr * cr) < 0.000001)
5158
if ((sr * sr) < 0.000001)
5160
tmp2 += FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+ " 0 0 cm\n";
5162
if ((item->TopLine) || (item->RightLine) || (item->BottomLine) || (item->LeftLine))
5167
tmp2 += FToStr(item->width())+" 0 l\n";
5169
if (item->RightLine)
5171
tmp2 += FToStr(item->width())+" 0 m\n";
5172
tmp2 += FToStr(item->width())+" "+FToStr(-item->height())+" l\n";
5174
if (item->BottomLine)
5176
tmp2 += "0 "+FToStr(-item->height())+" m\n";
5177
tmp2 += FToStr(item->width())+" "+FToStr(-item->height())+" l\n";
5182
tmp2 += "0 "+FToStr(-item->height())+" l\n";
5188
if (Options.Compress)
5189
tmp2 = CompressStr(&tmp2);
5190
uint patObject = newObject();
5191
StartObj(patObject);
5192
PutDoc("<< /Type /Pattern\n");
5193
PutDoc("/PatternType 1\n");
5194
PutDoc("/PaintType 1\n");
5195
PutDoc("/TilingType 1\n");
5196
PutDoc("/BBox [ 0 0 "+FToStr(pat->width)+" "+FToStr(pat->height)+" ]\n");
5200
mpa.translate(currItem->xPos() - ActPageP->xOffset(), ActPageP->height() - (currItem->yPos() - ActPageP->yOffset()));
5201
mpa.rotate(-currItem->rotation());
5203
double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation;
5204
currItem->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation);
5205
mpa.translate(patternOffsetX, -patternOffsetY);
5206
mpa.rotate(-patternRotation);
5207
mpa.scale(pat->scaleX, pat->scaleY);
5208
mpa.scale(patternScaleX / 100.0 , patternScaleY / 100.0);
5209
PutDoc("/Matrix ["+FToStr(mpa.m11())+" "+FToStr(mpa.m12())+" "+FToStr(mpa.m21())+" "+FToStr(mpa.m22())+" "+FToStr(mpa.dx())+" "+FToStr(mpa.dy())+"]\n");
5210
PutDoc("/XStep "+FToStr(pat->width)+"\n");
5211
PutDoc("/YStep "+FToStr(pat->height)+"\n");
5212
PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
5213
if (Seite.ImgObjects.count() != 0)
5215
PutDoc("/XObject <<\n");
5216
QMap<QString,int>::Iterator it;
5217
for (it = Seite.ImgObjects.begin(); it != Seite.ImgObjects.end(); ++it)
5218
PutDoc("/"+it.key()+" "+QString::number(it.value())+" 0 R\n");
5221
if (Seite.FObjects.count() != 0)
5223
PutDoc("/Font << \n");
5224
QMap<QString,int>::Iterator it2;
5225
for (it2 = Seite.FObjects.begin(); it2 != Seite.FObjects.end(); ++it2)
5226
PutDoc("/"+it2.key()+" "+QString::number(it2.value())+" 0 R\n");
5229
if (Shadings.count() != 0)
5231
PutDoc("/Shading << \n");
5232
QMap<QString,int>::Iterator it3;
5233
for (it3 = Shadings.begin(); it3 != Shadings.end(); ++it3)
5234
PutDoc("/"+it3.key()+" "+QString::number(it3.value())+" 0 R\n");
5237
if (Patterns.count() != 0)
5239
PutDoc("/Pattern << \n");
5240
QMap<QString,int>::Iterator it3p;
5241
for (it3p = Patterns.begin(); it3p != Patterns.end(); ++it3p)
5242
PutDoc("/"+it3p.key()+" "+QString::number(it3p.value())+" 0 R\n");
5245
if (Transpar.count() != 0)
5247
PutDoc("/ExtGState << \n");
5248
QMap<QString,int>::Iterator it3t;
5249
for (it3t = Transpar.begin(); it3t != Transpar.end(); ++it3t)
5250
PutDoc("/"+it3t.key()+" "+QString::number(it3t.value())+" 0 R\n");
5253
if ((ICCProfiles.count() != 0) || (spotMap.count() != 0))
5255
PutDoc("/ColorSpace << \n");
5256
QMap<QString,ICCD>::Iterator it3c;
5257
if (ICCProfiles.count() != 0)
5259
for (it3c = ICCProfiles.begin(); it3c != ICCProfiles.end(); ++it3c)
5260
PutDoc("/"+it3c.value().ResName+" "+QString::number(it3c.value().ResNum)+" 0 R\n");
5262
QMap<QString,SpotC>::Iterator it3sc;
5263
if (spotMap.count() != 0)
5265
for (it3sc = spotMap.begin(); it3sc != spotMap.end(); ++it3sc)
5266
PutDoc("/"+it3sc.value().ResName+" "+QString::number(it3sc.value().ResNum)+" 0 R\n");
5271
PutDoc("/Length "+QString::number(tmp2.length()));
5272
if (Options.Compress)
5273
PutDoc("\n/Filter /FlateDecode");
5274
PutDoc(" >>\nstream\n"+EncStream(tmp2, patObject)+"\nendstream\nendobj\n");
5275
Patterns.insert("Pattern"+QString::number(patObject), patObject);
5276
QString tmp = "/Pattern cs\n";
5277
tmp += "/Pattern"+QString::number(patObject)+" scn\n";
5278
tmp += SetClipPath(currItem);
5279
if (currItem->fillRule)
5287
double StartX = currItem->GrStartX;
5288
double StartY = -currItem->GrStartY;
5289
double EndX = currItem->GrEndX;
5290
double EndY =- currItem->GrEndY;
5291
QList<double> StopVec;
5292
QList<double> TransVec;
5293
QStringList Gcolors;
5294
QStringList colorNames;
5295
QList<int> colorShades;
5296
QList<VColorStop*> cstops = currItem->fill_gradient.colorStops();
5301
colorShades.clear();
5302
double lastStop = -1.0;
5303
double actualStop = 0.0;
5304
bool isFirst = true;
5305
if ((currItem->GrType == 5) || (currItem->GrType == 7))
5307
for (uint cst = 0; cst < currItem->fill_gradient.Stops(); ++cst)
5309
actualStop = cstops.at(cst)->rampPoint;
5310
if ((actualStop != lastStop) || (isFirst))
5313
lastStop = actualStop;
5314
TransVec.prepend(cstops.at(cst)->opacity);
5315
StopVec.prepend(sqrt(pow(EndX - StartX, 2) + pow(EndY - StartY,2))*cstops.at(cst)->rampPoint);
5316
Gcolors.prepend(SetGradientColor(cstops.at(cst)->name, cstops.at(cst)->shade));
5317
colorNames.prepend(cstops.at(cst)->name);
5318
colorShades.prepend(cstops.at(cst)->shade);
5324
for (uint cst = 0; cst < currItem->fill_gradient.Stops(); ++cst)
5326
actualStop = cstops.at(cst)->rampPoint;
5327
if ((actualStop != lastStop) || (isFirst))
5330
lastStop = actualStop;
5331
double x = (1 - cstops.at(cst)->rampPoint) * StartX + cstops.at(cst)->rampPoint * EndX;
5332
double y = (1 - cstops.at(cst)->rampPoint) * StartY + cstops.at(cst)->rampPoint * EndY;
5333
TransVec.append(cstops.at(cst)->opacity);
5336
Gcolors.append(SetGradientColor(cstops.at(cst)->name, cstops.at(cst)->shade));
5337
colorNames.append(cstops.at(cst)->name);
5338
colorShades.append(cstops.at(cst)->shade);
5342
output = PDF_DoLinGradient(currItem, StopVec, TransVec, Gcolors, colorNames, colorShades);
5346
QString PDFLibCore::PDF_DoLinGradient(PageItem *currItem, QList<double> Stops, QList<double> Trans, const QStringList& Colors, QStringList colorNames, QList<int> colorShades)
5350
bool oneSameSpot = false;
5351
bool oneSpot1 = false;
5352
bool oneSpot2 = false;
5353
bool twoSpot = false;
5354
bool spotMode = false;
5355
uint spotObject = 0;
5357
CMYKColor cmykValues;
5358
double w = currItem->width();
5359
double h = -currItem->height();
5360
double w2 = currItem->GrStartX;
5361
double h2 = -currItem->GrStartY;
5362
int colorsCountm1=Colors.count()-1;
5363
for (int c = 0; c < colorsCountm1; ++c)
5365
oneSameSpot = false;
5370
QString spot1 = colorNames[c].simplified().replace("#", "#23").replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "#20" );
5371
QString spot2 = colorNames[c+1].simplified().replace("#", "#23").replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "#20" );
5373
if ((Options.Version >= PDFOptions::PDFVersion_14) && ((Trans.at(c+1) != 1) || (Trans.at(c) != 1)))
5375
uint shadingObject = newObject();
5376
StartObj(shadingObject);
5377
QString ShName = ResNam+QString::number(ResCount);
5378
Shadings[ShName] = shadingObject;
5381
if ((currItem->GrType == 5) || (currItem->GrType == 7))
5382
PutDoc("/ShadingType 3\n");
5384
PutDoc("/ShadingType 2\n");
5385
PutDoc("/ColorSpace /DeviceGray\n");
5386
PutDoc("/BBox [0 "+FToStr(h)+" "+FToStr(w)+" 0]\n");
5387
if ((currItem->GrType == 5) || (currItem->GrType == 7))
5389
PutDoc("/Coords ["+FToStr(w2)+" "+FToStr(h2)+" "+FToStr(Stops.at(c+1))+" "+FToStr(w2)+" "+FToStr(h2)+" "+FToStr(Stops.at(c))+"]\n");
5390
PutDoc("/Extend [true true]\n");
5391
PutDoc("/Function\n<<\n/FunctionType 2\n/Domain [0 1]\n");
5392
PutDoc("/C0 ["+FToStr(Trans.at(c+1))+"]\n");
5393
PutDoc("/C1 ["+FToStr(Trans.at(c))+"]\n");
5397
PutDoc("/Coords ["+FToStr(Stops.at(c*2))+" "+FToStr(Stops.at(c*2+1))+" "+FToStr(Stops.at(c*2+2))+" "+FToStr(Stops.at(c*2+3))+"]\n");
5398
PutDoc("/Extend [true true]\n");
5399
PutDoc("/Function\n<<\n/FunctionType 2\n/Domain [0 1]\n");
5400
PutDoc("/C0 ["+FToStr(Trans.at(c))+"]\n");
5401
PutDoc("/C1 ["+FToStr(Trans.at(c+1))+"]\n");
5403
PutDoc("/N 1\n>>\n>>\nendobj\n");
5404
uint formObject = newObject();
5405
StartObj(formObject);
5406
PutDoc("<<\n/Type /XObject\n/Subtype /Form\n");
5407
PutDoc("/FormType 1\n");
5408
PutDoc("/Group << /S /Transparency /CS /DeviceGray >>\n");
5409
PutDoc("/BBox [ 0 0 "+FToStr(currItem->width())+" "+FToStr(-currItem->height())+" ]\n");
5410
PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
5411
if (Shadings.count() != 0)
5413
PutDoc("/Shading << \n");
5414
QMap<QString,int>::Iterator it3;
5415
for (it3 = Shadings.begin(); it3 != Shadings.end(); ++it3)
5416
PutDoc("/"+it3.key()+" "+QString::number(it3.value())+" 0 R\n");
5421
stre += "q\n"+SetClipPath(currItem)+"h\nW* n\n"+"/"+ShName+" sh\nQ\n";
5422
if (Options.Compress)
5423
stre = CompressStr(&stre);
5424
PutDoc("/Length "+QString::number(stre.length())+"\n");
5425
if (Options.Compress)
5426
PutDoc("/Filter /FlateDecode\n");
5427
PutDoc(">>\nstream\n"+EncStream(stre, formObject)+"\nendstream\nendobj\n");
5428
Seite.XObjects[ResNam+QString::number(ResCount)] = formObject;
5430
QString GXName = ResNam+QString::number(ResCount);
5432
Transpar[GXName] = writeGState("/SMask << /S /Luminosity /G "+QString::number(formObject)+" 0 R >>\n"
5436
uint shadingObject2 = newObject();
5437
StartObj(shadingObject2);
5438
QString ShName = ResNam+QString::number(ResCount);
5439
Shadings[ShName] = shadingObject2;
5442
if ((currItem->GrType == 5) || (currItem->GrType == 7))
5443
PutDoc("/ShadingType 3\n");
5445
PutDoc("/ShadingType 2\n");
5447
PutDoc("/ColorSpace /DeviceRGB\n");
5450
if (Options.isGrayscale)
5451
PutDoc("/ColorSpace /DeviceGray\n");
5454
if ((doc.HasCMS) && (Options.UseProfiles))
5455
PutDoc("/ColorSpace "+ICCProfiles[Options.SolidProf].ICCArray+"\n");
5458
if (spotMap.contains(colorNames[c]))
5460
if (spotMap.contains(colorNames[c+1]))
5462
if (oneSpot1 && oneSpot2)
5464
oneSpot1 = oneSpot2 = false;
5465
oneSameSpot = (colorNames[c] == colorNames[c+1]);
5468
if (((!oneSpot1) && (!oneSpot2) && (!twoSpot)) || (!Options.UseSpotColors))
5469
PutDoc("/ColorSpace /DeviceCMYK\n");
5473
spotObject = newObject();
5474
PutDoc("/ColorSpace [ /DeviceN [");
5476
PutDoc(" /"+spot1+" ]\n");
5478
PutDoc(" /Cyan /Magenta /Yellow /Black /"+spot1+" ]\n");
5480
PutDoc(" /Cyan /Magenta /Yellow /Black /"+spot2+" ]\n");
5482
PutDoc(" /"+spot1+" /"+spot2+" ]\n");
5483
PutDoc("/DeviceCMYK\n");
5484
PutDoc(QString::number(spotObject)+" 0 R\n");
5490
PutDoc("/BBox [0 "+FToStr(h)+" "+FToStr(w)+" 0]\n");
5491
if ((currItem->GrType == 5) || (currItem->GrType == 7))
5493
PutDoc("/Coords ["+FToStr(w2)+" "+FToStr(h2)+" "+FToStr(Stops.at(c+1))+" "+FToStr(w2)+" "+FToStr(h2)+" "+FToStr(Stops.at(c))+"]\n");
5494
if (Colors.count() == 2)
5495
PutDoc("/Extend [true true]\n");
5499
PutDoc("/Extend [false true]\n");
5502
if (c == Colors.count()-2)
5503
PutDoc("/Extend [true false]\n");
5505
PutDoc("/Extend [false false]\n");
5509
PutDoc("/Function\n<<\n/FunctionType 2\n/Domain [0 1]\n");
5510
if (Options.UseSpotColors)
5514
PutDoc("/C0 ["+FToStr(colorShades[c] / 100.0)+"]\n");
5515
PutDoc("/C1 ["+FToStr(colorShades[c+1] / 100.0)+"]\n");
5519
PutDoc("/C1 [0 0 0 0 "+FToStr(colorShades[c] / 100.0)+"]\n");
5520
PutDoc("/C0 ["+Colors[c+1]+" 0 ]\n");
5524
PutDoc("/C1 ["+Colors[c]+" 0 ]\n");
5525
PutDoc("/C0 [0 0 0 0 "+FToStr(colorShades[c+1] / 100.0)+"]\n");
5529
PutDoc("/C1 ["+FToStr(colorShades[c] / 100.0)+" 0]\n");
5530
PutDoc("/C0 [0 "+FToStr(colorShades[c+1] / 100.0)+"]\n");
5534
PutDoc("/C1 ["+Colors[c]+"]\n");
5535
PutDoc("/C0 ["+Colors[c+1]+"]\n");
5540
PutDoc("/C0 ["+Colors[c+1]+"]\n");
5541
PutDoc("/C1 ["+Colors[c]+"]\n");
5546
PutDoc("/Coords ["+FToStr(Stops.at(c*2))+" "+FToStr(Stops.at(c*2+1))+" "+FToStr(Stops.at(c*2+2))+" "+FToStr(Stops.at(c*2+3))+"]\n");
5547
if (Colors.count() == 2)
5548
PutDoc("/Extend [true true]\n");
5552
PutDoc("/Extend [true false]\n");
5555
if (c == Colors.count()-2)
5556
PutDoc("/Extend [false true]\n");
5558
PutDoc("/Extend [false false]\n");
5562
PutDoc("/Function\n<<\n/FunctionType 2\n/Domain [0 1]\n");
5563
if (Options.UseSpotColors)
5567
PutDoc("/C0 ["+FToStr(colorShades[c] / 100.0)+"]\n");
5568
PutDoc("/C1 ["+FToStr(colorShades[c+1] / 100.0)+"]\n");
5572
PutDoc("/C0 [0 0 0 0 "+FToStr(colorShades[c] / 100.0)+"]\n");
5573
PutDoc("/C1 ["+Colors[c+1]+" 0 ]\n");
5577
PutDoc("/C0 ["+Colors[c]+" 0 ]\n");
5578
PutDoc("/C1 [0 0 0 0 "+FToStr(colorShades[c+1] / 100.0)+"]\n");
5582
PutDoc("/C0 ["+FToStr(colorShades[c] / 100.0)+" 0]\n");
5583
PutDoc("/C1 [0 "+FToStr(colorShades[c+1] / 100.0)+"]\n");
5587
PutDoc("/C0 ["+Colors[c]+"]\n");
5588
PutDoc("/C1 ["+Colors[c+1]+"]\n");
5593
PutDoc("/C0 ["+Colors[c]+"]\n");
5594
PutDoc("/C1 ["+Colors[c+1]+"]\n");
5597
PutDoc("/N 1\n>>\n>>\nendobj\n");
5601
StartObj(spotObject);
5602
PutDoc("<<\n/FunctionType 4\n");
5605
PutDoc("/Domain [0.0 1.0]\n");
5606
ScColorEngine::getCMYKValues(doc.PageColors[colorNames[c]], &doc, cmykValues);
5607
cmykValues.getValues(cc, mc, yc, kc);
5609
colorDesc += "dup "+FToStr(static_cast<double>(cc) / 255.0)+" mul exch\n";
5610
colorDesc += "dup "+FToStr(static_cast<double>(mc) / 255.0)+" mul exch\n";
5611
colorDesc += "dup "+FToStr(static_cast<double>(yc) / 255.0)+" mul exch\n";
5612
colorDesc += "dup "+FToStr(static_cast<double>(kc) / 255.0)+" mul exch pop\n}\n";
5616
PutDoc("/Domain [0.0 1.0 0.0 1.0]\n");
5617
ScColorEngine::getCMYKValues(doc.PageColors[colorNames[c]], &doc, cmykValues);
5618
cmykValues.getValues(cc, mc, yc, kc);
5619
colorDesc = "{\nexch\n";
5620
colorDesc += "dup "+FToStr(static_cast<double>(cc) / 255.0)+" mul 1.0 exch sub exch\n";
5621
colorDesc += "dup "+FToStr(static_cast<double>(mc) / 255.0)+" mul 1.0 exch sub exch\n";
5622
colorDesc += "dup "+FToStr(static_cast<double>(yc) / 255.0)+" mul 1.0 exch sub exch\n";
5623
colorDesc += "dup "+FToStr(static_cast<double>(kc) / 255.0)+" mul 1.0 exch sub exch pop 5 -1 roll\n";
5624
ScColorEngine::getCMYKValues(doc.PageColors[colorNames[c+1]], &doc, cmykValues);
5625
cmykValues.getValues(cc, mc, yc, kc);
5626
colorDesc += "dup "+FToStr(static_cast<double>(cc) / 255.0)+" mul 1.0 exch sub 6 -1 roll mul 1.0 exch sub 5 1 roll\n";
5627
colorDesc += "dup "+FToStr(static_cast<double>(mc) / 255.0)+" mul 1.0 exch sub 5 -1 roll mul 1.0 exch sub 4 1 roll\n";
5628
colorDesc += "dup "+FToStr(static_cast<double>(yc) / 255.0)+" mul 1.0 exch sub 4 -1 roll mul 1.0 exch sub 3 1 roll\n";
5629
colorDesc += "dup "+FToStr(static_cast<double>(kc) / 255.0)+" mul 1.0 exch sub 3 -1 roll mul 1.0 exch sub 2 1 roll pop\n}\n";
5633
PutDoc("/Domain [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]\n");
5636
ScColorEngine::getCMYKValues(doc.PageColors[colorNames[c]], &doc, cmykValues);
5637
cmykValues.getValues(cc, mc, yc, kc);
5641
ScColorEngine::getCMYKValues(doc.PageColors[colorNames[c+1]], &doc, cmykValues);
5642
cmykValues.getValues(cc, mc, yc, kc);
5644
colorDesc = "{\ndup "+FToStr(static_cast<double>(cc) / 255.0)+" mul 1.0 exch sub 6 -1 roll 1.0 exch sub mul 1.0 exch sub 5 1 roll\n";
5645
colorDesc += "dup "+FToStr(static_cast<double>(mc) / 255.0) +" mul 1.0 exch sub 5 -1 roll 1.0 exch sub mul 1.0 exch sub 4 1 roll\n";
5646
colorDesc += "dup "+FToStr(static_cast<double>(yc) / 255.0) +" mul 1.0 exch sub 4 -1 roll 1.0 exch sub mul 1.0 exch sub 3 1 roll\n";
5647
colorDesc += "dup "+FToStr(static_cast<double>(kc) / 255.0) +" mul 1.0 exch sub 3 -1 roll 1.0 exch sub mul 1.0 exch sub 2 1 roll pop\n}\n";
5649
PutDoc("/Range [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]\n");
5650
PutDoc("/Length "+QString::number(colorDesc.length()+1)+"\n");
5651
PutDoc(">>\nstream\n"+EncStream(colorDesc, spotObject)+"\nendstream\nendobj\n");
5654
if ((Options.Version >= PDFOptions::PDFVersion_14) && ((Trans.at(c+1) != 1) || (Trans.at(c) != 1)))
5655
tmp += "/"+TRes+" gs\n";
5656
tmp += SetClipPath(currItem);
5658
tmp += "/"+ShName+" sh\nQ\n";
5663
bool PDFLibCore::PDF_Annotation(PageItem *ite, uint)
5668
QMap<int, QString> ind2PDFabr;
5669
static const QString bifonts[] = {"/Courier", "/Courier-Bold", "/Courier-Oblique", "/Courier-BoldOblique",
5670
"/Helvetica", "/Helvetica-Bold", "/Helvetica-Oblique", "/Helvetica-BoldOblique",
5671
"/Times-Roman", "/Times-Bold", "/Times-Italic", "/Times-BoldItalic",
5672
"/ZapfDingbats", "/Symbol"};
5673
static const size_t ar = sizeof(bifonts) / sizeof(*bifonts);
5674
for (uint a = 0; a < ar; ++a)
5675
ind2PDFabr[a] = bifonts[a];
5676
double x = ite->xPos() - ActPageP->xOffset();
5677
double y = ActPageP->height() - (ite->yPos() - ActPageP->yOffset());
5678
double x2 = x+ite->width();
5679
double y2 = y-ite->height();
5680
QString bm(""), bmUtf16("");
5682
QFileInfo fiBase(Spool.fileName());
5683
QString baseDir = fiBase.absolutePath();
5684
if (!((ite->itemText.length() == 1) && (ite->itemText.text(0, 1) == QChar(13))))
5686
// #6823 EncStringUTF16() perform the string encoding by its own
5687
// via EncodeUTF16() so bmUtf16 must not encoded before
5688
for (uint d = 0; d < static_cast<uint>(ite->itemText.length()); ++d)
5690
cc = ite->itemText.text(d, 1);
5692
if ((cc == "(") || (cc == ")") || (cc == "\\"))
5694
if (cc == QChar(13))
5699
QString anTitle = ite->itemName().replace(".", "_" );
5700
QStringList bmst = bm.split("\\r", QString::SkipEmptyParts);
5701
QStringList bmstUtf16 = bmUtf16.split(QChar(13), QString::SkipEmptyParts);
5702
const QString m[] = {"4", "5", "F", "l", "H", "n"};
5703
QString ct(m[ite->annotation().ChkStil()]);
5704
uint annotationObj = newObject();
5705
uint appearanceObj = 0;
5710
if ((ite->annotation().Type() > 1) && ((ite->annotation().ActionType() == 1) || (ite->annotation().AAact())) && (!ite->annotation().Action().isEmpty()))
5711
actionObj = WritePDFString(ite->annotation().Action());
5712
uint AActionObj = writeActions(ite->annotation(), annotationObj);
5713
StartObj(annotationObj);
5714
Seite.AObjects.append(annotationObj);
5715
PutDoc("<<\n/Type /Annot\n");
5716
switch (ite->annotation().Type())
5720
PutDoc("/Subtype /Text\n");
5721
PutDoc("/Contents "+EncStringUTF16("("+bmUtf16+")",annotationObj)+"\n");
5725
PutDoc("/Subtype /Link\n");
5726
if (ite->annotation().ActionType() == 2)
5728
PutDoc("/Dest /"+NDnam+QString::number(NDnum)+"\n");
5730
de.Name = NDnam+QString::number(NDnum);
5731
de.Seite = ite->annotation().Ziel();
5732
de.Act = ite->annotation().Action();
5733
NamedDest.append(de);
5736
if (ite->annotation().ActionType() == 7)
5738
PutDoc("/A << /Type /Action /S /GoToR\n/F "+ EncString("("+Path2Relative(ite->annotation().Extern(), baseDir)+")",annotationObj)+"\n");
5739
PutDoc("/D ["+QString::number(ite->annotation().Ziel())+" /XYZ "+ite->annotation().Action()+"]\n>>\n");
5741
if (ite->annotation().ActionType() == 8)
5742
PutDoc("/A << /Type /Action /S /URI\n/URI "+ EncString("("+ite->annotation().Extern()+")",annotationObj)+"\n>>\n");
5743
if (ite->annotation().ActionType() == 9)
5745
PutDoc("/A << /Type /Action /S /GoToR\n/F "+ EncString("("+ite->annotation().Extern()+")",ObjCounter-1)+"\n");
5746
PutDoc("/D ["+QString::number(ite->annotation().Ziel())+" /XYZ "+ite->annotation().Action()+"]\n>>\n");
5754
Seite.FormObjects.append(annotationObj);
5755
PutDoc("/Subtype /Widget\n");
5756
PutDoc("/T "+EncString("("+anTitle+")",annotationObj)+"\n");
5757
if (!ite->annotation().ToolTip().isEmpty())
5758
PutDoc("/TU "+EncStringUTF16("("+PDFEncode(ite->annotation().ToolTip())+")",annotationObj)+"\n");
5760
QString mm[] = {"4", "2", "0", "32"};
5761
PutDoc(mm[ite->annotation().Vis()]);
5763
PutDoc("/BS << /Type /Border /W ");
5764
PutDoc(ite->annotation().borderColor() != CommonStrings::None ? QString::number(ite->annotation().Bwid()) : QString("0"));
5766
const QString x[] = {"S", "D", "U", "B", "I"};
5767
PutDoc(x[ite->annotation().Bsty()]);
5770
if (ite->annotation().Type() == 4)
5771
cnx += "/"+StdFonts["/ZapfDingbats"];
5774
if (Options.Version < PDFOptions::PDFVersion_14)
5775
cnx += "/"+StdFonts[ind2PDFabr[ite->annotation().Font()]];
5777
cnx += UsedFontsF[ite->itemText.defaultStyle().charStyle().font().replacementName()];
5778
// cnx += UsedFontsP[ite->itemText.defaultStyle().charStyle().font().replacementName()]+"Form";
5780
cnx += " "+FToStr(ite->itemText.defaultStyle().charStyle().fontSize() / 10.0)+" Tf";
5781
if (ite->itemText.defaultStyle().charStyle().fillColor() != CommonStrings::None)
5782
cnx += " "+ putColor(ite->itemText.defaultStyle().charStyle().fillColor(), ite->itemText.defaultStyle().charStyle().fillShade(), true);
5783
if (ite->fillColor() != CommonStrings::None)
5784
cnx += " "+ putColor(ite->fillColor(), ite->fillShade(), false);
5786
PutDoc("/DA "+EncString(cnx,annotationObj)+"\n");
5787
int flg = ite->annotation().Flag();
5788
if (Options.Version == PDFOptions::PDFVersion_13)
5790
PutDoc("/Ff "+QString::number(flg)+"\n");
5791
QString xs[] = {"N", "I", "O", "P"};
5792
switch (ite->annotation().Type())
5795
PutDoc("/FT /Btn\n");
5797
PutDoc(xs[ite->annotation().Feed()]);
5802
PutDoc("/FT /Tx\n");
5803
PutDoc("/V " + EncStringUTF16("("+bmUtf16+")",annotationObj)+"\n");
5804
PutDoc("/DV "+ EncStringUTF16("("+bmUtf16+")",annotationObj)+"\n");
5805
PutDoc("/Q "+QString::number(qMin(ite->itemText.defaultStyle().alignment(), ParagraphStyle::Rightaligned))+"\n");
5806
appearanceObj = newObject();
5807
PutDoc("/AP << /N "+QString::number(appearanceObj)+" 0 R >>\n");
5808
if (ite->annotation().MaxChar() != -1)
5809
PutDoc("/MaxLen "+QString::number(ite->annotation().MaxChar())+"\n");
5812
PutDoc("/FT /Btn\n");
5813
PutDoc(ite->annotation().IsChk() ? "/V /Yes\n/DV /Yes\n/AS /Yes\n" :
5814
"/V /Off\n/DV /Off\n/AS /Off\n");
5815
appearanceObj = newObject();
5816
PutDoc("/AP << /N << /Yes "+QString::number(appearanceObj)+" 0 R >> >>\n");
5820
PutDoc("/FT /Ch\n/V (");
5821
if (bmst.count() > 0)
5825
if (bmstUtf16.count() > 0)
5826
cnx += bmstUtf16[0];
5828
PutDoc(EncStringUTF16(cnx,annotationObj)+"\n");
5830
for (int bmc = 0; bmc < bmstUtf16.count(); ++bmc)
5831
PutDoc(EncStringUTF16("("+bmstUtf16[bmc]+")",annotationObj)+"\n");
5833
appearanceObj = newObject();
5834
PutDoc("/AP << /N "+QString::number(appearanceObj)+" 0 R >>\n");
5838
if ((ite->annotation().Type() == 5) || (ite->annotation().Type() == 6))
5840
PutDoc("/BG [ 1 1 1 ] ");
5841
if (ite->annotation().borderColor() != CommonStrings::None)
5842
PutDoc("/BC [ "+SetColor(ite->annotation().borderColor(), 100)+" ] ");
5846
if (ite->fillColor() != CommonStrings::None)
5847
PutDoc("/BG [ "+SetColor(ite->fillColor(), ite->fillShade())+" ] ");
5848
if (ite->annotation().borderColor() != CommonStrings::None)
5849
PutDoc("/BC [ "+SetColor(ite->annotation().borderColor(), 100)+" ] ");
5852
switch (ite->annotation().Type())
5855
PutDoc("/CA "+EncString("("+bm+")",annotationObj)+" ");
5856
if (!ite->annotation().RollOver().isEmpty())
5857
PutDoc("/RC "+ EncString("("+PDFEncode(ite->annotation().RollOver())+")",annotationObj)+" ");
5858
if (!ite->annotation().Down().isEmpty())
5859
PutDoc("/AC "+ EncString("("+PDFEncode(ite->annotation().Down())+")",annotationObj)+" ");
5860
if (ite->annotation().UseIcons())
5862
if (!ite->Pfile.isEmpty())
5864
IconOb += ite->pixm.hasAlpha() ? 3 : 2;
5865
icon1Obj = newObject();
5866
PutDoc("/I "+QString::number(icon1Obj)+" 0 R ");
5868
if (!ite->Pfile2.isEmpty())
5870
CMSettings cms(ite->doc(), "", Intent_Perceptual);
5871
img.LoadPicture(ite->Pfile2, 1, cms, false, false, ScImage::RGBData, 72);
5873
img3.getAlpha(ite->Pfile2, 1, im, true, false);
5874
IconOb += !im.isEmpty() ? 3 : 2;
5876
icon2Obj = newObject();
5877
PutDoc("/IX "+QString::number(icon2Obj)+" 0 R ");
5879
if (!ite->Pfile3.isEmpty())
5881
CMSettings cms(ite->doc(), "", Intent_Perceptual);
5882
img2.LoadPicture(ite->Pfile3, 1, cms, false, false, ScImage::RGBData, 72);
5884
img3.getAlpha(ite->Pfile3, 1, im, true, false);
5885
IconOb += !im.isEmpty() ? 3 : 2;
5887
icon3Obj = newObject();
5888
PutDoc("/RI "+QString::number(icon3Obj)+" 0 R ");
5890
PutDoc("/TP "+QString::number(ite->annotation().IPlace())+" ");
5891
PutDoc("/IF << /SW /");
5892
QString x[] = {"A", "S", "B", "N"};
5893
PutDoc(x[ite->annotation().ScaleW()]);
5895
PutDoc(ite->imageXScale() != ite->imageYScale() ? "A" : "P");
5897
if ((ite->width()/ite->imageXScale() - ite->pixm.width()) != 0)
5899
if (ite->annotation().ScaleW() == 3)
5900
PutDoc(FToStr(qMax(ite->imageXOffset() / (ite->width()/ite->imageXScale() - ite->pixm.width()), 0.01))+" ");
5906
if ((ite->height()/ite->imageYScale() - ite->pixm.height()) != 0)
5908
if (ite->annotation().ScaleW() == 3)
5909
PutDoc(FToStr(1.0 - qMax(ite->imageYOffset() / (ite->height()/ite->imageYScale() - ite->pixm.height()), 0.01)));
5923
PutDoc("/CA "+EncString("("+ct+")",annotationObj)+" ");
5926
if (ite->rotation() != 0)
5927
PutDoc("/R "+QString::number((abs(static_cast<int>(ite->rotation())) / 90)*90)+" ");
5929
if ((ite->annotation().ActionType() != 0) || (ite->annotation().AAact()))
5931
if (ite->annotation().ActionType() == 7)
5933
PutDoc("/A << /Type /Action /S /GoToR\n/F "+ EncString("("+Path2Relative(ite->annotation().Extern(), baseDir)+")",annotationObj)+ "\n");
5934
PutDoc("/D ["+QString::number(ite->annotation().Ziel())+" /XYZ "+ite->annotation().Action()+"]\n>>\n");
5936
if (ite->annotation().ActionType() == 9)
5938
PutDoc("/A << /Type /Action /S /GoToR\n/F "+ EncString("("+ite->annotation().Extern()+")",ObjCounter-1)+"\n");
5939
PutDoc("/D ["+QString::number(ite->annotation().Ziel())+" /XYZ "+ite->annotation().Action()+"]\n>>\n");
5941
if (ite->annotation().ActionType() == 5)
5942
PutDoc("/A << /Type /Action /S /ImportData\n/F "+ EncString("("+ite->annotation().Action()+")",annotationObj)+" >>\n");
5943
if (ite->annotation().ActionType() == 4)
5944
PutDoc("/A << /Type /Action /S /ResetForm >>\n");
5945
if (ite->annotation().ActionType() == 3)
5947
PutDoc("/A << /Type /Action /S /SubmitForm\n/F << /FS /URL /F "+ EncString("("+ite->annotation().Action()+")",annotationObj)+" >>\n");
5948
// if (ite->annotation().HTML())
5949
// PutDoc("/Flags 4");
5950
switch (ite->annotation().HTML())
5954
PutDoc("/Flags 4"); // bit 3 on
5958
PutDoc("/Flags 64"); // bit 6 on
5962
PutDoc("/Flags 512"); // bit 9 on
5972
if (ite->annotation().ActionType() == 1)
5974
if (!ite->annotation().Action().isEmpty())
5976
PutDoc("/A << /Type /Action /S /JavaScript /JS " + QString::number(actionObj) + " 0 R >>\n");
5979
if (ite->annotation().AAact())
5981
if (!ite->annotation().Action().isEmpty())
5983
PutDoc("/A << /Type /Action /S /JavaScript /JS " + QString::number(actionObj) + " 0 R >>\n");
5985
PutDoc("/AA " + QString::number(AActionObj) + " 0 R\n");
5987
if (ite->annotation().ActionType() == 2)
5989
PutDoc("/A << /Type /Action /S /GoTo /D /" + NDnam + QString::number(NDnum) + " >>\n");
5991
de.Name = NDnam+QString::number(NDnum);
5992
de.Seite = ite->annotation().Ziel();
5993
de.Act = ite->annotation().Action();
5994
NamedDest.append(de);
6000
if ((ite->annotation().Type() < 2) || (ite->annotation().Type() > 9))
6001
PutDoc("/Border [ 0 0 0 ]\n");
6002
switch (((abs(static_cast<int>(ite->rotation())) / 90)*90))
6007
x = ite->xPos() - ActPageP->xOffset();
6008
y2 = ActPageP->height() - (ite->yPos() - ActPageP->yOffset());
6009
x2 = x + ite->height();
6010
y = y2 + ite->width();
6013
x = ite->xPos() - ActPageP->xOffset() - ite->width();
6014
y2 = ActPageP->height() - (ite->yPos() - ActPageP->yOffset());
6015
x2 = ite->xPos() - ActPageP->xOffset();
6016
y = y2 + ite->height();
6019
x = ite->xPos() - ActPageP->xOffset() - ite->height();
6020
y2 = ActPageP->height() - (ite->yPos() - ActPageP->yOffset()) - ite->width();
6021
x2 = ite->xPos() - ActPageP->xOffset();
6022
y = ActPageP->height() - (ite->yPos() - ActPageP->yOffset());
6025
PutDoc("/Rect [ "+FToStr(x+bleedDisplacementX)+" "+FToStr(y2+bleedDisplacementY)+" "+FToStr(x2+bleedDisplacementX)+" "+FToStr(y+bleedDisplacementY)+" ]\n");
6026
PutDoc(">>\nendobj\n");
6028
if ((ite->annotation().Type() == 2) && (ite->annotation().UseIcons()))
6030
if (!ite->Pfile.isEmpty())
6032
if (!PDF_Image(ite, ite->Pfile, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), true))
6034
cc = QString::number(ite->pixm.width())+" 0 0 "+QString::number(ite->pixm.height())+" 0 0 cm\n";
6035
cc += "/"+ResNam+"I"+QString::number(ResCount-1)+" Do";
6036
PDF_xForm(icon1Obj, ite->pixm.width(), ite->pixm.height(), cc);
6038
if (!ite->Pfile2.isEmpty())
6040
if (!PDF_Image(ite, ite->Pfile2, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), true))
6042
cc = QString::number(img.width())+" 0 0 "+QString::number(img.height())+" 0 0 cm\n";
6043
cc += "/"+ResNam+"I"+QString::number(ResCount-1)+" Do";
6044
PDF_xForm(icon2Obj, img.width(), img.height(), cc);
6046
if (!ite->Pfile3.isEmpty())
6048
if (!PDF_Image(ite, ite->Pfile3, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), true))
6050
cc = QString::number(img2.width())+" 0 0 "+QString::number(img2.height())+" 0 0 cm\n";
6051
cc += "/"+ResNam+"I"+QString::number(ResCount-1)+" Do";
6052
PDF_xForm(icon3Obj, img2.width(), img2.height(), cc);
6055
// write Appearance?
6056
if (ite->annotation().Type() == 3)
6059
if (ite->fillColor() != CommonStrings::None)
6060
cc += putColor(ite->fillColor(), ite->fillShade(), false);
6061
cc += FToStr(x)+" "+FToStr(y2)+" "+FToStr(x2-x)+" "+FToStr(y-y2)+" re\nf\n";
6062
cc += "/Tx BMC\nBT\n";
6063
if (ite->itemText.defaultStyle().charStyle().fillColor() != CommonStrings::None)
6064
cc += putColor(ite->itemText.defaultStyle().charStyle().fillColor(), ite->itemText.defaultStyle().charStyle().fillShade(), true);
6065
if (Options.Version < PDFOptions::PDFVersion_14)
6066
cc += "/"+StdFonts[ind2PDFabr[ite->annotation().Font()]];
6068
cc += UsedFontsF[ite->itemText.defaultStyle().charStyle().font().replacementName()];
6069
// cc += UsedFontsP[ite->itemText.defaultStyle().charStyle().font().replacementName()]+"Form";
6070
cc += " "+FToStr(ite->itemText.defaultStyle().charStyle().fontSize() / 10.0)+" Tf\n";
6071
if (bmst.count() > 1)
6073
cc += "1 0 0 1 0 0 Tm\n0 0 Td\n";
6074
for (int mz = 0; mz < bmst.count(); ++mz)
6076
cc += EncStringUTF16("("+bmst[mz]+")",annotationObj);
6082
cc += "1 0 0 1 0 0 Tm\n0 0 Td\n"+EncStringUTF16("("+bmUtf16+")",annotationObj)+" Tj\nET\nEMC";
6083
PDF_xForm(appearanceObj, ite->width(), ite->height(), cc);
6085
if (ite->annotation().Type() == 4)
6088
if (ite->itemText.defaultStyle().charStyle().fillColor() != CommonStrings::None)
6089
cc += putColor(ite->itemText.defaultStyle().charStyle().fillColor(), ite->itemText.defaultStyle().charStyle().fillShade(), true);
6090
cc += "/"+StdFonts["/ZapfDingbats"]+" "+FToStr(ite->itemText.defaultStyle().charStyle().fontSize() / 10.0)+" Tf\n";
6091
cc += "0 0 Td\n("+ct+") Tj\nET\nQ";
6092
PDF_xForm(appearanceObj, ite->width(), ite->height(), cc);
6094
if ((ite->annotation().Type() == 5) || (ite->annotation().Type() == 6))
6098
cc += "0 0 "+FToStr(x2-x)+" "+FToStr(y-y2)+" re\nf\n";
6099
cc += QString::number(ite->annotation().Bwid())+" w\n";
6100
if (ite->annotation().borderColor() != CommonStrings::None)
6101
cc += putColor(ite->annotation().borderColor(), 100.0, false);
6104
cc += "0 0 "+FToStr(x2-x)+" "+FToStr(y-y2)+" re\nS\n";
6105
cc += "/Tx BMC\nq\nBT\n";
6107
if (Options.Version < PDFOptions::PDFVersion_14)
6108
cc += "/"+StdFonts[ind2PDFabr[ite->annotation().Font()]];
6110
cc += UsedFontsF[ite->itemText.defaultStyle().charStyle().font().replacementName()];
6111
// cc += UsedFontsP[ite->itemText.defaultStyle().charStyle().font().replacementName()]+"Form";
6112
cc += " "+FToStr(ite->itemText.defaultStyle().charStyle().fontSize() / 10.0)+" Tf\n";
6113
cc += "1 0 0 1 0 0 Tm\n0 0 Td\n";
6114
if (bmst.count() > 0)
6115
cc += EncStringUTF16("("+bmst[0]+")",annotationObj);
6116
cc += " Tj\nET\nQ\nEMC";
6117
PDF_xForm(appearanceObj, ite->width(), ite->height(), cc);
6122
uint PDFLibCore::writeActions(const Annotation& annot, uint annotationObj)
6125
if ((annot.Type() > 1) && (annot.AAact()))
6128
if (!annot.E_act().isEmpty())
6129
E = WritePDFString(annot.E_act());
6131
if (!annot.X_act().isEmpty())
6132
X = WritePDFString(annot.X_act());
6134
if (!annot.D_act().isEmpty())
6135
D = WritePDFString(annot.D_act());
6137
if (!annot.Fo_act().isEmpty())
6138
Fo = WritePDFString(annot.Fo_act());
6140
if (!annot.Bl_act().isEmpty())
6141
Bl = WritePDFString(annot.Bl_act());
6146
if ((annot.Type() == 3) || (annot.Type() == 5) || (annot.Type() == 6))
6148
if (!annot.K_act().isEmpty())
6149
K = WritePDFString(annot.K_act());
6150
if (!annot.F_act().isEmpty())
6151
F = WritePDFString(annot.F_act());
6152
if (!annot.V_act().isEmpty())
6153
V = WritePDFString(annot.V_act());
6154
if (!annot.C_act().isEmpty())
6156
C = WritePDFString(annot.C_act());
6157
CalcFields.append(annotationObj);
6161
uint result = newObject();
6166
PutDoc("/E << /Type /Action /S /JavaScript /JS "+QString::number(E)+" 0 R >>\n");
6170
PutDoc("/X << /Type /Action /S /JavaScript /JS "+QString::number(X)+" 0 R >>\n");
6174
PutDoc("/D << /Type /Action /S /JavaScript /JS "+QString::number(D)+" 0 R >>\n");
6178
PutDoc("/Fo << /Type /Action /S /JavaScript /JS "+QString::number(Fo)+" 0 R >>\n");
6182
PutDoc("/Bl << /Type /Action /S /JavaScript /JS "+QString::number(Bl)+" 0 R >>\n");
6184
if ((annot.Type() == 3) || (annot.Type() == 5) || (annot.Type() == 6))
6188
PutDoc("/K << /Type /Action /S /JavaScript /JS "+QString::number(K) + " 0 R >>\n");
6192
PutDoc("/F << /Type /Action /S /JavaScript /JS "+QString::number(F) + " 0 R >>\n");
6196
PutDoc("/V << /Type /Action /S /JavaScript /JS "+QString::number(V)+" 0 R >>\n");
6200
PutDoc("/C << /Type /Action /S /JavaScript /JS "+QString::number(C)+" 0 R >>\n");
6203
PutDoc(">>\nendobj\n");
6209
uint PDFLibCore::WritePDFStream(const QString& cc)
6211
uint result = newObject();
6213
if (Options.Compress)
6214
tmp = CompressStr(&tmp);
6216
PutDoc("<< /Length "+QString::number(tmp.length())); // moeglicherweise +1
6217
if (Options.Compress)
6218
PutDoc("\n/Filter /FlateDecode");
6219
PutDoc(" >>\nstream\n"+EncStream(tmp, result)+"\nendstream\nendobj\n");
6223
uint PDFLibCore::WritePDFString(const QString& cc)
6226
for (int i = 0; i < cc.length(); ++i)
6228
if (cc[i].unicode() > 255)
6231
tmp += toHex(cc[i].row());
6232
tmp += toHex(cc[i].cell());
6237
return WritePDFStream(tmp);
6240
void PDFLibCore::PDF_xForm(uint objNr, double w, double h, QString im)
6243
PutDoc("<<\n/Type /XObject\n/Subtype /Form\n");
6244
PutDoc("/BBox [ 0 0 "+FToStr(w)+" "+FToStr(h)+" ]\n");
6245
PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
6246
if (Seite.ImgObjects.count() != 0)
6248
PutDoc("/XObject <<\n");
6249
QMap<QString,int>::Iterator it;
6250
for (it = Seite.ImgObjects.begin(); it != Seite.ImgObjects.end(); ++it)
6251
PutDoc("/"+it.key()+" "+QString::number(it.value())+" 0 R\n");
6254
if (Seite.FObjects.count() != 0)
6256
PutDoc("/Font << \n");
6257
QMap<QString,int>::Iterator it2;
6258
for (it2 = Seite.FObjects.begin(); it2 != Seite.FObjects.end(); ++it2)
6259
PutDoc("/"+it2.key()+" "+QString::number(it2.value())+" 0 R\n");
6263
PutDoc("/Length "+QString::number(im.length())+"\n");
6264
PutDoc(">>\nstream\n"+EncStream(im, objNr)+"\nendstream\nendobj\n");
6265
Seite.XObjects[ResNam+QString::number(ResCount)] = objNr;
6269
void PDFLibCore::PDF_Form(const QString& im) // unused? - av
6271
uint form = newObject();
6274
PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
6275
if (Seite.FObjects.count() != 0)
6277
PutDoc("/Font << \n");
6278
QMap<QString,int>::Iterator it2;
6279
for (it2 = Seite.FObjects.begin(); it2 != Seite.FObjects.end(); ++it2)
6280
PutDoc("/"+it2.key()+" "+QString::number(it2.value())+" 0 R\n");
6284
PutDoc("/Length "+QString::number(im.length())+"\n");
6285
PutDoc(">>\nstream\n"+EncStream(im, form)+"\nendstream\nendobj\n");
6288
void PDFLibCore::PDF_Bookmark(PageItem *currItem, double ypos)
6290
Bvie->SetAction(currItem, "/XYZ 0 "+FToStr(ypos)+" 0]");
6295
bool PDFLibCore::PDF_EmbeddedPDF(PageItem* c, const QString& fn, double sx, double sy, double x, double y, bool fromAN, const QString& Profil, bool Embedded, int Intent, ShIm& imgInfo, QString* output)
6297
if (!Options.embedPDF)
6303
PoDoFo::PdfError::EnableDebug( false );
6304
#if (PODOFO_VERSION == 0 && PODOFO_MINOR > 6)
6305
PoDoFo::PdfError::EnableLogging( false );
6307
#if (PODOFO_VERSION == 0 && PODOFO_MINOR == 5 && PODOFO_REVISION == 99) || PODOFO_MINOR > 5
6308
PoDoFo::PdfMemDocument doc( fn.toLocal8Bit().data() );
6310
PoDoFo::PdfDocument doc( fn.toLocal8Bit().data() );
6312
PoDoFo::PdfPage* page = doc.GetPage(qMin(qMax(1, c->pixm.imgInfo.actualPageNumber), c->pixm.imgInfo.numberOfPages) - 1);
6313
PoDoFo::PdfObject* contents = page? page->GetContents() : NULL;
6314
PoDoFo::PdfObject* resources = page? page->GetResources() : NULL;
6315
for (PoDoFo::PdfObject* par = page->GetObject(); par && !resources; par = par->GetIndirectKey("Parent"))
6317
resources = par->GetIndirectKey("Resources");
6319
if (contents && contents->GetDataType() == PoDoFo::ePdfDataType_Dictionary)
6321
PoDoFo::PdfStream* stream = contents->GetStream();
6322
QMap<PoDoFo::PdfReference, uint> importedObjects;
6323
QList<PoDoFo::PdfReference> referencedObjects;
6324
PoDoFo::PdfObject* nextObj;
6325
uint xObj = newObject();
6326
uint xResources = newObject();
6328
importedObjects[page->GetObject()->Reference()] = xObj;
6330
PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1");
6331
PoDoFo::PdfRect pagesize = page->GetPageSize();
6332
int rotation = page->GetRotation();
6334
pageM.scale(1.0/pagesize.GetWidth(), 1.0/pagesize.GetHeight());
6335
pageM.rotate(-rotation);
6336
PutDoc("\n/BBox [" + QString::number(pagesize.GetLeft(), 'f'));
6337
PutDoc(" " + QString::number(pagesize.GetBottom(), 'f'));
6338
PutDoc(" " + QString::number(pagesize.GetLeft() + pagesize.GetWidth(), 'f'));
6339
PutDoc(" " + QString::number(pagesize.GetBottom() + pagesize.GetHeight(), 'f'));
6341
PutDoc("\n/Matrix [" + QString::number(pageM.m11(), 'f') + " "
6342
+ QString::number(pageM.m12(), 'f') + " "
6343
+ QString::number(pageM.m21(), 'f') + " "
6344
+ QString::number(pageM.m22(), 'f') + " ");
6347
else if (rotation == 90)
6349
else if (rotation == 180)
6351
else if (rotation == 270)
6352
PutDoc(QString::number(pagesize.GetHeight() / pagesize.GetWidth()) + " " + QString::number(1.0 - 1.0 / (pagesize.GetHeight() / pagesize.GetWidth())));
6356
// PutDoc("\n/Matrix [" + QString::number(1.0/pagesize.GetWidth()) + " 0 0 " + QString::number(1.0/pagesize.GetHeight()) + " 0 0]");
6357
PutDoc("\n/Resources " + QString::number(xResources) + " 0 R");
6358
nextObj = page->GetObject()->GetIndirectKey("Group");
6361
PutDoc("\n/Group "); // PDF 1.4
6362
copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6365
PoDoFo::PdfObject parents = page->GetObject()->GetIndirectKey("StructParents");
6368
xParents = newObject();
6369
PutDoc("\n/StructParents " + QString::number(xParents)); // required if page uses structured content
6372
char * mbuffer = NULL;
6373
#if (PODOFO_MAJOR == 0 && PODOFO_MINOR >= 8)
6374
PoDoFo::pdf_long mlen = 0;
6375
#elif defined(pdf_long)
6380
stream->GetCopy(&mbuffer, &mlen);
6381
if (mbuffer[mlen-1] == '\n')
6383
PutDoc("\n/Length " + QString::number(mlen));
6384
nextObj = contents->GetIndirectKey("Filter");
6387
PutDoc("\n/Filter ");
6388
copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6390
nextObj = contents->GetIndirectKey("DecodeParms");
6393
PutDoc("\n/DecodeParms ");
6394
copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6396
PutDoc("\n>>\nstream\n");
6398
QByteArray buffer = QByteArray::fromRawData(mbuffer, mlen);
6399
EncodeArrayToStream(buffer, xObj);
6400
} // disconnect QByteArray from raw data
6402
PutDoc("\nendstream\nendobj\n");
6406
copyPoDoFoObject(resources, xResources, importedObjects);
6410
StartObj(xResources);
6411
PutDoc("<< >>\nendobj\n");
6415
// create structured parents
6417
// write referenced objects
6418
PoDoFo::PdfVecObjects* allObjects = contents->GetOwner();
6419
for (int i=0; i < referencedObjects.size(); ++i)
6421
nextObj = allObjects->GetObject(referencedObjects[i]);
6422
copyPoDoFoObject(nextObj, importedObjects[nextObj->Reference()], importedObjects);
6425
Seite.ImgObjects[ResNam+"I"+QString::number(ResCount)] = xObj;
6426
imgInfo.ResNum = ResCount;
6428
// Avoid a divide-by-zero if width/height are less than 1 point:
6429
imgInfo.Width = qMax(1, (int) pagesize.GetWidth());
6430
imgInfo.Height = qMax(1, (int) pagesize.GetHeight());
6431
imgInfo.xa = sx * pagesize.GetWidth()/imgInfo.Width;
6432
imgInfo.ya = sy * pagesize.GetHeight()/imgInfo.Height;
6433
// Width/Height are integers and may not exactly equal pagesize.GetWidth()/
6434
// pagesize.GetHeight(). Adjust scale factor to compensate for the difference.
6435
imgInfo.sxa = sx * pagesize.GetWidth()/imgInfo.Width;
6436
imgInfo.sya = sy * pagesize.GetHeight()/imgInfo.Height;
6440
else if (contents && contents->GetDataType() == PoDoFo::ePdfDataType_Array)//Page contents might be an array
6442
QMap<PoDoFo::PdfReference, uint> importedObjects;
6443
QList<PoDoFo::PdfReference> referencedObjects;
6444
PoDoFo::PdfObject* nextObj;
6445
uint xObj = newObject();
6446
uint xResources = newObject();
6448
importedObjects[page->GetObject()->Reference()] = xObj;
6450
PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1");
6451
PoDoFo::PdfRect pagesize = page->GetPageSize();
6452
int rotation = page->GetRotation();
6454
pageM.scale(1.0/pagesize.GetWidth(), 1.0/pagesize.GetHeight());
6455
pageM.rotate(-rotation);
6456
PutDoc("\n/BBox [" + QString::number(pagesize.GetLeft(), 'f'));
6457
PutDoc(" " + QString::number(pagesize.GetBottom(), 'f'));
6458
PutDoc(" " + QString::number(pagesize.GetLeft() + pagesize.GetWidth(), 'f'));
6459
PutDoc(" " + QString::number(pagesize.GetBottom() + pagesize.GetHeight(), 'f'));
6461
PutDoc("\n/Matrix [" + QString::number(pageM.m11(), 'f') + " "
6462
+ QString::number(pageM.m12(), 'f') + " "
6463
+ QString::number(pageM.m21(), 'f') + " "
6464
+ QString::number(pageM.m22(), 'f') + " ");
6467
else if (rotation == 90)
6469
else if (rotation == 180)
6471
else if (rotation == 270)
6472
PutDoc(QString::number(pagesize.GetHeight() / pagesize.GetWidth(), 'f') + " " + QString::number(1.0 - 1.0 / (pagesize.GetHeight() / pagesize.GetWidth()), 'f'));
6476
PutDoc("\n/Resources " + QString::number(xResources) + " 0 R");
6477
nextObj = page->GetObject()->GetIndirectKey("Group");
6480
PutDoc("\n/Group "); // PDF 1.4
6481
copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6484
char * mbuffer = NULL;
6486
// copied from podofoimpose
6487
PoDoFo::PdfMemoryOutputStream outMemStream ( 1 );
6488
// PoDoFo::PdfFilteredEncodeStream outMemStream (outMemStreamRaw, ePdfFilter_FlateDecode, false);
6489
PoDoFo::PdfArray carray(page->GetContents()->GetArray());
6490
for(unsigned int ci = 0; ci < carray.size(); ++ci)
6492
if(carray[ci].HasStream())
6494
carray[ci].GetStream()->GetFilteredCopy ( &outMemStream );
6496
else if(carray[ci].IsReference())
6499
nextObj = doc.GetObjects().GetObject(carray[ci].GetReference());
6501
while(nextObj != NULL)
6504
if(nextObj->IsReference())
6506
nextObj = doc.GetObjects().GetObject(nextObj->GetReference());
6508
else if(nextObj->HasStream())
6510
nextObj->GetStream()->GetFilteredCopy ( &outMemStream );
6519
mlen = outMemStream.GetLength();
6520
mbuffer = outMemStream.TakeBuffer();
6521
// if (mbuffer[mlen-1] == '\n')
6523
PutDoc("\n/Length " + QString::number(mlen));
6525
nextObj = contents->GetIndirectKey("Filter");
6528
PutDoc("\n/Filter ");
6529
copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6531
nextObj = contents->GetIndirectKey("DecodeParms");
6534
PutDoc("\n/DecodeParms ");
6535
copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6538
PutDoc("\n>>\nstream\n");
6540
QByteArray buffer = QByteArray::fromRawData(mbuffer, mlen);
6541
EncodeArrayToStream(buffer, xObj);
6542
} // disconnect QByteArray from raw data
6544
PutDoc("\nendstream\nendobj\n");
6548
copyPoDoFoObject(resources, xResources, importedObjects);
6552
StartObj(xResources);
6553
PutDoc("<< >>\nendobj\n");
6557
// create structured parents
6559
// write referenced objects
6560
PoDoFo::PdfVecObjects* allObjects = contents->GetOwner();
6561
for (int i=0; i < referencedObjects.size(); ++i)
6563
nextObj = allObjects->GetObject(referencedObjects[i]);
6564
copyPoDoFoObject(nextObj, importedObjects[nextObj->Reference()], importedObjects);
6567
Seite.ImgObjects[ResNam+"I"+QString::number(ResCount)] = xObj;
6568
imgInfo.ResNum = ResCount;
6570
// Avoid a divide-by-zero if width/height are less than 1 point:
6571
imgInfo.Width = qMax(1, (int) pagesize.GetWidth());
6572
imgInfo.Height = qMax(1, (int) pagesize.GetHeight());
6573
imgInfo.xa = sx * pagesize.GetWidth()/imgInfo.Width;
6574
imgInfo.ya = sy * pagesize.GetHeight()/imgInfo.Height;
6575
// Width/Height are integers and may not exactly equal pagesize.GetWidth()/
6576
// pagesize.GetHeight(). Adjust scale factor to compensate for the difference.
6577
imgInfo.sxa = sx * pagesize.GetWidth()/imgInfo.Width;
6578
imgInfo.sya = sy * pagesize.GetHeight()/imgInfo.Height;
6584
catch(PoDoFo::PdfError& e)
6586
qDebug() << "PoDoFo error!";
6598
void PDFLibCore::copyPoDoFoDirect(const PoDoFo::PdfVariant* obj, QList<PoDoFo::PdfReference>& referencedObjects, QMap<PoDoFo::PdfReference, uint>& importedObjects)
6600
switch (obj->GetDataType())
6602
case PoDoFo::ePdfDataType_Reference:
6604
const PoDoFo::PdfReference reference(obj->GetReference());
6606
if (!importedObjects.contains(reference))
6608
objNr = newObject();
6609
importedObjects[reference] = objNr;
6610
referencedObjects.append(reference);
6614
objNr = importedObjects[reference];
6616
PutDoc(" " + QString::number(objNr) + " 0 R");
6619
case PoDoFo::ePdfDataType_Array:
6621
const PoDoFo::PdfArray& array(obj->GetArray());
6623
for (uint i=0; i < array.size(); ++i)
6624
copyPoDoFoDirect( &(array[i]), referencedObjects, importedObjects);
6628
case PoDoFo::ePdfDataType_Dictionary:
6630
const PoDoFo::PdfDictionary& dict(obj->GetDictionary());
6631
const PoDoFo::TKeyMap keys = dict.GetKeys();
6633
for (PoDoFo::TCIKeyMap k=keys.begin(); k != keys.end(); ++k)
6635
PutDoc("\n/" + k->first.GetEscapedName());
6636
copyPoDoFoDirect(k->second, referencedObjects, importedObjects);
6651
void PDFLibCore::copyPoDoFoObject(const PoDoFo::PdfObject* obj, uint scObjID, QMap<PoDoFo::PdfReference, uint>& importedObjects)
6653
PoDoFo::PdfVecObjects* allObjects = obj->GetOwner();
6654
QList<PoDoFo::PdfReference> referencedObjects;
6656
copyPoDoFoDirect(obj, referencedObjects, importedObjects);
6657
if (obj->HasStream())
6659
char * mbuffer = NULL;
6660
#if (PODOFO_MAJOR == 0 && PODOFO_MINOR >= 8)
6661
PoDoFo::pdf_long mlen = 0;
6662
#elif defined(pdf_long)
6667
const PoDoFo::PdfStream* stream = obj->GetStream();
6668
stream->GetCopy(&mbuffer, &mlen);
6669
if (mbuffer[mlen-1] == '\n')
6671
PutDoc("\nstream\n");
6673
QByteArray buffer = QByteArray::fromRawData(mbuffer, mlen);
6674
EncodeArrayToStream(buffer, scObjID);
6675
} // disconnect QByteArray from raw data
6677
PutDoc("\nendstream");
6679
PutDoc("\nendobj\n");
6681
for (int i=0; i < referencedObjects.size(); ++i)
6683
PoDoFo::PdfObject* nextObj = allObjects->GetObject(referencedObjects[i]);
6684
copyPoDoFoObject(nextObj, importedObjects[nextObj->Reference()], importedObjects);
6690
bool PDFLibCore::PDF_Image(PageItem* c, const QString& fn, double sx, double sy, double x, double y, bool fromAN, const QString& Profil, bool Embedded, eRenderIntent Intent, QString* output)
6692
QFileInfo fi = QFileInfo(fn);
6693
QString ext = fi.suffix().toLower();
6695
ext = getImageType(fn);
6697
QString tmp, tmpy, dummy, cmd1, cmd2, BBox;
6700
bool alphaM = false;
6701
bool realCMYK = false;
6702
bool bitmapFromGS = false;
6703
bool isEmbeddedPDF = false;
6704
bool hasGrayProfile = false;
6705
QString profInUse = Profil;
6706
int afl = Options.Resolution;
6707
double ax, ay, a2, a1;
6714
if (Options.RecalcPic)
6715
ImInfo.reso = Options.PicRes / 72.0;
6717
ImInfo.reso = Options.Resolution / 72.0;
6723
ImInfo.origXsc = c->imageXScale();
6724
ImInfo.origYsc = c->imageYScale();
6726
ImInfo2.origXsc = c->imageXScale();
6727
ImInfo2.origYsc = c->imageYScale();
6728
if (SharedImages.contains(fn))
6729
ImInfo2 = SharedImages[fn];
6730
if ((!SharedImages.contains(fn))
6732
|| (c->asLatexFrame())
6733
|| (c->effectsInUse.count() != 0)
6734
|| ((ImInfo2.origXsc != ImInfo.origXsc) || (ImInfo2.origYsc != ImInfo.origYsc))
6735
|| (ImInfo2.RequestProps != c->pixm.imgInfo.RequestProps)
6736
|| (ImInfo2.Page != c->pixm.imgInfo.actualPageNumber))
6738
bool imageLoaded = false;
6739
if ((extensionIndicatesPDF(ext) || ((extensionIndicatesEPSorPS(ext)) && (c->pixm.imgInfo.type != ImageType7))) && c->effectsInUse.count() == 0)
6741
if (extensionIndicatesEPSorPS(ext))
6743
QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.pdf");
6745
opts.append("-dEPSCrop");
6746
if (Options.Version >= PDFOptions::PDFVersion_14)
6747
opts.append( "-dCompatibilityLevel=1.4" );
6749
opts.append( "-dCompatibilityLevel=1.3" );
6750
/* These options don't seem to work
6751
if ((Options.UseRGB) || ((doc.HasCMS) && (Options.UseProfiles2)) || (Options.isGrayscale))
6752
opts.append( "-sProcessColorModel=/DeviceRGB" );
6754
opts.append( "-sProcessColorModel=/DeviceCMYK" ); */
6755
if (convertPS2PDF(fn, tmpFile, opts) == 0)
6757
imageLoaded = PDF_EmbeddedPDF(c, tmpFile, sx, sy, x, y, fromAN, Profil, Embedded, Intent, ImInfo, output);
6758
QFile::remove(tmpFile);
6762
imageLoaded = PDF_EmbeddedPDF(c, fn, sx, sy, x, y, fromAN, Profil, Embedded, Intent, ImInfo, output);
6763
isEmbeddedPDF = true;
6764
ImInfo.Page = c->pixm.imgInfo.actualPageNumber;
6766
if(!imageLoaded && extensionIndicatesPDF(ext) && c->effectsInUse.count() == 0 && Options.embedPDF)
6767
qDebug() << "Failed to embed the PDF file";
6771
if ((extensionIndicatesPDF(ext) || extensionIndicatesEPSorPS(ext)) && (c->pixm.imgInfo.type != ImageType7))
6773
bitmapFromGS = true;
6774
if (Options.RecalcPic)
6776
afl = qMin(Options.PicRes, Options.Resolution);
6777
ImInfo.reso = afl / 72.0;
6780
afl = Options.Resolution;
6783
CMSettings cms(c->doc(), Profil, Intent);
6785
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6788
if ((doc.HasCMS) && (Options.UseProfiles2))
6789
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6792
if (Options.isGrayscale)
6793
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6795
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::CMYKData, afl);
6802
if (f.open(QIODevice::ReadOnly))
6807
tmp = readLinefromDataStream(ts);
6808
if (tmp.startsWith("%%BoundingBox:"))
6811
BBox = tmp.remove("%%BoundingBox:");
6815
if (tmp.startsWith("%%BoundingBox"))
6818
BBox = tmp.remove("%%BoundingBox");
6821
if (tmp.startsWith("%%EndComments"))
6827
CMSettings cms(c->doc(), Profil, Intent);
6829
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6832
if ((doc.HasCMS) && (Options.UseProfiles2))
6833
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6836
if (Options.isGrayscale)
6837
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6839
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::CMYKData, afl);
6847
PDF_Error_ImageLoadFailure(fn);
6850
if (Options.RecalcPic)
6852
ImInfo.sxa = sx * (1.0 / ImInfo.reso);
6853
ImInfo.sya = sy * (1.0 / ImInfo.reso);
6859
img.imgInfo.valid = false;
6860
img.imgInfo.clipPath = "";
6861
img.imgInfo.PDSpathData.clear();
6862
img.imgInfo.layerInfo.clear();
6863
img.imgInfo.RequestProps = c->pixm.imgInfo.RequestProps;
6864
img.imgInfo.isRequest = c->pixm.imgInfo.isRequest;
6865
CMSettings cms(c->doc(), Profil, Intent);
6867
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, 72, &realCMYK);
6870
if ((doc.HasCMS) && (Options.UseProfiles2))
6871
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RawData, 72, &realCMYK);
6874
if (Options.isGrayscale)
6875
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, 72, &realCMYK);
6877
imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::CMYKData, 72, &realCMYK);
6882
PDF_Error_ImageLoadFailure(fn);
6885
if ((Options.RecalcPic) && (Options.PicRes < (qMax(72.0 / c->imageXScale(), 72.0 / c->imageYScale()))))
6887
double afl = Options.PicRes;
6888
a2 = (72.0 / sx) / afl;
6889
a1 = (72.0 / sy) / afl;
6890
origWidth = img.width();
6891
origHeight = img.height();
6892
ax = img.width() / a2;
6893
ay = img.height() / a1;
6894
if ((Options.UseRGB) || (Options.isGrayscale) || ((Options.UseProfiles2) && !(img.imgInfo.colorspace == ColorSpaceCMYK)) )
6896
ColorSpaceEnum colsp = img.imgInfo.colorspace;
6897
bool prog = img.imgInfo.progressive;
6898
img = img.scaled(qRound(ax), qRound(ay), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
6899
img.imgInfo.colorspace = colsp;
6900
img.imgInfo.progressive = prog;
6903
img.scaleImage(qRound(ax), qRound(ay));
6904
ImInfo.sxa = sx * a2;
6905
ImInfo.sya = sy * a1;
6909
bool hasColorEffect = false;
6910
if (c->effectsInUse.count() != 0)
6912
for (int a = 0; a < c->effectsInUse.count(); ++a)
6914
if (c->effectsInUse.at(a).effectCode == ScImage::EF_COLORIZE)
6915
hasColorEffect = true;
6916
if (c->effectsInUse.at(a).effectCode == ScImage::EF_DUOTONE)
6917
hasColorEffect = true;
6918
if (c->effectsInUse.at(a).effectCode == ScImage::EF_TRITONE)
6919
hasColorEffect = true;
6920
if (c->effectsInUse.at(a).effectCode == ScImage::EF_QUADTONE)
6921
hasColorEffect = true;
6924
if ((doc.HasCMS) && (Options.UseProfiles2))
6926
if (!ICCProfiles.contains(Profil))
6930
uint embeddedProfile = newObject();
6931
StartObj(embeddedProfile);
6934
if ((Embedded) && (!Options.EmbeddedI))
6935
img3.getEmbeddedProfile(fn, &dataP, &components);
6936
if ((dataP.isEmpty()) || ((img.imgInfo.colorspace == ColorSpaceGray) && (hasColorEffect) && (components == 1)))
6938
if (img.imgInfo.colorspace == ColorSpaceCMYK)
6940
QString profilePath;
6941
if (Embedded && ScCore->InputProfilesCMYK.contains(Options.ImageProf))
6943
profilePath = ScCore->InputProfilesCMYK[Options.ImageProf];
6944
profInUse = Options.ImageProf;
6946
else if (ScCore->InputProfilesCMYK.contains(Profil))
6947
profilePath = ScCore->InputProfilesCMYK[Profil];
6950
profilePath = ScCore->InputProfilesCMYK[c->doc()->CMSSettings.DefaultImageCMYKProfile];
6951
profInUse = c->doc()->CMSSettings.DefaultImageCMYKProfile;
6953
loadRawBytes(profilePath, dataP);
6958
QString profilePath;
6959
if (Embedded && ScCore->InputProfiles.contains(Options.ImageProf))
6961
profilePath = ScCore->InputProfiles[Options.ImageProf];
6962
profInUse = Options.ImageProf;
6964
else if (ScCore->InputProfiles.contains(Profil))
6965
profilePath = ScCore->InputProfiles[Profil];
6968
profilePath = ScCore->InputProfiles[c->doc()->CMSSettings.DefaultImageRGBProfile];
6969
profInUse = c->doc()->CMSSettings.DefaultImageRGBProfile;
6971
loadRawBytes(profilePath, dataP);
6975
if (!ICCProfiles.contains(profInUse))
6978
if ((Options.CompressMethod != PDFOptions::Compression_None) && Options.Compress)
6980
QByteArray compData = CompressArray(dataP);
6981
if (compData.size() > 0)
6983
PutDoc("/Filter /FlateDecode\n");
6987
PutDoc("/Length "+QString::number(dataP.size()+1)+"\n");
6988
PutDoc("/N "+QString::number(components)+"\n");
6989
PutDoc(">>\nstream\n");
6990
EncodeArrayToStream(dataP, embeddedProfile);
6991
PutDoc("\nendstream\nendobj\n");
6992
uint profileResource = newObject();
6993
StartObj(profileResource);
6994
dataD.ResName = ResNam+QString::number(ResCount);
6995
dataD.ICCArray = "[ /ICCBased "+QString::number(embeddedProfile)+" 0 R ]";
6996
dataD.ResNum = profileResource;
6997
dataD.components = components;
6998
ICCProfiles[profInUse] = dataD;
6999
PutDoc("[ /ICCBased "+QString::number(embeddedProfile)+" 0 R ]\n");
7003
if (components == 1)
7004
hasGrayProfile = true;
7008
if (ICCProfiles[Profil].components == 1)
7010
if ((img.imgInfo.colorspace == ColorSpaceGray) && (hasColorEffect))
7012
profInUse = c->doc()->CMSSettings.DefaultImageRGBProfile;
7013
if (!ICCProfiles.contains(profInUse))
7016
uint embeddedProfile = newObject();
7017
StartObj(embeddedProfile);
7020
loadRawBytes(ScCore->InputProfiles[c->doc()->CMSSettings.DefaultImageRGBProfile], dataP);
7023
if ((Options.CompressMethod != PDFOptions::Compression_None) && Options.Compress)
7025
QByteArray compData = CompressArray(dataP);
7026
if (compData.size() > 0)
7028
PutDoc("/Filter /FlateDecode\n");
7032
PutDoc("/Length "+QString::number(dataP.size()+1)+"\n");
7033
PutDoc("/N "+QString::number(components)+"\n");
7034
PutDoc(">>\nstream\n");
7035
EncodeArrayToStream(dataP, embeddedProfile);
7036
PutDoc("\nendstream\nendobj\n");
7037
uint profileResource = newObject();
7038
StartObj(profileResource);
7039
dataD.ResName = ResNam+QString::number(ResCount);
7040
dataD.ICCArray = "[ /ICCBased "+QString::number(embeddedProfile)+" 0 R ]";
7041
dataD.ResNum = profileResource;
7042
dataD.components = components;
7043
ICCProfiles[profInUse] = dataD;
7044
PutDoc("[ /ICCBased "+QString::number(embeddedProfile)+" 0 R ]\n");
7050
hasGrayProfile = true;
7056
img2.imgInfo.clipPath = "";
7057
img2.imgInfo.PDSpathData.clear();
7058
img2.imgInfo.layerInfo.clear();
7059
img2.imgInfo.RequestProps = c->pixm.imgInfo.RequestProps;
7060
img2.imgInfo.isRequest = c->pixm.imgInfo.isRequest;
7061
if (c->pixm.imgInfo.type == ImageType7)
7065
bool gotAlpha = false;
7066
bool pdfVer14 = (Options.Version >= PDFOptions::PDFVersion_14);
7067
gotAlpha = img2.getAlpha(fn, c->pixm.imgInfo.actualPageNumber, im2, true, pdfVer14, afl, img.width(), img.height());
7070
PDF_Error_MaskLoadFailure(fn);
7073
alphaM = !im2.isEmpty();
7076
if ((Options.UseRGB) || (Options.isGrayscale))
7080
if ((Options.UseProfiles2) && (img.imgInfo.colorspace != ColorSpaceCMYK))
7085
origWidth = img.width();
7086
origHeight = img.height();
7087
img.applyEffect(c->effectsInUse, c->doc()->PageColors, imgE);
7088
if (!((Options.RecalcPic) && (Options.PicRes < (qMax(72.0 / c->imageXScale(), 72.0 / c->imageYScale())))))
7090
ImInfo.sxa = sx * (1.0 / ImInfo.reso);
7091
ImInfo.sya = sy * (1.0 / ImInfo.reso);
7096
bool compAlphaAvail = false;
7097
maskObj = newObject();
7099
PutDoc("<<\n/Type /XObject\n/Subtype /Image\n");
7100
if (Options.CompressMethod != PDFOptions::Compression_None)
7102
QByteArray compAlpha = CompressArray(im2);
7103
if (compAlpha.size() > 0)
7106
compAlphaAvail = true;
7109
if (Options.Version >= PDFOptions::PDFVersion_14)
7111
PutDoc("/Width "+QString::number(origWidth)+"\n");
7112
PutDoc("/Height "+QString::number(origHeight)+"\n");
7113
PutDoc("/ColorSpace /DeviceGray\n");
7114
PutDoc("/BitsPerComponent 8\n");
7115
PutDoc("/Length "+QString::number(im2.size())+"\n");
7119
PutDoc("/Width "+QString::number(origWidth)+"\n");
7120
PutDoc("/Height "+QString::number(origHeight)+"\n");
7121
PutDoc("/ImageMask true\n/BitsPerComponent 1\n");
7122
PutDoc("/Length "+QString::number(im2.size())+"\n");
7124
if ((Options.CompressMethod != PDFOptions::Compression_None) && compAlphaAvail)
7125
PutDoc("/Filter /FlateDecode\n");
7126
PutDoc(">>\nstream\n");
7127
EncodeArrayToStream(im2, maskObj);
7128
PutDoc("\nendstream\nendobj\n");
7129
Seite.ImgObjects[ResNam+"I"+QString::number(ResCount)] = maskObj;
7132
uint imageObj = newObject();
7134
PutDoc("<<\n/Type /XObject\n/Subtype /Image\n");
7135
PutDoc("/Width "+QString::number(img.width())+"\n");
7136
PutDoc("/Height "+QString::number(img.height())+"\n");
7137
if ((doc.HasCMS) && (Options.UseProfiles2))
7139
PutDoc("/ColorSpace "+ICCProfiles[profInUse].ICCArray+"\n");
7140
PutDoc("/Intent /");
7142
if (Options.EmbeddedI)
7143
inte2 = Options.Intent2;
7144
static const QString cmsmode[] = {"Perceptual", "RelativeColorimetric", "Saturation", "AbsoluteColorimetric"};
7145
PutDoc(cmsmode[inte2] + "\n");
7150
PutDoc("/ColorSpace /DeviceRGB\n");
7153
if (Options.isGrayscale)
7154
PutDoc("/ColorSpace /DeviceGray\n");
7156
PutDoc("/ColorSpace /DeviceCMYK\n");
7159
enum PDFOptions::PDFCompression cm = Options.CompressMethod;
7160
bool exportToCMYK = false, exportToGrayscale = false, jpegUseOriginal = false;
7161
if (!Options.UseRGB && !(doc.HasCMS && Options.UseProfiles2 && !realCMYK))
7163
exportToGrayscale = Options.isGrayscale;
7164
if (exportToGrayscale)
7165
exportToCMYK = !Options.isGrayscale;
7167
exportToCMYK = !Options.UseRGB;
7169
if (extensionIndicatesJPEG(ext) && (cm != PDFOptions::Compression_None))
7171
if (((Options.UseRGB || Options.UseProfiles2) && (cm == PDFOptions::Compression_Auto) && (c->effectsInUse.count() == 0) && (img.imgInfo.colorspace == ColorSpaceRGB)) && (!img.imgInfo.progressive) && (!((Options.RecalcPic) && (Options.PicRes < (qMax(72.0 / c->imageXScale(), 72.0 / c->imageYScale()))))))
7173
jpegUseOriginal = true;
7174
cm = PDFOptions::Compression_JPEG;
7176
// We can't unfortunately use directly cmyk jpeg files. Otherwise we have to use the /Decode argument in image
7177
// dictionnary, which we do not quite want as this argument is simply ignored by some rips and software
7178
// amongst which photoshop and illustrator
7179
/*else if (((!Options.UseRGB) && (!Options.isGrayscale) && (!Options.UseProfiles2)) && (cm== 0) && (c->effectsInUse.count() == 0) && (img.imgInfo.colorspace == ColorSpaceCMYK) && (!((Options.RecalcPic) && (Options.PicRes < (qMax(72.0 / c->imageXScale(), 72.0 / c->imageYScale()))))) && (!img.imgInfo.progressive))
7181
jpegUseOriginal = false;
7182
exportToCMYK = true;
7183
cm = PDFOptions::Compression_JPEG;
7187
if (Options.CompressMethod == PDFOptions::Compression_JPEG)
7189
if (realCMYK || !((Options.UseRGB) || (Options.UseProfiles2)))
7191
exportToGrayscale = Options.isGrayscale;
7192
if (exportToGrayscale)
7193
exportToCMYK = !Options.isGrayscale;
7195
exportToCMYK = !Options.UseRGB;
7197
cm = PDFOptions::Compression_JPEG;
7200
cm = PDFOptions::Compression_ZIP;
7205
if ((Options.CompressMethod == PDFOptions::Compression_JPEG) || (Options.CompressMethod == PDFOptions::Compression_Auto))
7207
if (realCMYK || !((Options.UseRGB) || (Options.UseProfiles2)))
7209
exportToGrayscale = Options.isGrayscale;
7210
if (exportToGrayscale)
7211
exportToCMYK = !Options.isGrayscale;
7213
exportToCMYK = !Options.UseRGB;
7215
cm = PDFOptions::Compression_JPEG;
7216
/*if (Options.CompressMethod == PDFOptions::Compression_Auto)
7218
QFileInfo fi(tmpFile);
7219
if (fi.size() < im.size())
7222
if (!loadRawBytes(tmpFile, im))
7224
cm = PDFOptions::Compression_JPEG;
7227
cm = PDFOptions::Compression_ZIP;
7231
int bytesWritten = 0;
7232
PutDoc("/BitsPerComponent 8\n");
7233
uint lengthObj = newObject();
7234
PutDoc("/Length "+QString::number(lengthObj)+" 0 R\n");
7235
if (cm == PDFOptions::Compression_JPEG)
7236
PutDoc("/Filter /DCTDecode\n");
7237
else if (cm != PDFOptions::Compression_None)
7238
PutDoc("/Filter /FlateDecode\n");
7239
// if (exportToCMYK && (cm == PDFOptions::Compression_JPEG))
7240
// PutDoc("/Decode [1 0 1 0 1 0 1 0]\n");
7243
if (Options.Version >= PDFOptions::PDFVersion_14)
7244
PutDoc("/SMask "+QString::number(maskObj)+" 0 R\n");
7246
PutDoc("/Mask "+QString::number(maskObj)+" 0 R\n");
7248
PutDoc(">>\nstream\n");
7249
if ((hasGrayProfile) && (doc.HasCMS) && (Options.UseProfiles2) && (!hasColorEffect))
7250
exportToGrayscale = true;
7251
if (cm == PDFOptions::Compression_JPEG)
7252
bytesWritten = WriteJPEGImageToStream(img, fn, imageObj, exportToCMYK, exportToGrayscale, jpegUseOriginal, (!hasColorEffect && hasGrayProfile));
7253
else if (cm == PDFOptions::Compression_ZIP)
7254
bytesWritten = WriteFlateImageToStream(img, imageObj, exportToCMYK, exportToGrayscale, (!hasColorEffect && hasGrayProfile));
7256
bytesWritten = WriteImageToStream(img, imageObj, exportToCMYK, exportToGrayscale, (!hasColorEffect && hasGrayProfile));
7257
PutDoc("\nendstream\nendobj\n");
7258
if (bytesWritten <= 0)
7260
PDF_Error_ImageWriteFailure(fn);
7263
StartObj(lengthObj);
7264
PutDoc(QString(" %1\n").arg(bytesWritten));
7266
Seite.ImgObjects[ResNam+"I"+QString::number(ResCount)] = imageObj;
7267
ImInfo.ResNum = ResCount;
7268
ImInfo.Width = img.width();
7269
ImInfo.Height = img.height();
7272
ImInfo.RequestProps = c->pixm.imgInfo.RequestProps;
7273
} // not embedded PDF
7274
if ((c->effectsInUse.count() == 0) && (!SharedImages.contains(fn)))
7275
SharedImages.insert(fn, ImInfo);
7280
ImInfo = SharedImages[fn];
7281
ImInfo.sxa *= sx / ImInfo.xa;
7282
ImInfo.sya *= sy / ImInfo.ya;
7284
ImRes = SharedImages[fn].ResNum;
7285
ImWid = SharedImages[fn].Width;
7286
ImHei = SharedImages[fn].Height;
7287
aufl = SharedImages[fn].reso;
7288
sxn = SharedImages[fn].sxa * sx / SharedImages[fn].xa;
7289
syn = SharedImages[fn].sya * sy / SharedImages[fn].ya;
7292
QString embedPre = "";
7293
if ((bitmapFromGS) || (isEmbeddedPDF)) // compensate gsResolution setting
7297
// #9268 : per specs default color space is grayscale
7298
/*if (Options.isGrayscale)
7299
embedPre = "0 g 0 G";
7300
else if (Options.UseRGB)
7301
embedPre = "0 0 0 rg 0 0 0 RG";
7303
embedPre = "0 0 0 0 k 0 0 0 0 K";*/
7304
embedPre = "0 g 0 G";
7305
embedPre += " 1 w 0 J 0 j [] 0 d\n"; // add default graphics stack parameters pdftex relies on them
7307
if (c->asLatexFrame())
7309
ImInfo.sxa *= 1.0 / c->imageXScale();
7310
ImInfo.sya *= 1.0 / c->imageYScale();
7314
ImInfo.sxa *= PrefsManager::instance()->appPrefs.gs_Resolution / 72.0;
7315
ImInfo.sya *= PrefsManager::instance()->appPrefs.gs_Resolution / 72.0;
7318
if (!fromAN && output)
7319
*output = QString(embedPre + FToStr(ImInfo.Width*ImInfo.sxa)+" 0 0 "+FToStr(ImInfo.Height*ImInfo.sya)+" "+FToStr(x*sx)+" "+FToStr((-ImInfo.Height*ImInfo.sya+y*sy))+" cm\n/"+ResNam+"I"+QString::number(ImInfo.ResNum)+" Do\n");
7321
*output = QString("");
7325
bool PDFLibCore::PDF_End_Doc(const QString& PrintPr, const QString& Name, int Components)
7330
QTreeWidgetItem* pp;
7332
QMap<int,QString> Inha;
7333
if ((Bvie->topLevelItemCount() != 0) && (Options.Bookmarks) && (BookMinUse))
7335
int Basis = ObjCounter - 1;
7336
Outlines.Count = Bvie->topLevelItemCount();
7337
ip = (BookMItem*)Bvie->topLevelItem(0);
7338
pp = Bvie->topLevelItem(0);
7339
Outlines.First = ip->ItemNr+Basis;
7340
Outlines.Last = ((BookMItem*) Bvie->topLevelItem(Outlines.Count - 1))->ItemNr+Basis;
7341
QTreeWidgetItemIterator it(Bvie);
7344
ip = (BookMItem*)(*it);
7345
QString encText = ip->text(0);
7346
Inhal = QString::number(ip->ItemNr+Basis)+ " 0 obj\n";
7347
Inhal += "<<\n/Title "+EncStringUTF16("("+encText+")", ip->ItemNr+Basis)+"\n";
7349
Inhal += "/Parent 3 0 R\n";
7351
Inhal += "/Parent "+QString::number(ip->Pare+Basis)+" 0 R\n";
7353
Inhal += "/Prev "+QString::number(ip->Prev+Basis)+" 0 R\n";
7355
Inhal += "/Next "+QString::number(ip->Next+Basis)+" 0 R\n";
7357
Inhal += "/First "+QString::number(ip->First+Basis)+" 0 R\n";
7359
Inhal += "/Last "+QString::number(ip->Last+Basis)+" 0 R\n";
7360
if (ip->childCount())
7361
Inhal += "/Count -"+QString::number(ip->childCount())+"\n";
7362
if ((ip->PageObject->OwnPage != -1) && PageTree.Kids.contains(ip->PageObject->OwnPage))
7364
QString action = ip->Action;
7365
if (action.isEmpty())
7367
const Page* page = doc.DocPages.at(ip->PageObject->OwnPage);
7368
double actionPos = page->height() - (ip->PageObject->yPos() - page->yOffset());
7369
action = QString("/XYZ 0 %1 0").arg(actionPos);
7371
Inhal += "/Dest ["+QString::number(PageTree.Kids[ip->PageObject->OwnPage])+" 0 R "+action+"\n";
7373
Inhal += ">>\nendobj\n";
7374
Inha[ip->ItemNr] = Inhal;
7377
QMap<int,QString> ::ConstIterator contentIt;
7378
for (contentIt = Inha.begin(); contentIt != Inha.end(); ++contentIt)
7380
XRef.append(bytesWritten());
7381
PutDoc(contentIt.value());
7385
StartObj(ObjCounter);
7387
PutDoc("<< /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
7388
if ((Seite.ImgObjects.count() != 0) || (Seite.XObjects.count() != 0))
7390
PutDoc("/XObject <<\n");
7391
QMap<QString,int>::Iterator it;
7392
for (it = Seite.ImgObjects.begin(); it != Seite.ImgObjects.end(); ++it)
7393
PutDoc("/"+it.key()+" "+QString::number(it.value())+" 0 R\n");
7394
QMap<QString,int>::Iterator iti;
7395
for (iti = Seite.XObjects.begin(); iti != Seite.XObjects.end(); ++iti)
7396
PutDoc("/"+iti.key()+" "+QString::number(iti.value())+" 0 R\n");
7399
if (Seite.FObjects.count() != 0)
7401
PutDoc("/Font << \n");
7402
QMap<QString,int>::Iterator it2;
7403
for (it2 = Seite.FObjects.begin(); it2 != Seite.FObjects.end(); ++it2)
7404
PutDoc("/"+it2.key()+" "+QString::number(it2.value())+" 0 R\n");
7407
if (Shadings.count() != 0)
7409
PutDoc("/Shading << \n");
7410
QMap<QString,int>::Iterator it3;
7411
for (it3 = Shadings.begin(); it3 != Shadings.end(); ++it3)
7412
PutDoc("/"+it3.key()+" "+QString::number(it3.value())+" 0 R\n");
7415
if (Patterns.count() != 0)
7417
PutDoc("/Pattern << \n");
7418
QMap<QString,int>::Iterator it3p;
7419
for (it3p = Patterns.begin(); it3p != Patterns.end(); ++it3p)
7420
PutDoc("/"+it3p.key()+" "+QString::number(it3p.value())+" 0 R\n");
7423
if (Transpar.count() != 0)
7425
PutDoc("/ExtGState << \n");
7426
QMap<QString,int>::Iterator it3t;
7427
for (it3t = Transpar.begin(); it3t != Transpar.end(); ++it3t)
7428
PutDoc("/"+it3t.key()+" "+QString::number(it3t.value())+" 0 R\n");
7431
if ((ICCProfiles.count() != 0) || (spotMap.count() != 0) || (spotMapReg.count() != 0))
7433
PutDoc("/ColorSpace << \n");
7434
QMap<QString,ICCD>::Iterator it3c;
7435
if (ICCProfiles.count() != 0)
7437
for (it3c = ICCProfiles.begin(); it3c != ICCProfiles.end(); ++it3c)
7438
PutDoc("/"+it3c.value().ResName+" "+QString::number(it3c.value().ResNum)+" 0 R\n");
7440
QMap<QString,SpotC>::Iterator it3sc;
7441
if (spotMap.count() != 0)
7443
for (it3sc = spotMap.begin(); it3sc != spotMap.end(); ++it3sc)
7444
PutDoc("/"+it3sc.value().ResName+" "+QString::number(it3sc.value().ResNum)+" 0 R\n");
7446
QMap<QString,SpotC>::Iterator it3scr;
7447
if (spotMapReg.count() != 0)
7449
for (it3scr = spotMapReg.begin(); it3scr != spotMapReg.end(); ++it3scr)
7450
PutDoc("/"+it3scr.value().ResName+" "+QString::number(it3scr.value().ResNum)+" 0 R\n");
7454
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
7456
PutDoc("/Properties <<\n");
7458
ll.isPrintable = false;
7461
for (int la = 0; la < doc.Layers.count(); ++la)
7463
doc.Layers.levelToLayer(ll, la);
7464
PutDoc("/"+OCGEntries[ll.Name].Name+" "+QString::number(OCGEntries[ll.Name].ObjNum)+" 0 R\n");
7469
PutDoc(">>\nendobj\n");
7471
XRef[2] = bytesWritten();
7472
PutDoc("3 0 obj\n<<\n/Type /Outlines\n");
7473
PutDoc("/Count "+QString::number(Outlines.Count)+"\n");
7474
// if ((Bvie->childCount() != 0) && (Options.Bookmarks))
7475
if ((Bvie->topLevelItemCount() != 0) && (Options.Bookmarks))
7477
PutDoc("/First "+QString::number(Outlines.First)+" 0 R\n");
7478
PutDoc("/Last "+QString::number(Outlines.Last)+" 0 R\n");
7480
PutDoc(">>\nendobj\n");
7481
XRef[3] = bytesWritten();
7482
PutDoc("4 0 obj\n<<\n/Type /Pages\n/Kids [");
7483
QMap<int, int>::Iterator kidsIt;
7484
for (kidsIt = PageTree.Kids.begin(); kidsIt != PageTree.Kids.end(); ++kidsIt)
7485
PutDoc(QString::number(kidsIt.value())+" 0 R ");
7487
PutDoc("/Count "+QString::number(PageTree.Count)+"\n");
7488
PutDoc("/Resources "+QString::number(ObjCounter-1)+" 0 R\n");
7489
PutDoc(">>\nendobj\n");
7490
XRef[4] = bytesWritten();
7491
PutDoc("5 0 obj\n<<\n");
7492
if (NamedDest.count() != 0)
7494
QList<Dest>::Iterator vt;
7495
for (vt = NamedDest.begin(); vt != NamedDest.end(); ++vt)
7497
if (PageTree.Kids.contains((*vt).Seite))
7498
PutDoc("/"+(*vt).Name+" ["+QString::number(PageTree.Kids[(*vt).Seite])+" 0 R /XYZ "+(*vt).Act+"]\n");
7501
PutDoc(">>\nendobj\n");
7502
XRef[5] = bytesWritten();
7503
PutDoc("6 0 obj\n<<\n");
7504
PutDoc("/Fields [ ");
7505
if (Seite.FormObjects.count() != 0)
7507
for (int fo = 0; fo < Seite.FormObjects.count(); ++fo)
7508
PutDoc(QString::number(Seite.FormObjects[fo])+" 0 R ");
7511
if (CalcFields.count() != 0)
7514
for (int foc = 0; foc < CalcFields.count(); ++foc)
7515
PutDoc(QString::number(CalcFields[foc])+" 0 R ");
7518
if ((Seite.FormObjects.count() != 0) || (CalcFields.count() != 0))
7519
PutDoc("/NeedAppearances true\n/DR "+QString::number(ResO)+" 0 R\n");
7520
PutDoc(">>\nendobj\n");
7521
if (doc.JavaScripts.count() != 0)
7523
int Fjav0 = ObjCounter;
7524
QMap<QString,QString>::Iterator itja0;
7525
for (itja0 = doc.JavaScripts.begin(); itja0 != doc.JavaScripts.end(); ++itja0)
7526
WritePDFString(itja0.value());
7527
int Fjav = ObjCounter;
7528
QMap<QString,QString>::Iterator itja;
7529
for (itja = doc.JavaScripts.begin(); itja != doc.JavaScripts.end(); ++itja)
7531
StartObj(ObjCounter);
7533
PutDoc("<< /S /JavaScript /JS "+QString::number(Fjav0)+" 0 R >>\n");
7537
StartObj(ObjCounter);
7539
PutDoc("<< /Names [ ");
7540
QMap<QString,QString>::Iterator itja2;
7541
for (itja2 = doc.JavaScripts.begin(); itja2 != doc.JavaScripts.end(); ++itja2)
7543
PutDoc(EncString("("+itja2.key()+")", 6)+" "+QString::number(Fjav)+" 0 R ");
7546
PutDoc("] >>\nendobj\n");
7548
XRef[6] = bytesWritten();
7549
PutDoc("7 0 obj\n<< ");
7550
if (doc.JavaScripts.count() != 0)
7551
PutDoc("/JavaScript "+QString::number(ObjCounter-1)+" 0 R");
7552
PutDoc(" >>\nendobj\n");
7554
if (Options.Articles)
7556
for (int ele = 0; ele < doc.DocItems.count(); ++ele)
7558
PageItem* tel = doc.DocItems.at(ele);
7559
if ((tel->asTextFrame()) && (tel->prevInChain() == 0) && (tel->nextInChain() != 0) &&
7560
(!tel->inPdfArticle))
7564
int fir = ObjCounter + 1;
7565
int ccb = ObjCounter + 1;
7566
bd.Parent = ObjCounter;
7567
while (tel->nextInChain() != 0)
7569
if ((tel->OwnPage != -1) && PageTree.Kids.contains(tel->OwnPage))
7574
bd.Page = PageTree.Kids[tel->OwnPage];
7575
bd.Recht = QRect(static_cast<int>(tel->xPos() - doc.DocPages.at(tel->OwnPage)->xOffset()),
7576
static_cast<int>(doc.DocPages.at(tel->OwnPage)->height() - (tel->yPos() - doc.DocPages.at(tel->OwnPage)->yOffset())),
7577
static_cast<int>(tel->width()),
7578
static_cast<int>(tel->height()));
7581
tel->inPdfArticle = true;
7582
tel = tel->nextInChain();
7586
if ((tel->OwnPage != -1) && PageTree.Kids.contains(tel->OwnPage))
7588
bd.Page = PageTree.Kids[tel->OwnPage];
7589
bd.Recht = QRect(static_cast<int>(tel->xPos() - doc.DocPages.at(tel->OwnPage)->xOffset()),
7590
static_cast<int>(doc.DocPages.at(tel->OwnPage)->height() - (tel->yPos() - doc.DocPages.at(tel->OwnPage)->yOffset())),
7591
static_cast<int>(tel->width()),
7592
static_cast<int>(tel->height()));
7595
tel->inPdfArticle = true;
7596
if (Beads.count() > 0)
7598
int threadObj = newObject();
7599
StartObj(threadObj);
7600
Threads.append(threadObj);
7601
PutDoc("<< /Type /Thread\n");
7602
PutDoc(" /F "+QString::number(threadObj + 1)+" 0 R\n");
7603
PutDoc(">>\nendobj\n");
7604
Beads[0].Prev = fir + Beads.count()-1;
7605
Beads[Beads.count()-1].Next = fir;
7607
for (int beac = 0; beac < Beads.count(); ++beac)
7609
StartObj(ObjCounter);
7611
PutDoc("<< /Type /Bead\n");
7612
PutDoc(" /T "+QString::number(Beads[beac].Parent)+" 0 R\n");
7613
PutDoc(" /N "+QString::number(Beads[beac].Next)+" 0 R\n");
7614
PutDoc(" /V "+QString::number(Beads[beac].Prev)+" 0 R\n");
7615
PutDoc(" /P "+QString::number(Beads[beac].Page)+" 0 R\n");
7616
PutDoc(" /R [ "+QString::number(Beads[beac].Recht.x())+" "+
7617
QString::number(Beads[beac].Recht.y())+" ");
7618
PutDoc(QString::number(Beads[beac].Recht.bottomRight().x())+" "+QString::number(Beads[beac].Recht.y()-Beads[beac].Recht.height())+" ]\n");
7619
PutDoc(">>\nendobj\n");
7623
for (int ele = 0; ele < doc.DocItems.count(); ++ele)
7624
doc.DocItems.at(ele)->inPdfArticle = false;
7626
XRef[7] = bytesWritten();
7627
PutDoc("8 0 obj\n[");
7628
for (int th = 0; th < Threads.count(); ++th)
7629
PutDoc(QString::number(Threads[th])+" 0 R ");
7630
PutDoc("]\nendobj\n");
7631
if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
7633
XRef[8] = bytesWritten();
7635
PutDoc("9 0 obj\n<<\n");
7636
PutDoc("/D << /Order [ ");
7638
ll.isPrintable = false;
7641
for (int la = 0; la < doc.Layers.count(); ++la)
7643
doc.Layers.levelToLayer(ll, la);
7645
lay.prepend(QString::number(OCGEntries[ll.Name].ObjNum)+" 0 R ");
7648
for (int layc = 0; layc < lay.count(); ++layc)
7654
QHash<QString, OCGInfo>::Iterator itoc;
7655
for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
7657
if (!itoc.value().visible)
7658
PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
7661
PutDoc("/AS [<</Event /Print /OCGs [ ");
7662
for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
7664
PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
7666
PutDoc("] /Category [/Print]>> <</Event /View /OCGs [");
7667
for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
7669
PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
7671
PutDoc("] /Category [/View]>>]\n");
7674
for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
7676
PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
7679
PutDoc(">>\nendobj\n");
7681
if (Options.Version == PDFOptions::PDFVersion_X3)
7683
StartObj(ObjCounter);
7686
loadRawBytes(PrintPr, dataP);
7688
if (Options.Compress)
7690
QByteArray compData = CompressArray(dataP);
7691
if (compData.size() > 0)
7693
PutDoc("/Filter /FlateDecode\n");
7697
PutDoc("/Length "+QString::number(dataP.size()+1)+"\n");
7698
PutDoc("/N "+QString::number(Components)+"\n");
7699
PutDoc(">>\nstream\n");
7701
PutDoc("\nendstream\nendobj\n");
7702
XRef[8] = bytesWritten();
7703
PutDoc("9 0 obj\n");
7704
PutDoc("<<\n/Type /OutputIntent\n/S /GTS_PDFX\n");
7705
PutDoc("/DestOutputProfile "+QString::number(ObjCounter-1)+" 0 R\n");
7706
PutDoc("/OutputConditionIdentifier (Custom)\n");
7707
PutDoc("/Info ("+PDFEncode(Options.Info)+")\n");
7708
PutDoc("/OutputCondition ("+PDFEncode(Name)+")\n");
7709
PutDoc(">>\nendobj\n");
7711
uint StX = bytesWritten();
7713
PutDoc("0 "+QString::number(ObjCounter)+"\n");
7714
PutDoc("0000000000 65535 f \n");
7715
for (int a = 0; a < XRef.count(); ++a)
7719
tmp.sprintf("%10d", XRef[a]);
7720
tmp.replace(QRegExp(" "), "0");
7721
PutDoc(tmp+" 00000 n \n");
7725
// unused object, mark as free-never-to-be-used-again
7726
PutDoc("0000000000 65535 f \n");
7729
PutDoc("trailer\n<<\n/Size "+QString::number(XRef.count()+1)+"\n");
7731
for (uint cl = 0; cl < 16; ++cl)
7732
IDs += QChar(FileID[cl]);
7733
IDs = String2Hex(&IDs);
7734
PutDoc("/Root 1 0 R\n/Info 2 0 R\n/ID [<"+IDs+"><"+IDs+">]\n");
7735
if (Options.Encrypt)
7736
PutDoc("/Encrypt "+QString::number(Encrypt)+" 0 R\n");
7737
PutDoc(">>\nstartxref\n");
7738
PutDoc(QString::number(StX)+"\n%%EOF\n");
7739
return closeAndCleanup();
7742
void PDFLibCore::PDF_Error(const QString& errorMsg)
7744
ErrorMessage = errorMsg;
7745
if (!ScCore->usingGUI())
7746
qDebug("%s", errorMsg.toLocal8Bit().data());
7749
void PDFLibCore::PDF_Error_WriteFailure(void)
7751
PDF_Error( tr("A write error occurred, please check available disk space") );
7754
void PDFLibCore::PDF_Error_ImageLoadFailure(const QString& fileName)
7756
PDF_Error( tr("Failed to load an image : %1").arg(fileName) );
7759
void PDFLibCore::PDF_Error_ImageWriteFailure(const QString& fileName)
7761
PDF_Error( tr("Failed to write an image : %1").arg(fileName) );
7764
void PDFLibCore::PDF_Error_MaskLoadFailure(const QString& fileName)
7766
PDF_Error( tr("Failed to load an image mask : %1").arg(fileName) );
7769
void PDFLibCore::PDF_Error_InsufficientMemory(void)
7771
PDF_Error( tr("Insufficient memory for processing an image"));
7774
bool PDFLibCore::closeAndCleanup()
7776
bool writeSucceed = (Spool.error() == QFile::NoError);
7778
PDF_Error_WriteFailure();
7780
if (abortExport || !writeSucceed)
7785
Seite.XObjects.clear();
7786
Seite.ImgObjects.clear();
7787
Seite.FObjects.clear();
7788
Seite.AObjects.clear();
7789
Seite.FormObjects.clear();
7793
ICCProfiles.clear();
7794
return writeSucceed;
7797
void PDFLibCore::cancelRequested()