~ubuntu-branches/ubuntu/wily/scribus/wily-proposed

« back to all changes in this revision

Viewing changes to .pc/0001-qreal-double-fixes.patch/scribus/pdflib_core.cpp

  • Committer: Package Import Robot
  • Author(s): Oleksandr Moskalenko
  • Date: 2012-02-09 21:50:56 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120209215056-2wrx1ara0jbm7fi5
Tags: 1.4.0.dfsg+r17287-1
* New upstream stable release upload into Debian (Closes: #654703).
* Applied the Ubuntu armel patch.
* Removed non-free color swatches from resources.
* debian/control:
  - Moved icc-profiles from Recommends to Suggests (Closes: #655885).
  - Updated Standards-Version to 3.9.2.
  - Updated extended description per lintian warning.
* debian/rules:
  - Update mailcap (Closes: #630751). A request for mime.types update has
    been sent to the mime-support maintainer.
  - Added build-arch and build-indep targets per lintian warning.
* debian/patches:
  - top_cmakelists.patch - don't copy extra docs and changelogs.
  - scribus_cmakelists.patch - don't copy extra docs and changelogs.
  - scribus_cmakelists.patch - don't install the non-free "doc" dir.
  - profiles_cmakelists.patch - don't install non-free sRGB profile.
* debian/copyright: 
  - Converted to the DEP5 machine readable foramt.
  - Added licenses for free color swatches.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
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.
6
 
*/
7
 
/***************************************************************************
8
 
                          pdflib_core.cpp  -  description
9
 
                             -------------------
10
 
    begin                : Sat Jan 19 2002
11
 
    copyright            : (C) 2002 by Franz Schmid
12
 
    email                : Franz.Schmid@altmuehlnet.de
13
 
 ***************************************************************************/
14
 
 
15
 
/***************************************************************************
16
 
 *                                                                         *
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.                                   *
21
 
 *                                                                         *
22
 
 ***************************************************************************/
23
 
 
24
 
#if defined(_MSC_VER)
25
 
#define _USE_MATH_DEFINES
26
 
#endif
27
 
 
28
 
#include "pdflib_core.h"
29
 
 
30
 
#include "scconfig.h"
31
 
 
32
 
#include <cmath>
33
 
#include <cstdlib>
34
 
#include <string>
35
 
#ifdef HAVE_UNISTD_H
36
 
#include <unistd.h>
37
 
#endif
38
 
 
39
 
#include "rc4.h"
40
 
 
41
 
#include <QByteArray>
42
 
#include <QDateTime>
43
 
#include <QDataStream>
44
 
#include <QDebug>
45
 
#include <QDir>
46
 
#include <QFileInfo>
47
 
#include <QImage>
48
 
#include <QList>
49
 
#include <QPainterPath>
50
 
#include <QPixmap>
51
 
#include <QRect>
52
 
#include <QRegExp>
53
 
#include <QStack>
54
 
#include <QString>
55
 
#include <QTextCodec>
56
 
 
57
 
 
58
 
#include "bookmwin.h"
59
 
#include "bookmarkpalette.h"
60
 
#include "cmsettings.h"
61
 
#include "commonstrings.h"
62
 
#include "multiprogressdialog.h"
63
 
#include "page.h"
64
 
#include "pageitem.h"
65
 
#include "pageitem_textframe.h"
66
 
#include "pdfoptions.h"
67
 
#include "prefscontext.h"
68
 
#include "prefsmanager.h"
69
 
#include "sccolor.h"
70
 
#include "sccolorengine.h"
71
 
#include "scfonts.h"
72
 
#include "scpaths.h"
73
 
#include "scpattern.h"
74
 
#include "scribus.h"
75
 
#include "scribuscore.h"
76
 
#include "scribusdoc.h"
77
 
#include "scstreamfilter_flate.h"
78
 
#include "scstreamfilter_rc4.h"
79
 
#include "text/nlsconfig.h"
80
 
#include "util.h"
81
 
#include "util_file.h"
82
 
#include "util_formats.h"
83
 
#include "util_math.h"
84
 
#include "util_ghostscript.h"
85
 
 
86
 
using namespace std;
87
 
 
88
 
#if defined(_WIN32)
89
 
#undef GetObject
90
 
#endif
91
 
 
92
 
 
93
 
PDFLibCore::PDFLibCore(ScribusDoc & docu)
94
 
        : QObject(&docu),
95
 
        doc(docu),
96
 
        ActPageP(0),
97
 
        Options(doc.PDF_Options),
98
 
        Bvie(0),
99
 
        ucs2Codec(0),
100
 
        ObjCounter(7),
101
 
        ResNam("RE"),
102
 
        ResCount(0),
103
 
        NDnam("LI"),
104
 
        NDnum(0),
105
 
        KeyGen(""),
106
 
        OwnerKey(""),
107
 
        UserKey(""),
108
 
        FileID(""),
109
 
        EncryKey(""),
110
 
        Encrypt(0),
111
 
        KeyLen(5),
112
 
        colorsToUse(),
113
 
        spotNam("Spot"),
114
 
        spotCount(0),
115
 
        progressDialog(0),
116
 
        abortExport(false),
117
 
        usingGUI(ScCore->usingGUI())
118
 
{
119
 
        KeyGen.resize(32);
120
 
        OwnerKey.resize(32);
121
 
        UserKey.resize(32);
122
 
        FileID.resize(16);
123
 
        EncryKey.resize(5);
124
 
        Catalog.Outlines = 2;
125
 
        Catalog.PageTree = 3;
126
 
        Catalog.Dest = 4;
127
 
        PageTree.Count = 0;
128
 
        Outlines.First = 0;
129
 
        Outlines.Last = 0;
130
 
        Outlines.Count = 0;
131
 
        Seite.ObjNum = 0;
132
 
        Seite.Thumb = 0;
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];
138
 
        if (usingGUI)
139
 
        {
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()));
149
 
        }
150
 
}
151
 
 
152
 
PDFLibCore::~PDFLibCore()
153
 
{
154
 
        delete progressDialog;
155
 
}
156
 
 
157
 
static inline QString FToStr(double c)
158
 
{
159
 
        return QString::number(c, 'f', 5);
160
 
};
161
 
 
162
 
bool PDFLibCore::doExport(const QString& fn, const QString& nam, int Components,
163
 
                                          const std::vector<int> & pageNs, const QMap<int,QPixmap> & thumbs)
164
 
{
165
 
        QPixmap pm;
166
 
        bool ret = false, error = false;
167
 
        int  pc_exportpages=0;
168
 
        int  pc_exportmasterpages=0;
169
 
        if (usingGUI)
170
 
                progressDialog->show();
171
 
        QMap<QString, QMap<uint, FPointArray> > usedFonts;
172
 
        usedFonts.clear();
173
 
        doc.getUsedFonts(usedFonts);
174
 
        ucs2Codec = QTextCodec::codecForName("UTF-16");
175
 
        if (!ucs2Codec)
176
 
        {
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";
179
 
                return false;
180
 
        }
181
 
        if (PDF_Begin_Doc(fn, PrefsManager::instance()->appPrefs.AvailFonts, usedFonts, doc.scMW()->bookmarkPalette->BView))
182
 
        {
183
 
                QMap<int, int> pageNsMpa;
184
 
                for (uint a = 0; a < pageNs.size(); ++a)
185
 
                {
186
 
                        pageNsMpa.insert(doc.MasterNames[doc.DocPages.at(pageNs[a]-1)->MPageNam], 0);
187
 
                }
188
 
                if (usingGUI)
189
 
                {
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);
196
 
                }
197
 
                for (int ap = 0; ap < doc.MasterPages.count() && !abortExport; ++ap)
198
 
                {
199
 
                        if (doc.MasterItems.count() != 0)
200
 
                        {
201
 
                                if (pageNsMpa.contains(ap))
202
 
                                {
203
 
                                        qApp->processEvents();
204
 
                                        if (!PDF_TemplatePage(doc.MasterPages.at(ap)))
205
 
                                                error = abortExport = true;
206
 
                                        ++pc_exportmasterpages;
207
 
                                }
208
 
                        }
209
 
                        if (usingGUI)
210
 
                        {
211
 
                                progressDialog->setProgress("EMP", pc_exportmasterpages);
212
 
                                progressDialog->setOverallProgress(pc_exportmasterpages+pc_exportpages);
213
 
                        }
214
 
                }
215
 
                for (uint a = 0; a < pageNs.size() && !abortExport; ++a)
216
 
                {
217
 
                        if (doc.PDF_Options.Thumbnails)
218
 
                                pm = thumbs[pageNs[a]];
219
 
                        qApp->processEvents();
220
 
                        if (abortExport) break;
221
 
 
222
 
                        PDF_Begin_Page(doc.DocPages.at(pageNs[a]-1), pm);
223
 
                        qApp->processEvents();
224
 
                        if (abortExport) break;
225
 
 
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;
230
 
 
231
 
                        PDF_End_Page(a);
232
 
                        pc_exportpages++;
233
 
                        if (usingGUI)
234
 
                        {
235
 
                                progressDialog->setProgress("EP", pc_exportpages);
236
 
                                progressDialog->setOverallProgress(pc_exportmasterpages+pc_exportpages);
237
 
                        }
238
 
                }
239
 
                ret = true;//Even when aborting we return true. Dont want that "couldnt write msg"
240
 
                if (!abortExport)
241
 
                {
242
 
                        if (doc.PDF_Options.Version == PDFOptions::PDFVersion_X3)
243
 
                                ret = PDF_End_Doc(ScCore->PrinterProfiles[doc.PDF_Options.PrintProf], nam, Components);
244
 
                        else
245
 
                                ret = PDF_End_Doc();
246
 
                }
247
 
                else
248
 
                        closeAndCleanup();
249
 
        }
250
 
        if (usingGUI)
251
 
                progressDialog->close();
252
 
        return (ret && !error);
253
 
}
254
 
 
255
 
const QString& PDFLibCore::errorMessage(void) const
256
 
{
257
 
        return ErrorMessage;
258
 
}
259
 
 
260
 
bool PDFLibCore::exportAborted(void) const
261
 
{
262
 
        return abortExport;
263
 
}
264
 
 
265
 
void PDFLibCore::StartObj(int nr)
266
 
{
267
 
        for (int i=XRef.size(); i < nr; ++i)
268
 
                XRef.append(0);
269
 
        XRef[nr-1] = bytesWritten();
270
 
        PutDoc(QString::number(nr)+ " 0 obj\n");
271
 
}
272
 
 
273
 
// Encode a string for inclusion in a
274
 
// PDF (literal) .
275
 
static QString PDFEncode(const QString & in)
276
 
{
277
 
        QString tmp("");
278
 
        for (int d = 0; d < in.length(); ++d)
279
 
        {
280
 
                QChar cc(in.at(d));
281
 
                if ((cc == '(') || (cc == ')') || (cc == '\\'))
282
 
                        tmp += '\\';
283
 
                tmp += cc;
284
 
        }
285
 
        return tmp;
286
 
}
287
 
 
288
 
static QString blendMode(int code)
289
 
{
290
 
        switch (code)
291
 
        {
292
 
                case 0:
293
 
                        return("Normal");
294
 
                        break;
295
 
                case 1:
296
 
                        return("Darken");
297
 
                        break;
298
 
                case 2:
299
 
                        return("Lighten");
300
 
                        break;
301
 
                case 3:
302
 
                        return("Multiply");
303
 
                        break;
304
 
                case 4:
305
 
                        return("Screen");
306
 
                        break;
307
 
                case 5:
308
 
                        return("Overlay");
309
 
                        break;
310
 
                case 6:
311
 
                        return("HardLight");
312
 
                        break;
313
 
                case 7:
314
 
                        return("SoftLight");
315
 
                        break;
316
 
                case 8:
317
 
                        return("Difference");
318
 
                        break;
319
 
                case 9:
320
 
                        return("Exclusion");
321
 
                        break;
322
 
                case 10:
323
 
                        return("ColorDodge");
324
 
                        break;
325
 
                case 11:
326
 
                        return("ColorBurn");
327
 
                        break;
328
 
                case 12:
329
 
                        return("Hue");
330
 
                        break;
331
 
                case 13:
332
 
                        return("Saturation");
333
 
                        break;
334
 
                case 14:
335
 
                        return("Color");
336
 
                        break;
337
 
                case 15:
338
 
                        return("Luminosity");
339
 
                        break;
340
 
                default:
341
 
                        return "";
342
 
        }
343
 
}       
344
 
 
345
 
QByteArray PDFLibCore::EncodeUTF16(const QString &in)
346
 
{
347
 
//      QString tmp("");
348
 
//      for (int d = 0; d < in.length(); ++d)
349
 
//      {
350
 
//              QChar cc(in.at(d));
351
 
//              if ((cc == '(') || (cc == ')') || (cc == '\\'))
352
 
//                      tmp += '\\';
353
 
//              tmp += cc;
354
 
//      }
355
 
        QString tmp = in;
356
 
        QByteArray cres = ucs2Codec->fromUnicode( tmp );
357
 
#ifndef WORDS_BIGENDIAN
358
 
        // on little endian systems we ned to swap bytes:
359
 
        uchar sw;
360
 
        for(int d = 0; d < cres.size()-1; d += 2)
361
 
        {
362
 
                sw = cres[d];
363
 
                cres[d] = cres[d+1];
364
 
                cres[d+1] = sw;
365
 
        }
366
 
#endif
367
 
        return cres;
368
 
}
369
 
 
370
 
QString PDFLibCore::EncStream(const QString & in, int ObjNum)
371
 
{
372
 
        if (in.length() < 1)
373
 
                return QString("");
374
 
        else if (!Options.Encrypt)
375
 
                return in;
376
 
        rc4_context_t rc4;
377
 
        QString tmp(in);
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());
385
 
        QString uk = "";
386
 
        for (int cl = 0; cl < tmp.length(); ++cl)
387
 
                uk += QChar(ou[cl]);
388
 
        return uk;
389
 
}
390
 
 
391
 
QString PDFLibCore::EncString(const QString & in, int ObjNum)
392
 
{
393
 
        if (!Options.Encrypt)
394
 
                return in;
395
 
        rc4_context_t rc4;
396
 
        QString tmp;
397
 
        if (in.length() < 3)
398
 
                return "<>";
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());
407
 
        QString uk = "";
408
 
        for (int cl = 0; cl < tmp.length(); ++cl)
409
 
                uk += QChar(ou[cl]);
410
 
        tmp = "<"+String2Hex(&uk, false)+">";
411
 
        return tmp;
412
 
}
413
 
 
414
 
QString PDFLibCore::EncStringUTF16(const QString & in, int ObjNum)
415
 
{
416
 
        if (in.length() < 3)
417
 
                return "<>";
418
 
        if (!Options.Encrypt)
419
 
        {
420
 
                QString tmp = in.mid(1, in.length()-2);
421
 
                QByteArray us = EncodeUTF16(tmp);
422
 
                QString uk = "";
423
 
                for (int cl = 0; cl < us.size(); ++cl)
424
 
                        uk += QChar(us[cl]);
425
 
                return "<"+String2Hex(&uk, false)+">";
426
 
        }
427
 
        rc4_context_t rc4;
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());
434
 
        QString uk = "";
435
 
        for (int cl = 0; cl < ou.size(); ++cl)
436
 
                uk += QChar(ou[cl]);
437
 
        tmp = "<"+String2Hex(&uk, false)+">";
438
 
        return tmp;
439
 
}
440
 
 
441
 
bool PDFLibCore::EncodeArrayToStream(const QByteArray& in, int ObjNum)
442
 
{
443
 
        if (in.size() < 1)
444
 
                return true;
445
 
        bool succeed = false;
446
 
        if (Options.Encrypt)
447
 
        {
448
 
                QByteArray step1 = ComputeRC4Key(ObjNum);
449
 
                ScRC4EncodeFilter rc4Encode(&outStream, step1.data(), qMin(KeyLen+5, 16));
450
 
                if (rc4Encode.openFilter())
451
 
                {
452
 
                        succeed  = rc4Encode.writeData(in.data(), in.size());
453
 
                        succeed &= rc4Encode.closeFilter();
454
 
                }
455
 
        }
456
 
        else
457
 
                outStream.writeRawData(in, in.size());
458
 
        return (outStream.status() == QDataStream::Ok);
459
 
}
460
 
 
461
 
int PDFLibCore::WriteImageToStream(ScImage& image, int ObjNum, bool cmyk, bool gray, bool precal)
462
 
{
463
 
        bool succeed = false;
464
 
        int  bytesWritten = 0;
465
 
        if (Options.Encrypt)
466
 
        {
467
 
                QByteArray step1 = ComputeRC4Key(ObjNum);
468
 
                ScRC4EncodeFilter rc4Encode(&outStream, step1.data(), qMin(KeyLen+5, 16));
469
 
                if (rc4Encode.openFilter())
470
 
                {
471
 
                        if (gray)
472
 
                                succeed = image.writeGrayDataToFilter(&rc4Encode, precal);
473
 
                        else if (cmyk)
474
 
                                succeed = image.writeCMYKDataToFilter(&rc4Encode);
475
 
                        else
476
 
                                succeed = image.writeRGBDataToFilter(&rc4Encode);
477
 
                        succeed &= rc4Encode.closeFilter();
478
 
                        bytesWritten = rc4Encode.writtenToStream();
479
 
                }
480
 
        }
481
 
        else
482
 
        {
483
 
                ScNullEncodeFilter nullEncode(&outStream);
484
 
                if (nullEncode.openFilter())
485
 
                {
486
 
                        if (gray)
487
 
                                succeed = image.writeGrayDataToFilter(&nullEncode, precal);
488
 
                        else if (cmyk)
489
 
                                succeed = image.writeCMYKDataToFilter(&nullEncode);
490
 
                        else
491
 
                                succeed = image.writeRGBDataToFilter(&nullEncode);
492
 
                        succeed &= nullEncode.closeFilter();
493
 
                        bytesWritten = nullEncode.writtenToStream();
494
 
                }
495
 
        }
496
 
        return (succeed ? bytesWritten : 0);
497
 
}
498
 
 
499
 
int PDFLibCore::WriteJPEGImageToStream(ScImage& image, const QString& fn, int ObjNum, bool cmyk, 
500
 
                                                                                bool gray, bool sameFile, bool precal)
501
 
{
502
 
        bool succeed = true;
503
 
        int  bytesWritten = 0;
504
 
        QFileInfo fInfo(fn);
505
 
        QString   ext = fInfo.suffix().toLower();
506
 
        QString   jpgFileName, tmpFile;
507
 
        if (extensionIndicatesJPEG(ext) && sameFile)
508
 
                jpgFileName = fn;
509
 
        else
510
 
        {
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;
516
 
        }
517
 
        if (jpgFileName.isEmpty())
518
 
                return 0;
519
 
        if (Options.Encrypt)
520
 
        {
521
 
                succeed = false;
522
 
                QByteArray step1 = ComputeRC4Key(ObjNum);
523
 
                ScRC4EncodeFilter rc4Encode(&outStream, step1.data(), qMin(KeyLen+5, 16));
524
 
                if (rc4Encode.openFilter())
525
 
                {
526
 
                        succeed  = copyFileToFilter(jpgFileName, rc4Encode);
527
 
                        succeed &= rc4Encode.closeFilter();
528
 
                        bytesWritten = rc4Encode.writtenToStream();
529
 
                }
530
 
        }
531
 
        else
532
 
        {
533
 
                succeed &= copyFileToStream(jpgFileName, outStream);
534
 
                QFileInfo jpgInfo(jpgFileName);
535
 
                bytesWritten = jpgInfo.size();
536
 
        }
537
 
        if (!tmpFile.isEmpty() && QFile::exists(tmpFile))
538
 
                QFile::remove(tmpFile);
539
 
        return (succeed ? bytesWritten : 0);
540
 
}
541
 
 
542
 
int PDFLibCore::WriteFlateImageToStream(ScImage& image, int ObjNum, bool cmyk, bool gray, bool precal)
543
 
{
544
 
        bool succeed = false;
545
 
        int  bytesWritten = 0;
546
 
        if (Options.Encrypt)
547
 
        {
548
 
                QByteArray step1 = ComputeRC4Key(ObjNum);
549
 
                ScRC4EncodeFilter   rc4Encode(&outStream, step1.data(), qMin(KeyLen+5, 16));
550
 
                ScFlateEncodeFilter flateEncode(&rc4Encode);
551
 
                if (flateEncode.openFilter())
552
 
                {
553
 
                        if (gray)
554
 
                                succeed = image.writeGrayDataToFilter(&flateEncode, precal);
555
 
                        else if (cmyk)
556
 
                                succeed = image.writeCMYKDataToFilter(&flateEncode);
557
 
                        else
558
 
                                succeed = image.writeRGBDataToFilter(&flateEncode);
559
 
                        succeed &= flateEncode.closeFilter();
560
 
                        bytesWritten = flateEncode.writtenToStream();
561
 
                }
562
 
        }
563
 
        else
564
 
        {
565
 
                ScFlateEncodeFilter flateEncode(&outStream);
566
 
                if (flateEncode.openFilter())
567
 
                {
568
 
                        if (gray)
569
 
                                succeed = image.writeGrayDataToFilter(&flateEncode, precal);
570
 
                        else if (cmyk)
571
 
                                succeed = image.writeCMYKDataToFilter(&flateEncode);
572
 
                        else
573
 
                                succeed = image.writeRGBDataToFilter(&flateEncode);
574
 
                        succeed &= flateEncode.closeFilter();
575
 
                        bytesWritten = flateEncode.writtenToStream();
576
 
                }
577
 
        }
578
 
        return (succeed ? bytesWritten : 0);
579
 
}
580
 
 
581
 
QString PDFLibCore::FitKey(const QString & pass)
582
 
{
583
 
        QString pw(pass);
584
 
        if (pw.length() < 32)
585
 
        {
586
 
                uint l = pw.length();
587
 
                for (uint a = 0; a < 32 - l; ++a)
588
 
                        pw += QChar(KeyGen[a]);
589
 
        }
590
 
        else
591
 
                pw = pw.left(32);
592
 
        return pw;
593
 
}
594
 
 
595
 
void PDFLibCore::CalcOwnerKey(const QString & Owner, const QString & User)
596
 
{
597
 
        rc4_context_t rc4;
598
 
        QString pw(FitKey(User));
599
 
        QString pw2(FitKey(Owner.isEmpty() ? User : Owner));
600
 
        QByteArray step1(16, ' ');
601
 
        step1 = ComputeMD5(pw2);
602
 
        if (KeyLen > 5)
603
 
        {
604
 
                for (int kl = 0; kl < 50; ++kl)
605
 
                        step1 = ComputeMD5Sum(&step1);
606
 
        }
607
 
        QByteArray us(32, ' ');
608
 
        QByteArray enk(16, ' ');
609
 
        if (KeyLen > 5)
610
 
        {
611
 
                for (uint a2 = 0; a2 < 32; ++a2)
612
 
                        OwnerKey[a2] = QChar(pw.at(a2)).cell();
613
 
                for (int rl = 0; rl < 20; rl++)
614
 
                {
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);
620
 
                }
621
 
        }
622
 
        else
623
 
        {
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);
629
 
        }
630
 
}
631
 
 
632
 
void PDFLibCore::CalcUserKey(const QString & User, int Permission)
633
 
{
634
 
        rc4_context_t   rc4;
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);
650
 
        if (KeyLen > 5)
651
 
        {
652
 
                for (int kl = 0; kl < 50; ++kl)
653
 
                        step1 = ComputeMD5Sum(&step1);
654
 
                EncryKey.resize(16);
655
 
        }
656
 
        for (int a2 = 0; a2 < KeyLen; ++a2)
657
 
                EncryKey[a2] = step1[a2];
658
 
        if (KeyLen > 5)
659
 
        {
660
 
                QString pr2("");
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++)
670
 
                {
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);
675
 
                }
676
 
        }
677
 
        else
678
 
        {
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);
681
 
        }
682
 
}
683
 
 
684
 
QByteArray PDFLibCore::ComputeMD5(const QString& in)
685
 
{
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);
691
 
}
692
 
 
693
 
QByteArray PDFLibCore::ComputeRC4Key(int ObjNum)
694
 
{
695
 
        int dlen = 0;
696
 
        QByteArray data(10, ' ');
697
 
        if (KeyLen > 5)
698
 
                data.resize(21);
699
 
        for (int cd = 0; cd < KeyLen; ++cd)
700
 
        {
701
 
                data[cd] = EncryKey[cd];
702
 
                dlen++;
703
 
        }
704
 
        data[dlen++] = ObjNum;
705
 
        data[dlen++] = ObjNum >> 8;
706
 
        data[dlen++] = ObjNum >> 16;
707
 
        data[dlen++] = 0;
708
 
        data[dlen++] = 0;
709
 
        QByteArray rc4Key(16, ' ');
710
 
        rc4Key = ComputeMD5Sum(&data);
711
 
        rc4Key.resize(qMin(KeyLen+5, 16));
712
 
        return rc4Key;
713
 
}
714
 
 
715
 
bool PDFLibCore::PDF_Begin_Doc(const QString& fn, SCFonts &AllFonts, QMap<QString, QMap<uint, FPointArray> > DocFonts, BookMView* vi)
716
 
{
717
 
        Spool.setFileName(fn);
718
 
        if (!Spool.open(QIODevice::WriteOnly))
719
 
                return false;
720
 
        outStream.setDevice(&Spool);
721
 
        QString tmp;
722
 
        QString ok = "";
723
 
        QString uk = "";
724
 
        QFileInfo fd;
725
 
        QString fext;
726
 
        int a;
727
 
        inPattern = 0;
728
 
        Bvie = vi;
729
 
        BookMinUse = false;
730
 
        UsedFontsP.clear();
731
 
        UsedFontsF.clear();
732
 
        if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
733
 
                ObjCounter = 10;
734
 
        else
735
 
                ObjCounter = 9;
736
 
        switch (Options.Version)
737
 
        {
738
 
                case PDFOptions::PDFVersion_X3:
739
 
                case PDFOptions::PDFVersion_13:
740
 
                        PutDoc("%PDF-1.3\n");
741
 
                        break;
742
 
                case PDFOptions::PDFVersion_14:
743
 
                        PutDoc("%PDF-1.4\n");
744
 
                        break;
745
 
                case PDFOptions::PDFVersion_15:
746
 
                        PutDoc("%PDF-1.5\n");
747
 
                        break;
748
 
        }
749
 
        if (Options.Version == PDFOptions::PDFVersion_X3)
750
 
                ObjCounter++;
751
 
        PutDoc("%\xc7\xec\x8f\xa2\n");
752
 
        StartObj(1);
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)
760
 
        {
761
 
                case PDFOptions::SinglePage:
762
 
                        PutDoc("/SinglePage\n");
763
 
                        break;
764
 
                case PDFOptions::OneColumn:
765
 
                        PutDoc("/OneColumn\n");
766
 
                        break;
767
 
                case PDFOptions::TwoColumnLeft:
768
 
                        PutDoc("/TwoColumnLeft\n");
769
 
                        break;
770
 
                case PDFOptions::TwoColumnRight:
771
 
                        PutDoc("/TwoColumnRight\n");
772
 
                        break;
773
 
        }
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())
783
 
        {
784
 
                PutDoc("/OpenAction << /S /JavaScript /JS (this."+Options.openAction+"\\(\\)) >>\n");
785
 
        }
786
 
 
787
 
        QDate d = QDate::currentDate();
788
 
        Datum = "D:";
789
 
        tmp.sprintf("%4d", d.year());
790
 
        tmp.replace(QRegExp(" "), "0");
791
 
        Datum += tmp;
792
 
        tmp.sprintf("%2d", d.month());
793
 
        tmp.replace(QRegExp(" "), "0");
794
 
        Datum += tmp;
795
 
        tmp.sprintf("%2d", d.day());
796
 
        tmp.replace(QRegExp(" "), "0");
797
 
        Datum += tmp;
798
 
        tmp = QTime::currentTime().toString();
799
 
        tmp.replace(QRegExp(":"), "");
800
 
        Datum += tmp;
801
 
 
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
804
 
        PutDoc("/Perms\n");
805
 
        PutDoc("<<\n");
806
 
        PutDoc("/UR3\n");
807
 
        PutDoc("<<\n");
808
 
        PutDoc("/M ("+Datum+")\n");
809
 
        PutDoc("/Name (Scribus "+QString(VERSION)+")\n");
810
 
        PutDoc("/Reference [\n");
811
 
        PutDoc("<<\n");
812
 
        PutDoc("/TransformParams\n");
813
 
        PutDoc("<<\n");
814
 
        PutDoc("/Type /TransformParams\n");
815
 
        PutDoc("/V /2.2\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");
820
 
        PutDoc(">>\n");
821
 
        PutDoc("/TransformMethod /UR3\n");
822
 
        PutDoc("/Type /SigRef\n");
823
 
        PutDoc(">>\n");
824
 
        PutDoc("]\n");
825
 
        PutDoc("/Type /Sig\n");
826
 
        PutDoc(">>\n");
827
 
        PutDoc(">>\n");
828
 
*/
829
 
 
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");
839
 
        QString IDg(Datum);
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();
845
 
        IDg += "/False";
846
 
        FileID = ComputeMD5(IDg);
847
 
        if (Options.Encrypt)
848
 
        {
849
 
                if ((Options.Version == PDFOptions::PDFVersion_14) || (Options.Version == PDFOptions::PDFVersion_15))
850
 
                        KeyLen = 16;
851
 
                else
852
 
                        KeyLen = 5;
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]);
857
 
                if (KeyLen > 5)
858
 
                {
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]);
863
 
                }
864
 
                else
865
 
                {
866
 
                        for (uint cl = 0; cl < 32; ++cl)
867
 
                                uk += QChar(UserKey[cl]);
868
 
                }
869
 
        }
870
 
        StartObj(2);
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");
876
 
        else
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());
891
 
        if (Options.Encrypt)
892
 
        {
893
 
                Encrypt = newObject();
894
 
                StartObj(Encrypt);
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");
900
 
        }
901
 
        QMap<QString, QMap<uint, FPointArray> > ReallyUsed;
902
 
        ReallyUsed.clear();
903
 
        PageItem* pgit;
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)
913
 
        {
914
 
                pgit = doc.FrameItems.at(c);
915
 
                if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
916
 
                {
917
 
                        if (pgit->isAnnotation())
918
 
                        {
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)
924
 
                                {
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()]);
928
 
                                }
929
 
                        }
930
 
                        for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
931
 
                        {
932
 
                                ReallyUsed.insert(pgit->itemText.charStyle(e).font().replacementName(), DocFonts[pgit->itemText.charStyle(e).font().replacementName()]);
933
 
                        }
934
 
                }
935
 
        }
936
 
        for (int c = 0; c < doc.MasterItems.count(); ++c)
937
 
        {
938
 
                pgit = doc.MasterItems.at(c);
939
 
                if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
940
 
                {
941
 
                        if (pgit->isAnnotation())
942
 
                        {
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)
948
 
                                {
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()]);
952
 
                                }
953
 
                        }
954
 
                        for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
955
 
                        {
956
 
                                ReallyUsed.insert(pgit->itemText.charStyle(e).font().replacementName(), DocFonts[pgit->itemText.charStyle(e).font().replacementName()]);
957
 
                        }
958
 
                }
959
 
        }
960
 
        for (int d = 0; d < doc.DocItems.count(); ++d)
961
 
        {
962
 
                pgit = doc.DocItems.at(d);
963
 
                if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
964
 
                {
965
 
                        if (pgit->isAnnotation())
966
 
                        {
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)
972
 
                                {
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()]);
976
 
                                }
977
 
                        }
978
 
                        for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
979
 
                        {
980
 
                                ReallyUsed.insert(pgit->itemText.charStyle(e).font().replacementName(), DocFonts[pgit->itemText.charStyle(e).font().replacementName()]);
981
 
                        }
982
 
                }
983
 
        }
984
 
/*      if (Options.docInfoMarks)
985
 
        {
986
 
                StdFonts.insert("/Helvetica", "");
987
 
        } */
988
 
        QStringList patterns = doc.getUsedPatterns();
989
 
        for (int c = 0; c < patterns.count(); ++c)
990
 
        {
991
 
                ScPattern pa = doc.docPatterns[patterns[c]];
992
 
                for (int o = 0; o < pa.items.count(); o++)
993
 
                {
994
 
                        pgit = pa.items.at(o);
995
 
                        if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
996
 
                        {
997
 
                                if (pgit->isAnnotation())
998
 
                                {
999
 
                                        if (pgit->annotation().Type() == 4)
1000
 
                                                StdFonts.insert("/ZapfDingbats", "");
1001
 
                                        if (pgit->itemText.length() > 0)
1002
 
                                        {
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()]);
1006
 
                                        }
1007
 
                                }
1008
 
                                for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
1009
 
                                {
1010
 
                                        ReallyUsed.insert(pgit->itemText.charStyle(e).font().replacementName(), DocFonts[pgit->itemText.charStyle(e).font().replacementName()]);
1011
 
                                }
1012
 
                        }
1013
 
                }
1014
 
        }
1015
 
        a = 0;
1016
 
        QMap<QString, QString>::Iterator itStd;
1017
 
        for (itStd = StdFonts.begin(); itStd != StdFonts.end(); ++itStd)
1018
 
        {
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")
1025
 
                {
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");
1038
 
                        PutDoc("] >>\n");
1039
 
                }
1040
 
                PutDoc(">>\nendobj\n");
1041
 
                Seite.FObjects["FoStd"+QString::number(a)] = fontObject;
1042
 
                itStd.value() = "FoStd"+QString::number(a);
1043
 
                a++;
1044
 
        }
1045
 
        QMap<QString,QMap<uint, FPointArray> >::Iterator it;
1046
 
        a = 0;
1047
 
        for (it = ReallyUsed.begin(); it != ReallyUsed.end(); ++it)
1048
 
        {
1049
 
                ScFace& face(AllFonts[it.key()]);
1050
 
                ScFace::FontFormat fformat = face.format();
1051
 
                if ((!face.hasNames()) || (Options.SubsetList.contains(it.key())))
1052
 
                {
1053
 
                        if (face.hasNames())
1054
 
                        {
1055
 
                                UsedFontsP.insert(it.key(), "/Fo"+QString::number(a));
1056
 
                                uint SubFonts = 0;
1057
 
                                int glyphCount = 0;
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";
1065
 
                                QString fon("");
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)
1072
 
                                {
1073
 
                                        FPoint np, np1, np2;
1074
 
                                        bool nPath = true;
1075
 
                                        fon = "";
1076
 
                                        if (ig.value().size() > 3)
1077
 
                                        {
1078
 
                                                FPointArray gly = ig.value();
1079
 
                                                QMatrix mat;
1080
 
                                                mat.scale(100.0, -100.0);
1081
 
                                                gly.map(mat);
1082
 
                                                gly.translate(0, 1000);
1083
 
                                                for (uint poi = 0; poi < gly.size()-3; poi += 4)
1084
 
                                                {
1085
 
                                                        if (gly.point(poi).x() > 900000)
1086
 
                                                        {
1087
 
                                                                fon += "h\n";
1088
 
                                                                nPath = true;
1089
 
                                                                continue;
1090
 
                                                        }
1091
 
                                                        if (nPath)
1092
 
                                                        {
1093
 
                                                                np = gly.point(poi);
1094
 
                                                                fon += FToStr(np.x())+" "+FToStr(np.y())+" m\n";
1095
 
                                                                nPath = false;
1096
 
                                                        }
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";
1101
 
                                                }
1102
 
                                                fon += "h f*\n";
1103
 
                                                np = getMinClipF(&gly);
1104
 
                                                np1 = getMaxClipF(&gly);
1105
 
                                        }
1106
 
                                        else
1107
 
                                        {
1108
 
                                                fon = "h";
1109
 
                                                np = FPoint(0, 0);
1110
 
                                                np1 = FPoint(0, 0);
1111
 
                                        }
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");
1129
 
                                        glyphCount++;
1130
 
                                        int glyphsLeft = RealGlyphs.count() - SubFonts * 256;
1131
 
                                        if ((glyphCount > 255) || (glyphCount == glyphsLeft))
1132
 
                                        {
1133
 
                                                uint fontWidths = newObject();
1134
 
                                                StartObj(fontWidths);
1135
 
                                                PutDoc("[ ");
1136
 
                                                for (int ww = 0; ww < glyphWidths.count(); ++ww)
1137
 
                                                {
1138
 
                                                        PutDoc(QString::number(qRound(glyphWidths[ww]))+" ");
1139
 
                                                }
1140
 
                                                PutDoc("]\nendobj\n");
1141
 
                                                uint fontCharProcs = newObject();
1142
 
                                                StartObj(fontCharProcs);
1143
 
                                                PutDoc("<<\n");
1144
 
                                                for (int ww = 0; ww < charProcs.count(); ++ww)
1145
 
                                                {
1146
 
                                                        PutDoc(charProcs[ww]);
1147
 
                                                }
1148
 
                                                PutDoc(">>\nendobj\n");
1149
 
                                                uint fontEncoding = newObject();
1150
 
                                                StartObj(fontEncoding);
1151
 
                                                PutDoc(encoding);
1152
 
                                                PutDoc("]\n");
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;
1167
 
                                                charProcs.clear();
1168
 
                                                glyphWidths.clear();
1169
 
//                                              glyphMapping.clear();
1170
 
                                                glyphCount = 0;
1171
 
                                                ++SubFonts;
1172
 
                                                minx = 99999.9;
1173
 
                                                miny = 99999.9;
1174
 
                                                maxx = -99999.9;
1175
 
                                                maxy = -99999.9;
1176
 
                                                encoding = "<< /Type /Encoding\n/Differences [ 0\n";
1177
 
                                        }
1178
 
                                }
1179
 
                                Type3Fonts.insert("/Fo"+QString::number(a), glyphMapping);
1180
 
                        }
1181
 
                        else
1182
 
                        {
1183
 
                                QString fon("");
1184
 
                                QMap<uint,FPointArray>& RealGlyphs(it.value());
1185
 
                                QMap<uint,FPointArray>::Iterator ig;
1186
 
                                for (ig = RealGlyphs.begin(); ig != RealGlyphs.end(); ++ig)
1187
 
                                {
1188
 
                                        FPoint np, np1, np2;
1189
 
                                        bool nPath = true;
1190
 
                                        fon = "";
1191
 
                                        if (ig.value().size() > 3)
1192
 
                                        {
1193
 
                                                FPointArray gly = ig.value();
1194
 
                                                QMatrix mat;
1195
 
                                                mat.scale(0.1, 0.1);
1196
 
                                                gly.map(mat);
1197
 
                                                for (uint poi = 0; poi < gly.size()-3; poi += 4)
1198
 
                                                {
1199
 
                                                        if (gly.point(poi).x() > 900000)
1200
 
                                                        {
1201
 
                                                                fon += "h\n";
1202
 
                                                                nPath = true;
1203
 
                                                                continue;
1204
 
                                                        }
1205
 
                                                        if (nPath)
1206
 
                                                        {
1207
 
                                                                np = gly.point(poi);
1208
 
                                                                fon += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
1209
 
                                                                nPath = false;
1210
 
                                                        }
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";
1217
 
                                                }
1218
 
                                                fon += "h f*\n";
1219
 
                                                np = getMinClipF(&gly);
1220
 
                                                np1 = getMaxClipF(&gly);
1221
 
                                        }
1222
 
                                        else
1223
 
                                        {
1224
 
                                                fon = "h";
1225
 
                                                np = FPoint(0, 0);
1226
 
                                                np1 = FPoint(0, 0);
1227
 
                                        }
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");
1233
 
                                        PutDoc(">>\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;
1241
 
                                }
1242
 
                        }
1243
 
                }
1244
 
                else
1245
 
                {
1246
 
                        UsedFontsP.insert(it.key(), "/Fo"+QString::number(a));
1247
 
                        uint embeddedFontObject = 0;
1248
 
                        if ((fformat == ScFace::PFB) && (Options.EmbedList.contains(it.key())))
1249
 
                        {
1250
 
                                QString fon("");
1251
 
                                embeddedFontObject = newObject();
1252
 
                                StartObj(embeddedFontObject);
1253
 
                                QByteArray bb;
1254
 
                                AllFonts[it.key()].RawData(bb);
1255
 
                                int posi;
1256
 
                                for (posi = 6; posi < bb.size(); ++posi)
1257
 
                                {
1258
 
                                        if ((bb[posi] == static_cast<char>(0x80)) && (static_cast<int>(bb[posi+1]) == 2))
1259
 
                                                break;
1260
 
                                        fon += QChar(bb[posi]);
1261
 
                                }
1262
 
                                int len1 = fon.length();
1263
 
                                int ulen;
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())
1269
 
                                        ulen = bb.size()-7;
1270
 
                                posi += 6;
1271
 
                                for (int j = 0; j < ulen; ++j)
1272
 
                                        fon += QChar(bb[posi++]);
1273
 
                                posi += 6;
1274
 
                                int len2 = fon.length()-len1;
1275
 
                                for (int j = posi; j < bb.size(); ++j)
1276
 
                                {
1277
 
                                        if ((bb[j] == static_cast<char>(0x80)) && (static_cast<int>(bb[j+1]) == 3))
1278
 
                                                break;
1279
 
                                        if (bb[j] == '\r')
1280
 
                                                fon += "\n";
1281
 
                                        else
1282
 
                                                fon += QChar(bb[j]);
1283
 
                                }
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");
1294
 
                        }
1295
 
                        if ((fformat == ScFace::PFA) && (Options.EmbedList.contains(it.key())))
1296
 
                        {
1297
 
                                QString fon("");
1298
 
                                QString fon2("");
1299
 
                                QString tm("");
1300
 
                                uint value;
1301
 
                                bool ok = true;
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");
1308
 
                                if (len2 == -1)
1309
 
                                        len2 = fon.length()+1;
1310
 
                                int count = 0;
1311
 
                                for (int xx = len1; xx < len2-1; ++xx)
1312
 
                                {
1313
 
                                        tm = fon.at(xx);
1314
 
                                        if ((tm == QChar(13)) || (tm == QChar(10)))
1315
 
                                                continue;
1316
 
                                        xx++;
1317
 
                                        count++;
1318
 
                                        tm += fon.at(xx);
1319
 
                                        value = tm.toUInt(&ok, 16);
1320
 
                                        fon2 += QChar(value);
1321
 
                                }
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");
1332
 
                        }
1333
 
                        if ((fformat == ScFace::SFNT || fformat == ScFace::TTCF) && (Options.EmbedList.contains(it.key())))
1334
 
                        {
1335
 
                                QString fon("");
1336
 
                                embeddedFontObject = newObject();
1337
 
                                StartObj(embeddedFontObject);
1338
 
                                QByteArray bb;
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");
1352
 
                        }
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");
1359
 
                        PutDoc("/Flags ");
1360
 
                        //FIXME: isItalic() should be queried from ScFace, not from Qt -- AV
1361
 
                        //QFontInfo fo = QFontInfo(it.data());
1362
 
                        int pfl = 0;
1363
 
                        if (AllFonts[it.key()].isFixedPitch())
1364
 
                                pfl = pfl ^ 1;
1365
 
                        //if (fo.italic())
1366
 
                        if (AllFonts[it.key()].italicAngleAsString() != "0")
1367
 
                                pfl = pfl ^ 64;
1368
 
//                      pfl = pfl ^ 4;
1369
 
                        pfl = pfl ^ 32;
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()])
1389
 
                        {
1390
 
                                StartObj(ObjCounter);
1391
 
                                int chCount = 31;
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)
1394
 
                                {
1395
 
                                        PutDoc(QString::number(static_cast<int>(AllFonts[it.key()]->CharWidth[itg.key()]*
1396
 
                                                        1000))+" ");
1397
 
                                        if (itg == gl.end())
1398
 
                                                break;
1399
 
                                        ++itg;
1400
 
                                        chCount++;
1401
 
                                }
1402
 
                                PutDoc("]\nendobj\n");
1403
 
                                ObjCounter++;
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");
1411
 
                                //cf. widths:
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;
1418
 
                                ObjCounter++;
1419
 
                        }
1420
 
                        else */
1421
 
//                      {
1422
 
                                QMap<uint,std::pair<QChar,QString> > gl;
1423
 
                                AllFonts[it.key()].glyphNames(gl);
1424
 
                                int nglyphs = 0;
1425
 
                                QMap<uint,std::pair<QChar,QString> >::Iterator gli;
1426
 
                                for (gli = gl.begin(); gli != gl.end(); ++gli)
1427
 
                                {
1428
 
                                        if (gli.key() > static_cast<uint>(nglyphs))
1429
 
                                                nglyphs = gli.key();
1430
 
                                }
1431
 
                                ++nglyphs;
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)
1436
 
                                        Fcc += 1;
1437
 
                                for (uint Fc = 0; Fc < Fcc; ++Fc)
1438
 
                                {
1439
 
                                        uint fontWidths2 = newObject();
1440
 
                                        StartObj(fontWidths2);
1441
 
                                        int chCount = 32;
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)
1444
 
                                        {
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))+" ");
1448
 
                                                else
1449
 
                                                        PutDoc("0 ");
1450
 
                                                chCount++;
1451
 
                                                if (signed(glyph) == nglyphs-1)
1452
 
                                                        break;
1453
 
                                        }
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");
1463
 
                                        int crc = 0;
1464
 
                                        bool startOfSeq = true;
1465
 
                                        for (int ww2 = 32; ww2 < 256; ++ww2)
1466
 
                                        {
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())
1470
 
                                                {
1471
 
                                                        if (startOfSeq)
1472
 
                                                        {
1473
 
                                                                PutDoc(QString::number(ww2)+" ");
1474
 
                                                                startOfSeq = false;
1475
 
                                                        }
1476
 
                                                        PutDoc("/"+glIt.value().second+" ");
1477
 
                                                        QString tmp, tmp2;
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)
1483
 
                                                        {
1484
 
                                                                toUnicodeMaps.append(toUnicodeMap);
1485
 
                                                                toUnicodeMapsCount.append(toUnicodeMapCounter);
1486
 
                                                                toUnicodeMap = "";
1487
 
                                                                toUnicodeMapCounter = 0;
1488
 
                                                        }
1489
 
                                                        crc++;
1490
 
                                                }
1491
 
                                                else
1492
 
                                                {
1493
 
                                                        startOfSeq = true;
1494
 
                                                }
1495
 
                                                if (signed(glyph) == nglyphs-1)
1496
 
                                                        break;
1497
 
                                                if (crc > 8)
1498
 
                                                {
1499
 
                                                        PutDoc("\n");
1500
 
                                                        crc = 0;
1501
 
                                                }
1502
 
                                        }
1503
 
                                        if (toUnicodeMapCounter != 0)
1504
 
                                        {
1505
 
                                                toUnicodeMaps.append(toUnicodeMap);
1506
 
                                                toUnicodeMapsCount.append(toUnicodeMapCounter);
1507
 
                                        }
1508
 
                                        PutDoc("]\n");
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++)
1525
 
                                        {
1526
 
                                                toUnicodeMapStream += QString("%1 beginbfchar\n").arg(toUnicodeMapsCount[uniC]);
1527
 
                                                toUnicodeMapStream += toUnicodeMaps[uniC];
1528
 
                                                toUnicodeMapStream += "endbfchar\n";
1529
 
                                        }
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;
1549
 
                                } // for(Fc)
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)
1554
 
                                {
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))+" ");
1558
 
                                        else
1559
 
                                                PutDoc("0 ");
1560
 
                                }
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)
1567
 
//                              {
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");
1572
 
/*                              }
1573
 
                                else
1574
 
                                {
1575
 
                                        PutDoc("/Type1\n");
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\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" ));
1579
 
                                } */
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");
1593
 
                                PutDoc("] >>\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
1600
 
                }
1601
 
                a++;
1602
 
        }
1603
 
        if (Options.UseLPI)
1604
 
        {
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)
1610
 
                {
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 ");
1613
 
                        QString func ("");
1614
 
                        switch (itlp.value().SpotFunc)
1615
 
                        {
1616
 
                                case 0:
1617
 
                                        func = "/SimpleDot";
1618
 
                                        break;
1619
 
                                case 1:
1620
 
                                        func = "/Line";
1621
 
                                        break;
1622
 
                                case 2:
1623
 
                                        func = "/Round";
1624
 
                                        break;
1625
 
                                case 3:
1626
 
                                        func = "/Ellipse";
1627
 
                                        break;
1628
 
                                default:
1629
 
                                        func = "/SimpleDot";
1630
 
                                        break;
1631
 
                        }
1632
 
                        PutDoc(func+"\n>>\n");
1633
 
                }
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");
1638
 
                ResCount++;
1639
 
        }
1640
 
        if ((doc.HasCMS) && (Options.UseProfiles))
1641
 
        {
1642
 
                uint iccProfileObject = newObject();
1643
 
                StartObj(iccProfileObject);
1644
 
                QByteArray dataP;
1645
 
                struct ICCD dataD;
1646
 
                loadRawBytes(ScCore->InputProfiles[Options.SolidProf], dataP);
1647
 
                PutDoc("<<\n");
1648
 
                if (Options.Compress)
1649
 
                {
1650
 
                        QByteArray compData = CompressArray(dataP);
1651
 
                        if (compData.size() > 0)
1652
 
                        {
1653
 
                                PutDoc("/Filter /FlateDecode\n");
1654
 
                                dataP = compData;
1655
 
                        }
1656
 
                }
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");
1670
 
                PutDoc("endobj\n");
1671
 
                ResCount++;
1672
 
        }
1673
 
        if (((Options.isGrayscale == false) && (Options.UseRGB == false)) && (Options.UseSpotColors))
1674
 
        {
1675
 
                doc.getUsedColors(colorsToUse);
1676
 
                ColorList::Iterator itf;
1677
 
                for (itf = colorsToUse.begin(); itf != colorsToUse.end(); ++itf)
1678
 
                {
1679
 
                        if ((colorsToUse[itf.key()].isSpotColor()) || (colorsToUse[itf.key()].isRegistrationColor()))
1680
 
                        {
1681
 
                                CMYKColor cmykValues;
1682
 
                                int cc, cm, cy, ck;
1683
 
                                struct SpotC spotD;
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())
1701
 
                                        PutDoc("All");
1702
 
                                else
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);
1708
 
                                spotCount++;
1709
 
                        }
1710
 
                }
1711
 
        }
1712
 
        if ((Options.cropMarks) || (Options.bleedMarks) || (Options.registrationMarks) || (Options.colorMarks) || (Options.docInfoMarks))
1713
 
        {
1714
 
                struct SpotC spotD;
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");
1723
 
                PutDoc("/N 1\n");
1724
 
                PutDoc(">>\n]\nendobj\n");
1725
 
                spotD.ResName = spotNam+QString::number(spotCount);
1726
 
                spotD.ResNum = registrationColorspace;
1727
 
                spotMapReg.insert("Register", spotD);
1728
 
                spotCount++;
1729
 
        }
1730
 
        if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
1731
 
        {
1732
 
                ScLayer ll;
1733
 
                struct OCGInfo ocg;
1734
 
                ll.isPrintable = false;
1735
 
                ll.LNr = 0;
1736
 
                int Lnr = 0;
1737
 
                QString ocgNam("oc");
1738
 
                uint docLayersCount=doc.Layers.count();
1739
 
                for (uint la = 0; la < docLayersCount; ++la)
1740
 
                {
1741
 
                        uint optionalContent = newObject();
1742
 
                        QString tmp("");
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);
1749
 
                        PutDoc("<<\n");
1750
 
                        PutDoc("/Type /OCG\n");
1751
 
                        PutDoc("/Name ");
1752
 
                        PutDoc(EncStringUTF16("("+ll.Name+")", optionalContent));
1753
 
                        PutDoc("\n");
1754
 
                        PutDoc("/Usage <</Print <</PrintState ");
1755
 
                        if (ll.isPrintable)
1756
 
                                PutDoc("/ON");
1757
 
                        else
1758
 
                                PutDoc("/OFF");
1759
 
                        PutDoc(">> /View <</ViewState ");
1760
 
                        if (ll.isViewable)
1761
 
                                PutDoc("/ON");
1762
 
                        else
1763
 
                                PutDoc("/OFF");
1764
 
                        PutDoc(">>>>>>");
1765
 
                        PutDoc("\n");
1766
 
                        PutDoc(">>\nendobj\n");
1767
 
                        Lnr++;
1768
 
                }
1769
 
        }
1770
 
        return true;
1771
 
}
1772
 
 
1773
 
bool PDFLibCore::PDF_TemplatePage(const Page* pag, bool )
1774
 
{
1775
 
        QString tmp, tmpOut;
1776
 
        ActPageP = pag;
1777
 
        PageItem* ite;
1778
 
        QList<PageItem*> PItems;
1779
 
        int Lnr = 0;
1780
 
        ScLayer ll;
1781
 
        ll.isPrintable = false;
1782
 
        ll.LNr = 0;
1783
 
        Content = "";
1784
 
        Seite.AObjects.clear();
1785
 
        for (int la = 0; la < doc.Layers.count(); ++la)
1786
 
        {
1787
 
                doc.Layers.levelToLayer(ll, Lnr);
1788
 
                PItems = doc.MasterItems;
1789
 
                if ((ll.isPrintable) || ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers)))
1790
 
                {
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)
1794
 
                        {
1795
 
                                Content = "";
1796
 
                                ite =PItems.at(a);
1797
 
                                if (ite->LayerNr != ll.LNr)
1798
 
                                        continue;
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 )))
1811
 
                                        continue;
1812
 
                                if (ite->ChangedMasterItem)
1813
 
                                        continue;
1814
 
                                if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
1815
 
                                        continue;
1816
 
                                PutPage("q\n");
1817
 
                                if ((ite->doOverprint) && (!Options.UseRGB))
1818
 
                                {
1819
 
                                        QString ShName = ResNam+QString::number(ResCount);
1820
 
                                        ResCount++;
1821
 
                                        Transpar[ShName] = writeGState("/OP true\n"
1822
 
                                                                                                   "/op true\n"
1823
 
                                                                                                   "/OPM 1\n");
1824
 
                                        PutPage("/"+ShName+" gs\n");
1825
 
                                }
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())))
1830
 
                                {
1831
 
                                        PutPage("Q\n");
1832
 
                                        continue;
1833
 
                                }
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)
1840
 
                                {
1841
 
                                        PutPage("[ ");
1842
 
                                        QVector<double>::iterator it;
1843
 
                                        for ( it = ite->DashValues.begin(); it != ite->DashValues.end(); ++it )
1844
 
                                        {
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)+" ");
1850
 
                                        }
1851
 
                                        PutPage("] "+QString::number(static_cast<int>(ite->DashOffset))+" d\n");
1852
 
                                }
1853
 
                                else
1854
 
                                        PutPage("["+getDashString(ite->PLineArt, ite->lineWidth())+"] 0 d\n");
1855
 
                                switch (ite->PLineEnd)
1856
 
                                {
1857
 
                                        case Qt::FlatCap:
1858
 
                                                PutPage("0 J\n");
1859
 
                                                break;
1860
 
                                        case Qt::SquareCap:
1861
 
                                                PutPage("2 J\n");
1862
 
                                                break;
1863
 
                                        case Qt::RoundCap:
1864
 
                                                PutPage("1 J\n");
1865
 
                                                break;
1866
 
                                        default:
1867
 
                                                PutPage("0 J\n");
1868
 
                                                break;
1869
 
                                }
1870
 
                                switch (ite->PLineJoin)
1871
 
                                {
1872
 
                                        case Qt::MiterJoin:
1873
 
                                                PutPage("0 j\n");
1874
 
                                                break;
1875
 
                                        case Qt::BevelJoin:
1876
 
                                                PutPage("2 j\n");
1877
 
                                                break;
1878
 
                                        case Qt::RoundJoin:
1879
 
                                                PutPage("1 j\n");
1880
 
                                                break;
1881
 
                                        default:
1882
 
                                                PutPage("0 j\n");
1883
 
                                                break;
1884
 
                                }
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)
1887
 
                                {
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)
1891
 
                                                cr = 0;
1892
 
                                        if ((sr * sr) < 0.000001)
1893
 
                                                sr = 0;
1894
 
                                        PutPage(FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+" 0 0 cm\n");
1895
 
                                }
1896
 
                                switch (ite->itemType())
1897
 
                                {
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))
1904
 
                                                {
1905
 
                                                        if (ite->GrType != 0)
1906
 
                                                        {
1907
 
                                                                if (!PDF_Gradient(tmpOut, ite))
1908
 
                                                                        return false;
1909
 
                                                                PutPage(tmpOut);
1910
 
                                                        }
1911
 
                                                        else
1912
 
                                                        {
1913
 
                                                                PutPage(SetClipPath(ite));
1914
 
                                                                PutPage("h\nf*\n");
1915
 
                                                        }
1916
 
                                                }
1917
 
                                                PutPage("q\n");
1918
 
                                                if (ite->imageClip.size() != 0)
1919
 
                                                {
1920
 
                                                        PutPage(SetClipPathImage(ite));
1921
 
                                                        PutPage("h\nW*\nn\n");
1922
 
                                                }
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()))
1930
 
                                                {
1931
 
                                                        if (!PDF_Image(ite, ite->Pfile, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), false, ite->IProfile, ite->UseEmbedded, ite->IRender, &tmpOut))
1932
 
                                                                return false;
1933
 
                                                        PutPage(tmpOut);
1934
 
                                                }
1935
 
                                                PutPage("Q\n");
1936
 
                                                if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
1937
 
                                                {
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))
1941
 
                                                        {
1942
 
                                                                PutPage(SetClipPath(ite));
1943
 
                                                                PutPage("h\nS\n");
1944
 
                                                        }
1945
 
                                                        else
1946
 
                                                        {
1947
 
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
1948
 
                                                                for (int it = ml.size()-1; it > -1; it--)
1949
 
                                                                {
1950
 
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1951
 
                                                                        {
1952
 
                                                                                PutPage(setStrokeMulti(&ml[it]));
1953
 
                                                                                PutPage(SetClipPath(ite));
1954
 
                                                                                PutPage("h\nS\n");
1955
 
                                                                        }
1956
 
                                                                }
1957
 
                                                        }
1958
 
                                                }
1959
 
                                                break;
1960
 
                                        case PageItem::TextFrame:
1961
 
                                                break;
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())
1966
 
                                                {
1967
 
                                                        PutPage("0 0 m\n");
1968
 
                                                        PutPage(FToStr(ite->width())+" 0 l\n");
1969
 
                                                        PutPage("S\n");
1970
 
                                                }
1971
 
                                                else
1972
 
                                                {
1973
 
                                                        multiLine ml = doc.MLineStyles[ite->NamedLStyle];
1974
 
                                                        for (int it = ml.size()-1; it > -1; it--)
1975
 
                                                        {
1976
 
                                                                if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1977
 
                                                                {
1978
 
                                                                        PutPage(setStrokeMulti(&ml[it]));
1979
 
                                                                        PutPage("0 0 m\n");
1980
 
                                                                        PutPage(FToStr(ite->width())+" 0 l\n");
1981
 
                                                                        PutPage("S\n");
1982
 
                                                                }
1983
 
                                                        }
1984
 
                                                }
1985
 
                                                if (ite->startArrowIndex() != 0)
1986
 
                                                {
1987
 
                                                        QMatrix arrowTrans;
1988
 
                                                        arrowTrans.scale(-1,1);
1989
 
                                                        PutPage(drawArrow(ite, arrowTrans, ite->startArrowIndex()));
1990
 
                                                }
1991
 
                                                if (ite->endArrowIndex() != 0)
1992
 
                                                {
1993
 
                                                        QMatrix arrowTrans;
1994
 
                                                        arrowTrans.translate(ite->width(), 0);
1995
 
                                                        PutPage(drawArrow(ite, arrowTrans, ite->endArrowIndex()));
1996
 
                                                }
1997
 
                                                break;
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)
2004
 
                                                {
2005
 
                                                        if (!PDF_Gradient(tmpOut, ite))
2006
 
                                                                return false;
2007
 
                                                        PutPage(tmpOut);
2008
 
                                                }
2009
 
                                                else
2010
 
                                                {
2011
 
                                                        if (ite->fillColor() != CommonStrings::None)
2012
 
                                                        {
2013
 
                                                                PutPage(SetClipPath(ite));
2014
 
                                                                PutPage("h\nf*\n");
2015
 
                                                        }
2016
 
                                                }
2017
 
                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
2018
 
                                                {
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))
2022
 
                                                        {
2023
 
                                                                PutPage(SetClipPath(ite));
2024
 
                                                                PutPage("h\nS\n");
2025
 
                                                        }
2026
 
                                                        else
2027
 
                                                        {
2028
 
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
2029
 
                                                                for (int it = ml.size()-1; it > -1; it--)
2030
 
                                                                {
2031
 
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
2032
 
                                                                        {
2033
 
                                                                                PutPage(setStrokeMulti(&ml[it]));
2034
 
                                                                                PutPage(SetClipPath(ite));
2035
 
                                                                                PutPage("h\nS\n");
2036
 
                                                                        }
2037
 
                                                                }
2038
 
                                                        }
2039
 
                                                }
2040
 
                                                break;
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))))
2043
 
                                                {
2044
 
                                                        if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2045
 
                                                                PutPage(PDF_TransparenzFill(ite));
2046
 
                                                        if (ite->GrType != 0)
2047
 
                                                        {
2048
 
                                                                if (!PDF_Gradient(tmpOut, ite))
2049
 
                                                                        return false;
2050
 
                                                                PutPage(tmpOut);
2051
 
                                                        }
2052
 
                                                        else
2053
 
                                                        {
2054
 
                                                                if (ite->fillColor() != CommonStrings::None)
2055
 
                                                                {
2056
 
                                                                        PutPage(SetClipPath(ite));
2057
 
                                                                        PutPage("h\nf*\n");
2058
 
                                                                }
2059
 
                                                        }
2060
 
                                                }
2061
 
                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
2062
 
                                                {
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))
2066
 
                                                        {
2067
 
                                                                PutPage(SetClipPath(ite, false));
2068
 
                                                                PutPage("S\n");
2069
 
                                                        }
2070
 
                                                        else
2071
 
                                                        {
2072
 
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
2073
 
                                                                for (int it = ml.size()-1; it > -1; it--)
2074
 
                                                                {
2075
 
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
2076
 
                                                                        {
2077
 
                                                                                PutPage(setStrokeMulti(&ml[it]));
2078
 
                                                                                PutPage(SetClipPath(ite, false));
2079
 
                                                                                PutPage("S\n");
2080
 
                                                                        }
2081
 
                                                                }
2082
 
                                                        }
2083
 
                                                }
2084
 
                                                if (ite->startArrowIndex() != 0)
2085
 
                                                {
2086
 
                                                        FPoint Start = ite->PoLine.point(0);
2087
 
                                                        for (uint xx = 1; xx < ite->PoLine.size(); xx += 2)
2088
 
                                                        {
2089
 
                                                                FPoint Vector = ite->PoLine.point(xx);
2090
 
                                                                if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
2091
 
                                                                {
2092
 
                                                                        double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
2093
 
                                                                        QMatrix arrowTrans;
2094
 
                                                                        arrowTrans.translate(Start.x(), Start.y());
2095
 
                                                                        arrowTrans.rotate(r);
2096
 
                                                                        PutPage(drawArrow(ite, arrowTrans, ite->startArrowIndex()));
2097
 
                                                                        break;
2098
 
                                                                }
2099
 
                                                        }
2100
 
                                                }
2101
 
                                                if (ite->endArrowIndex() != 0)
2102
 
                                                {
2103
 
                                                        FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
2104
 
                                                        for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
2105
 
                                                        {
2106
 
                                                                FPoint Vector = ite->PoLine.point(xx);
2107
 
                                                                if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
2108
 
                                                                {
2109
 
                                                                        double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
2110
 
                                                                        QMatrix arrowTrans;
2111
 
                                                                        arrowTrans.translate(End.x(), End.y());
2112
 
                                                                        arrowTrans.rotate(r);
2113
 
                                                                        PutPage(drawArrow(ite, arrowTrans, ite->endArrowIndex()));
2114
 
                                                                        break;
2115
 
                                                                }
2116
 
                                                        }
2117
 
                                                }
2118
 
                                                break;
2119
 
                                        case PageItem::PathText:
2120
 
                                                if (ite->PoShow)
2121
 
                                                {
2122
 
                                                        if (ite->PoLine.size() > 3)
2123
 
                                                        {
2124
 
                                                                PutPage("q\n");
2125
 
                                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
2126
 
                                                                {
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))
2130
 
                                                                        {
2131
 
                                                                                PutPage(SetClipPath(ite, false));
2132
 
                                                                                PutPage("S\n");
2133
 
                                                                        }
2134
 
                                                                        else
2135
 
                                                                        {
2136
 
                                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
2137
 
                                                                                for (int it = ml.size()-1; it > -1; it--)
2138
 
                                                                                {
2139
 
                                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
2140
 
                                                                                        {
2141
 
                                                                                                PutPage(setStrokeMulti(&ml[it]));
2142
 
                                                                                                PutPage(SetClipPath(ite, false));
2143
 
                                                                                                PutPage("S\n");
2144
 
                                                                                        }
2145
 
                                                                                }
2146
 
                                                                        }
2147
 
                                                                }
2148
 
                                                                PutPage("Q\n");
2149
 
                                                        }
2150
 
                                                }
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));
2154
 
                                                break;
2155
 
                                        case PageItem::Multiple:
2156
 
                                                Q_ASSERT(false);
2157
 
                                                break;
2158
 
                                }
2159
 
                                PutPage("Q\n");
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)
2172
 
                                {
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");
2177
 
                                        PutDoc(">>\n");
2178
 
                                }
2179
 
                                if (Seite.FObjects.count() != 0)
2180
 
                                {
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");
2185
 
                                        PutDoc(">>\n");
2186
 
                                }
2187
 
                                if (Shadings.count() != 0)
2188
 
                                {
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");
2193
 
                                        PutDoc(">>\n");
2194
 
                                }
2195
 
                                if (Patterns.count() != 0)
2196
 
                                {
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");
2201
 
                                        PutDoc(">>\n");
2202
 
                                }
2203
 
                                if (Transpar.count() != 0)
2204
 
                                {
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");
2209
 
                                        PutDoc(">>\n");
2210
 
                                }
2211
 
                                if ((ICCProfiles.count() != 0) || (spotMap.count() != 0))
2212
 
                                {
2213
 
                                        PutDoc("/ColorSpace << \n");
2214
 
                                        QMap<QString,ICCD>::Iterator it3c;
2215
 
                                        if (ICCProfiles.count() != 0)
2216
 
                                        {
2217
 
                                                for (it3c = ICCProfiles.begin(); it3c != ICCProfiles.end(); ++it3c)
2218
 
                                                        PutDoc("/"+it3c.value().ResName+" "+QString::number(it3c.value().ResNum)+" 0 R\n");
2219
 
                                        }
2220
 
                                        QMap<QString,SpotC>::Iterator it3sc;
2221
 
                                        if (spotMap.count() != 0)
2222
 
                                        {
2223
 
                                                for (it3sc = spotMap.begin(); it3sc != spotMap.end(); ++it3sc)
2224
 
                                                        PutDoc("/"+it3sc.value().ResName+" "+QString::number(it3sc.value().ResNum)+" 0 R\n");
2225
 
                                        }
2226
 
                                        PutDoc(">>\n");
2227
 
                                }
2228
 
                                PutDoc(">>\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;
2238
 
                        }
2239
 
                        if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
2240
 
                                PutPage("EMC\n");
2241
 
                }
2242
 
                Lnr++;
2243
 
        }
2244
 
        return true;
2245
 
}
2246
 
 
2247
 
void PDFLibCore::PDF_Begin_Page(const Page* pag, QPixmap pm)
2248
 
{
2249
 
        QString tmp;
2250
 
        ActPageP = pag;
2251
 
        Content = "";
2252
 
        Seite.AObjects.clear();
2253
 
        if (Options.Thumbnails)
2254
 
        {
2255
 
                ScImage img(pm.toImage());
2256
 
                bool compDataAvail = false;
2257
 
                QByteArray array = img.ImageToArray();
2258
 
                if (Options.Compress)
2259
 
                {
2260
 
                        QByteArray compArray = CompressArray(array);
2261
 
                        if (compArray.size() > 0)
2262
 
                        {
2263
 
                                array = compArray;
2264
 
                                compDataAvail = true;
2265
 
                        }
2266
 
                }
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");
2272
 
                
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;
2280
 
        }
2281
 
}
2282
 
 
2283
 
void PDFLibCore::PDF_End_Page(int physPage)
2284
 
{
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)
2294
 
        //PutPage("Q\n");
2295
 
        if ((Options.cropMarks) || (Options.bleedMarks) || (Options.registrationMarks) || (Options.colorMarks) || (Options.docInfoMarks))
2296
 
        {
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)
2300
 
                {
2301
 
                // Bottom Left
2302
 
                        PutPage("0 "+FToStr(markOffs+Options.bleeds.Bottom)+" m\n");
2303
 
                        PutPage(FToStr(20.0)+" "+FToStr(markOffs+Options.bleeds.Bottom)+" l\n");
2304
 
                        PutPage("S\n");
2305
 
                        PutPage(FToStr(markOffs+bleedLeft)+" 0 m\n");
2306
 
                        PutPage(FToStr(markOffs+bleedLeft)+" 20 l\n");
2307
 
                        PutPage("S\n");
2308
 
                // Top Left
2309
 
                        PutPage("0 "+FToStr(maxBoxY-Options.bleeds.Top-markOffs)+" m\n");
2310
 
                        PutPage(FToStr(20.0)+" "+FToStr(maxBoxY-Options.bleeds.Top-markOffs)+" l\n");
2311
 
                        PutPage("S\n");
2312
 
                        PutPage(FToStr(markOffs+bleedLeft)+" "+FToStr(maxBoxY)+" m\n");
2313
 
                        PutPage(FToStr(markOffs+bleedLeft)+" "+FToStr(maxBoxY-20.0)+" l\n");
2314
 
                        PutPage("S\n");
2315
 
                // Bottom Right
2316
 
                        PutPage(FToStr(maxBoxX)+" "+FToStr(markOffs+Options.bleeds.Bottom)+" m\n");
2317
 
                        PutPage(FToStr(maxBoxX-20.0)+" "+FToStr(markOffs+Options.bleeds.Bottom)+" l\n");
2318
 
                        PutPage("S\n");
2319
 
                        PutPage(FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(0.0)+" m\n");
2320
 
                        PutPage(FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(20.0)+" l\n");
2321
 
                        PutPage("S\n");
2322
 
                // Top Right
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");
2325
 
                        PutPage("S\n");
2326
 
                        PutPage(FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(maxBoxY)+" m\n");
2327
 
                        PutPage(FToStr(maxBoxX-bleedRight-markOffs)+" "+FToStr(maxBoxY-20.0)+" l\n");
2328
 
                        PutPage("S\n");
2329
 
                }
2330
 
                if (Options.bleedMarks)
2331
 
                {
2332
 
                        PutPage("q\n");
2333
 
                        PutPage("[3 1 1 1] 0 d\n");
2334
 
                // Bottom Left
2335
 
                        PutPage("0 "+FToStr(markOffs)+" m\n");
2336
 
                        PutPage(FToStr(20.0)+" "+FToStr(markOffs)+" l\n");
2337
 
                        PutPage("S\n");
2338
 
                        PutPage(FToStr(markOffs)+" 0 m\n");
2339
 
                        PutPage(FToStr(markOffs)+" 20 l\n");
2340
 
                        PutPage("S\n");
2341
 
                // Top Left
2342
 
                        PutPage("0 "+FToStr(maxBoxY-markOffs)+" m\n");
2343
 
                        PutPage(FToStr(20.0)+" "+FToStr(maxBoxY-markOffs)+" l\n");
2344
 
                        PutPage("S\n");
2345
 
                        PutPage(FToStr(markOffs)+" "+FToStr(maxBoxY)+" m\n");
2346
 
                        PutPage(FToStr(markOffs)+" "+FToStr(maxBoxY-20.0)+" l\n");
2347
 
                        PutPage("S\n");
2348
 
                // Bottom Right
2349
 
                        PutPage(FToStr(maxBoxX)+" "+FToStr(markOffs)+" m\n");
2350
 
                        PutPage(FToStr(maxBoxX-20.0)+" "+FToStr(markOffs)+" l\n");
2351
 
                        PutPage("S\n");
2352
 
                        PutPage(FToStr(maxBoxX-markOffs)+" "+FToStr(0.0)+" m\n");
2353
 
                        PutPage(FToStr(maxBoxX-markOffs)+" "+FToStr(20.0)+" l\n");
2354
 
                        PutPage("S\n");
2355
 
                // Top Right
2356
 
                        PutPage(FToStr(maxBoxX)+" "+FToStr(maxBoxY-markOffs)+" m\n");
2357
 
                        PutPage(FToStr(maxBoxX-20.0)+" "+FToStr(maxBoxY-markOffs)+" l\n");
2358
 
                        PutPage("S\n");
2359
 
                        PutPage(FToStr(maxBoxX-markOffs)+" "+FToStr(maxBoxY)+" m\n");
2360
 
                        PutPage(FToStr(maxBoxX-markOffs)+" "+FToStr(maxBoxY-20.0)+" l\n");
2361
 
                        PutPage("S\n");
2362
 
                        PutPage("Q\n");
2363
 
                }
2364
 
                if (Options.registrationMarks)
2365
 
                {
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";
2369
 
                        PutPage("q\n");
2370
 
                        PutPage("1 0 0 1 "+FToStr(maxBoxX / 2.0 - 7.0)+" 3 cm\n");
2371
 
                        PutPage(regCross);
2372
 
                        PutPage("Q\n");
2373
 
                        PutPage("q\n");
2374
 
                        PutPage("1 0 0 1 3 "+FToStr(maxBoxY / 2.0 - 7.0)+" cm\n");
2375
 
                        PutPage(regCross);
2376
 
                        PutPage("Q\n");
2377
 
                        PutPage("q\n");
2378
 
                        PutPage("1 0 0 1 "+FToStr(maxBoxX / 2.0 - 7.0)+" "+FToStr(maxBoxY - 17.0)+" cm\n");
2379
 
                        PutPage(regCross);
2380
 
                        PutPage("Q\n");
2381
 
                        PutPage("q\n");
2382
 
                        PutPage("1 0 0 1 "+FToStr(maxBoxX - 17.0)+" "+FToStr(maxBoxY / 2.0 - 7.0)+" cm\n");
2383
 
                        PutPage(regCross);
2384
 
                        PutPage("Q\n");
2385
 
                }
2386
 
                if (Options.colorMarks)
2387
 
                {
2388
 
                        double startX = markOffs+bleedLeft+6.0;
2389
 
                        double startY = maxBoxY - 18.0;
2390
 
                        PutPage("0 0 0 1 K\n");
2391
 
                        double col = 1.0;
2392
 
                        for (int bl = 0; bl < 11; bl++)
2393
 
                        {
2394
 
                                PutPage("0 0 0 "+FToStr(col)+" k\n");
2395
 
                                PutPage(FToStr(startX+bl*14.0)+" "+FToStr(startY)+" 14 14 re B\n");
2396
 
                                col -= 0.1;
2397
 
                        }
2398
 
                        if (!Options.isGrayscale)
2399
 
                        {
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");
2403
 
                                startX -= 14.0;
2404
 
                                PutPage("0 0 0.5 0 k\n");
2405
 
                                PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2406
 
                                startX -= 14.0;
2407
 
                                PutPage("0 0.5 0 0 k\n");
2408
 
                                PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2409
 
                                startX -= 14.0;
2410
 
                                PutPage("0.5 0 0 0 k\n");
2411
 
                                PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2412
 
                                startX -= 14.0;
2413
 
                                PutPage("1 1 0 0 k\n");
2414
 
                                PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2415
 
                                startX -= 14.0;
2416
 
                                PutPage("1 0 1 0 k\n");
2417
 
                                PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2418
 
                                startX -= 14.0;
2419
 
                                PutPage("0 1 1 0 k\n");
2420
 
                                PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2421
 
                                startX -= 14.0;
2422
 
                                PutPage("0 0 0 1 k\n");
2423
 
                                PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2424
 
                                startX -= 14.0;
2425
 
                                PutPage("0 0 1 0 k\n");
2426
 
                                PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2427
 
                                startX -= 14.0;
2428
 
                                PutPage("0 1 0 0 k\n");
2429
 
                                PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2430
 
                                startX -= 14.0;
2431
 
                                PutPage("1 0 0 0 k\n");
2432
 
                                PutPage(FToStr(startX)+" "+FToStr(startY)+" 14 14 re B\n");
2433
 
                        }
2434
 
                }
2435
 
                if (Options.docInfoMarks)
2436
 
                {
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())
2445
 
                        {
2446
 
                                QFileInfo fi(doc.DocName);
2447
 
                                docTitle = fi.fileName();
2448
 
                        }
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");
2452
 
                        PutPage("q\n");
2453
 
                        PutPage("1 0 0 1 "+FToStr(startX)+" 6 cm\n");
2454
 
//                      PutPage("BT\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));
2460
 
                        PutPage("h\nf*\n");
2461
 
                        PutPage("Q\n");
2462
 
                        QDate d = QDate::currentDate();
2463
 
                        QString docDate = tr("Date:")+" "+d.toString(Qt::TextDate);
2464
 
                        PutPage("q\n");
2465
 
                        PutPage("1 0 0 1 "+FToStr(maxBoxX / 2.0 + 20.0)+" 6 cm\n");
2466
 
//                      PutPage("BT\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));
2473
 
                        PutPage("h\nf*\n");
2474
 
                        PutPage("Q\n");
2475
 
                }
2476
 
        }
2477
 
        Seite.ObjNum = WritePDFStream(Content);
2478
 
        int Gobj = 0;
2479
 
        if (Options.Version >= 14)
2480
 
        {
2481
 
                Gobj = newObject();
2482
 
                StartObj(Gobj);
2483
 
                PutDoc("<< /S /Transparency\n");
2484
 
                if (Options.UseRGB)
2485
 
                        PutDoc("/CS /DeviceRGB\n");
2486
 
                else
2487
 
                {
2488
 
                        if (Options.isGrayscale)
2489
 
                                PutDoc("/CS /DeviceGray\n");
2490
 
                        else
2491
 
                        {
2492
 
                                if ((doc.HasCMS) && (Options.UseProfiles))
2493
 
                                        PutDoc("/CS "+ICCProfiles[Options.SolidProf].ICCArray+"\n");
2494
 
                                else
2495
 
                                        PutDoc("/CS /DeviceCMYK\n");
2496
 
                        }
2497
 
                }
2498
 
                PutDoc(">>\nendobj\n");
2499
 
        }
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)
2516
 
        {
2517
 
                PutDoc("/Annots [ ");
2518
 
                for (int b = 0; b < Seite.AObjects.count(); ++b)
2519
 
                        PutDoc(QString::number(Seite.AObjects[b])+" 0 R ");
2520
 
                PutDoc("]\n");
2521
 
        }
2522
 
        if (Options.PresentMode)
2523
 
        {
2524
 
                if (Options.PresentVals[PgNr].pageViewDuration > 0)
2525
 
                        PutDoc("/Dur "+QString::number(Options.PresentVals[PgNr].pageViewDuration)+"\n");
2526
 
                if (Options.PresentVals[PgNr].effectType != 0)
2527
 
                {
2528
 
                        PutDoc("/Trans << /Type /Trans\n");
2529
 
                        PutDoc("/D "+QString::number(Options.PresentVals[PgNr].pageEffectDuration)+"\n");
2530
 
                        switch (Options.PresentVals[PgNr].effectType)
2531
 
                        {
2532
 
                                case 1:
2533
 
                                        PutDoc("/S /Blinds\n");
2534
 
                                        PutDoc(Options.PresentVals[PgNr].Dm == 0 ? "/Dm /H\n" : "/Dm /V\n");
2535
 
                                        break;
2536
 
                                case 2:
2537
 
                                        PutDoc("/S /Box\n");
2538
 
                                        PutDoc(Options.PresentVals[PgNr].M == 0 ? "/M /I\n" : "/M /O\n");
2539
 
                                        break;
2540
 
                                case 3:
2541
 
                                        PutDoc("/S /Dissolve\n");
2542
 
                                        break;
2543
 
                                case 4:
2544
 
                                        PutDoc("/S /Glitter\n");
2545
 
                                        PutDoc("/Di ");
2546
 
                                        switch (Options.PresentVals[PgNr].Di)
2547
 
                                        {
2548
 
                                                case 0:
2549
 
                                                        PutDoc("0");
2550
 
                                                        break;
2551
 
                                                case 1:
2552
 
                                                        PutDoc("270");
2553
 
                                                        break;
2554
 
                                                case 4:
2555
 
                                                        PutDoc("315");
2556
 
                                                        break;
2557
 
                                                default:
2558
 
                                                        PutDoc("0");
2559
 
                                                        break;
2560
 
                                        }
2561
 
                                        PutDoc("\n");
2562
 
                                        break;
2563
 
                                case 5:
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");
2567
 
                                        break;
2568
 
                                case 6:
2569
 
                                        PutDoc("/S /Wipe\n");
2570
 
                                        PutDoc("/Di ");
2571
 
                                        switch (Options.PresentVals[PgNr].Di)
2572
 
                                        {
2573
 
                                                case 0:
2574
 
                                                        PutDoc("0");
2575
 
                                                        break;
2576
 
                                                case 1:
2577
 
                                                        PutDoc("270");
2578
 
                                                        break;
2579
 
                                                case 2:
2580
 
                                                        PutDoc("90");
2581
 
                                                        break;
2582
 
                                                case 3:
2583
 
                                                        PutDoc("180");
2584
 
                                                        break;
2585
 
                                                default:
2586
 
                                                        PutDoc("0");
2587
 
                                                        break;
2588
 
                                        }
2589
 
                                        PutDoc("\n");
2590
 
                                        break;
2591
 
                                case 7:
2592
 
                                        PutDoc("/S /Push\n");
2593
 
                                        PutDoc("/Di ");
2594
 
                                        switch (Options.PresentVals[PgNr].Di)
2595
 
                                        {
2596
 
                                                case 0:
2597
 
                                                        PutDoc("0");
2598
 
                                                        break;
2599
 
                                                case 1:
2600
 
                                                        PutDoc("270");
2601
 
                                                        break;
2602
 
                                                case 2:
2603
 
                                                        PutDoc("90");
2604
 
                                                        break;
2605
 
                                                case 3:
2606
 
                                                        PutDoc("180");
2607
 
                                                        break;
2608
 
                                                default:
2609
 
                                                        PutDoc("0");
2610
 
                                                        break;
2611
 
                                        }
2612
 
                                        PutDoc("\n");
2613
 
                                        break;
2614
 
                                case 8:
2615
 
                                        PutDoc("/S /Cover\n");
2616
 
                                        PutDoc("/Di ");
2617
 
                                        switch (Options.PresentVals[PgNr].Di)
2618
 
                                        {
2619
 
                                                case 0:
2620
 
                                                        PutDoc("0");
2621
 
                                                        break;
2622
 
                                                case 1:
2623
 
                                                        PutDoc("270");
2624
 
                                                        break;
2625
 
                                                case 2:
2626
 
                                                        PutDoc("90");
2627
 
                                                        break;
2628
 
                                                case 3:
2629
 
                                                        PutDoc("180");
2630
 
                                                        break;
2631
 
                                                default:
2632
 
                                                        PutDoc("0");
2633
 
                                                        break;
2634
 
                                        }
2635
 
                                        PutDoc("\n");
2636
 
                                        break;
2637
 
                                case 9:
2638
 
                                        PutDoc("/S /Uncover\n");
2639
 
                                        PutDoc("/Di ");
2640
 
                                        switch (Options.PresentVals[PgNr].Di)
2641
 
                                        {
2642
 
                                                case 0:
2643
 
                                                        PutDoc("0");
2644
 
                                                        break;
2645
 
                                                case 1:
2646
 
                                                        PutDoc("270");
2647
 
                                                        break;
2648
 
                                                case 2:
2649
 
                                                        PutDoc("90");
2650
 
                                                        break;
2651
 
                                                case 3:
2652
 
                                                        PutDoc("180");
2653
 
                                                        break;
2654
 
                                                default:
2655
 
                                                        PutDoc("0");
2656
 
                                                        break;
2657
 
                                        }
2658
 
                                        PutDoc("\n");
2659
 
                                        break;
2660
 
                                case 10:
2661
 
                                        PutDoc("/S /Fade\n");
2662
 
                                        break;
2663
 
                        }
2664
 
                        PutDoc(">>\n");
2665
 
                }
2666
 
        }
2667
 
        PutDoc(">>\nendobj\n");
2668
 
        PageTree.Count++;
2669
 
        PageTree.Kids[physPage] = pageObject;
2670
 
}
2671
 
 
2672
 
 
2673
 
void PDFLibCore::writeXObject(uint objNr, QString dictionary, QByteArray stream)
2674
 
{
2675
 
        StartObj(objNr);
2676
 
        PutDoc("<<");
2677
 
        PutDoc(dictionary);
2678
 
        PutDoc(">>\nstream\n");
2679
 
        EncodeArrayToStream(stream, objNr);
2680
 
        PutDoc("\nendstream\nendobj\n");
2681
 
}
2682
 
 
2683
 
 
2684
 
uint PDFLibCore::writeObject(QString type, QString dictionary)
2685
 
{
2686
 
        uint result = newObject();
2687
 
        StartObj(result);
2688
 
        PutDoc("<<");
2689
 
        if (!type.isEmpty())
2690
 
                PutDoc("/Type " + type + "\n");
2691
 
        PutDoc(dictionary);
2692
 
        PutDoc(">>\nendobj\n");
2693
 
        return result;
2694
 
}
2695
 
 
2696
 
 
2697
 
bool PDFLibCore::PDF_ProcessPage(const Page* pag, uint PNr, bool clip)
2698
 
{
2699
 
        QStack<PageItem*> groupStack;
2700
 
        QStack<PageItem*> groupStackS;
2701
 
        QStack<QString>      groupDataStack;
2702
 
        QString tmp, output;
2703
 
        ActPageP = pag;
2704
 
        PageItem* ite;
2705
 
        QList<PageItem*> PItems;
2706
 
        int Lnr = 0;
2707
 
        ScLayer ll;
2708
 
        ll.isPrintable = false;
2709
 
        ll.LNr = 0;
2710
 
        if (Options.UseLPI)
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())
2722
 
        {*/
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;
2727
 
        /*}*/
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");
2732
 
        if (clip)
2733
 
        {
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");
2738
 
        }
2739
 
        if (!pag->MPageNam.isEmpty())
2740
 
        {
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)
2744
 
                {
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)
2748
 
                        {
2749
 
                                doc.Layers.levelToLayer(ll, Lnr);
2750
 
                                Lnr++;
2751
 
                                if ((ll.isPrintable) || ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers)))
2752
 
                                {
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)
2756
 
                                        {
2757
 
                                                ite = pag->FromMaster.at(am);
2758
 
                                                if (usingGUI)
2759
 
                                                        qApp->processEvents();
2760
 
                                                if ((ite->LayerNr != ll.LNr) || (!ite->printEnabled()))
2761
 
                                                        continue;
2762
 
                                                if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
2763
 
                                                        continue;
2764
 
                                                QString name = QString("/master_page_obj_%1_%2").arg(mPageIndex).arg(ite->ItemNr);
2765
 
                                                if (ite->isGroupControl)
2766
 
                                                {
2767
 
                                                        PutPage("q\n");
2768
 
                                                        FPointArray cl = ite->PoLine.copy();
2769
 
                                                        FPointArray clb = ite->PoLine.copy();
2770
 
                                                        QMatrix mm;
2771
 
                                                        mm.translate(ite->xPos() - mPage->xOffset(), (ite->yPos() - mPage->yOffset()) - mPage->height());
2772
 
                                                        mm.rotate(ite->rotation());
2773
 
                                                        cl.map( mm );
2774
 
                                                        ite->PoLine = cl;
2775
 
                                                        PutPage(SetClipPath(ite));
2776
 
                                                        PutPage("h W* n\n");
2777
 
                                                        groupStack.push(ite->groupsLastItem);
2778
 
                                                        ite->PoLine = clb.copy();
2779
 
                                                        continue;
2780
 
                                                }
2781
 
                                                if (! ite->asTextFrame())
2782
 
                                                        PutPage(name+" Do\n");
2783
 
                                                else
2784
 
                                                {
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()))
2792
 
                                                                return false;
2793
 
                                                        PutPage(output);
2794
 
                                                        ite->setXYPos(oldX, oldY, true);
2795
 
                                                        ite->BoundingX = OldBX;
2796
 
                                                        ite->BoundingY = OldBY;
2797
 
                                                }
2798
 
                                                if (groupStack.count() != 0)
2799
 
                                                {
2800
 
                                                        while (ite == groupStack.top())
2801
 
                                                        {
2802
 
                                                                PutPage("Q\n");
2803
 
                                                                groupStack.pop();
2804
 
                                                                if (groupStack.count() == 0)
2805
 
                                                                        break;
2806
 
                                                        }
2807
 
                                                }
2808
 
                                        }
2809
 
                                        for (int am = 0; am < pag->FromMaster.count(); ++am)
2810
 
                                        {
2811
 
                                                ite = pag->FromMaster.at(am);
2812
 
                                                if ((ite->LayerNr != ll.LNr) || (!ite->printEnabled()))
2813
 
                                                        continue;
2814
 
                                                if (ite->ChangedMasterItem)
2815
 
                                                        continue;
2816
 
                                                if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
2817
 
                                                        continue;
2818
 
                                                if (!ite->isTableItem)
2819
 
                                                        continue;
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;
2830
 
                                        }
2831
 
                                        if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
2832
 
                                                PutPage("EMC\n");
2833
 
                                }
2834
 
                        }
2835
 
                }
2836
 
        }
2837
 
        ll.isPrintable = false;
2838
 
        ll.LNr = 0;
2839
 
        Lnr = 0;
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)
2846
 
        {
2847
 
                doc.Layers.levelToLayer(ll, Lnr);
2848
 
                if ((ll.isPrintable) || ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers)))
2849
 
                {
2850
 
                        QString inh = "";
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)
2854
 
                        {
2855
 
                                if (usingGUI)
2856
 
                                {
2857
 
                                        progressDialog->setProgress("ECPI", ++pc_exportpagesitems);
2858
 
                                        qApp->processEvents();
2859
 
                                }
2860
 
                                ite = PItems.at(a);
2861
 
                                if (ite->LayerNr != ll.LNr)
2862
 
                                        continue;
2863
 
                                QString grcon = "";
2864
 
                                if (ite->isGroupControl)
2865
 
                                {
2866
 
                                        grcon += "q\n";
2867
 
                                        FPointArray cl = ite->PoLine.copy();
2868
 
                                        FPointArray clb = ite->PoLine.copy();
2869
 
                                        QMatrix mm;
2870
 
                                        mm.translate(ite->xPos() - pag->xOffset(), (ite->yPos() - pag->yOffset()) - pag->height());
2871
 
                                        mm.rotate(ite->rotation());
2872
 
                                        cl.map( mm );
2873
 
                                        ite->PoLine = cl;
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))
2879
 
                                        {
2880
 
                                                inh += grcon;
2881
 
                                                groupDataStack.push(inh);
2882
 
                                                inh = "";
2883
 
                                        }
2884
 
                                        else
2885
 
                                        {
2886
 
                                                PutPage(grcon);
2887
 
                                                groupDataStack.push(Content);
2888
 
                                                Content = "";
2889
 
                                        }
2890
 
                                        ite->PoLine = clb.copy();
2891
 
                                        continue;
2892
 
                                }
2893
 
                                if (!PDF_ProcessItem(output, ite, pag, PNr))
2894
 
                                        return false;
2895
 
                                if (((ll.transparency != 1) || (ll.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2896
 
                                        inh += output;
2897
 
                                else
2898
 
                                        PutPage(output);
2899
 
                                if (groupStack.count() != 0)
2900
 
                                {
2901
 
                                        while (ite == groupStack.top())
2902
 
                                        {
2903
 
                                                QString tmpData;
2904
 
                                                PageItem *controlItem = groupStackS.pop();
2905
 
                                                if (((ll.transparency != 1) || (ll.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2906
 
                                                {
2907
 
                                                        tmpData = inh;
2908
 
                                                        inh = groupDataStack.pop();
2909
 
                                                        if (Options.Version >= PDFOptions::PDFVersion_14)
2910
 
                                                                inh += Write_TransparencyGroup(controlItem->fillTransparency(), controlItem->fillBlendmode(), tmpData);
2911
 
                                                        else
2912
 
                                                                inh += tmpData;
2913
 
                                                        inh += "Q\n";
2914
 
                                                }
2915
 
                                                else
2916
 
                                                {
2917
 
                                                        tmpData = Content;
2918
 
                                                        Content = groupDataStack.pop();
2919
 
                                                        if (Options.Version >= PDFOptions::PDFVersion_14)
2920
 
                                                                Content += Write_TransparencyGroup(controlItem->fillTransparency(), controlItem->fillBlendmode(), tmpData);
2921
 
                                                        else
2922
 
                                                                Content += tmpData;
2923
 
                                                        PutPage("Q\n");
2924
 
                                                }
2925
 
                                                groupStack.pop();
2926
 
                                                if (groupStack.count() == 0)
2927
 
                                                        break;
2928
 
                                        }
2929
 
                                }
2930
 
                        }
2931
 
                        for (int a = 0; a < PItems.count() && !abortExport; ++a)
2932
 
                        {
2933
 
                                if (usingGUI)
2934
 
                                {
2935
 
                                        progressDialog->setProgress("ECPI", ++pc_exportpagesitems);
2936
 
                                        qApp->processEvents();
2937
 
                                }
2938
 
                                ite = PItems.at(a);
2939
 
                                if (ite->LayerNr != ll.LNr)
2940
 
                                        continue;
2941
 
                                if (!ite->isTableItem)
2942
 
                                        continue;
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 )))
2955
 
                                        continue;
2956
 
                                if (ite->ChangedMasterItem)
2957
 
                                        continue;
2958
 
                                if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
2959
 
                                        continue;
2960
 
                                if (!ite->printEnabled())
2961
 
                                        continue;
2962
 
                                if (((ll.transparency != 1) || (ll.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2963
 
                                        inh += PDF_ProcessTableItem(ite, pag);
2964
 
                                else
2965
 
                                        PutPage(PDF_ProcessTableItem(ite, pag));
2966
 
                        }
2967
 
                        if (((ll.transparency != 1) || (ll.blendMode != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
2968
 
                        {
2969
 
                                int Gobj = newObject();
2970
 
                                StartObj(Gobj);
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);
2977
 
                                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;
3000
 
                                PutPage("q\n");
3001
 
                                PutPage("/"+ShName+" gs\n");
3002
 
                                PutPage("/"+name+" Do\n");
3003
 
                                PutPage("Q\n");
3004
 
                        }
3005
 
                        if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
3006
 
                                PutPage("EMC\n");
3007
 
                }
3008
 
                Lnr++;
3009
 
        }
3010
 
        PutPage("Q\n"); // Restore
3011
 
        return true;
3012
 
}
3013
 
 
3014
 
QString PDFLibCore::Write_TransparencyGroup(double trans, int blend, QString &data)
3015
 
{
3016
 
        QString retString = "";
3017
 
        int Gobj = newObject();
3018
 
        StartObj(Gobj);
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);
3025
 
        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);
3047
 
        ResCount++;
3048
 
        Seite.XObjects[name] = formObject;
3049
 
        retString += "q\n";
3050
 
        retString += "/"+ShName+" gs\n";
3051
 
        retString += "/"+name+" Do\n";
3052
 
        retString += "Q\n";
3053
 
        return retString;
3054
 
}
3055
 
 
3056
 
QString PDFLibCore::PDF_ProcessTableItem(PageItem* ite, const Page* pag)
3057
 
{
3058
 
        if ((ite->lineColor() == CommonStrings::None) || (ite->lineWidth() == 0.0))
3059
 
                return "";
3060
 
        QString tmp("");
3061
 
        tmp += "q\n";
3062
 
        if ((ite->doOverprint) && (!Options.UseRGB))
3063
 
        {
3064
 
                QString ShName = ResNam+QString::number(ResCount);
3065
 
                ResCount++;
3066
 
                Transpar[ShName] = writeGState("/OP true\n"
3067
 
                                                                           "/op true\n"
3068
 
                                                                           "/OPM 1\n");
3069
 
                tmp += "/"+ShName+" gs\n";
3070
 
        }
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)
3081
 
        {
3082
 
                tmp += "[ ";
3083
 
                QVector<double>::iterator it;
3084
 
                for ( it = ite->DashValues.begin(); it != ite->DashValues.end(); ++it )
3085
 
                {
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)+" ";
3091
 
                }
3092
 
                tmp += "] "+QString::number(static_cast<int>(ite->DashOffset))+" d\n";
3093
 
        }
3094
 
        else
3095
 
                tmp += "["+getDashString(ite->PLineArt, ite->lineWidth())+"] 0 d\n";
3096
 
        tmp += "2 J\n";
3097
 
        switch (ite->PLineJoin)
3098
 
        {
3099
 
                case Qt::MiterJoin:
3100
 
                        tmp += "0 j\n";
3101
 
                        break;
3102
 
                case Qt::BevelJoin:
3103
 
                        tmp += "2 j\n";
3104
 
                        break;
3105
 
                case Qt::RoundJoin:
3106
 
                        tmp += "1 j\n";
3107
 
                        break;
3108
 
                default:
3109
 
                        tmp += "0 j\n";
3110
 
                        break;
3111
 
        }
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)
3114
 
        {
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)
3118
 
                        cr = 0;
3119
 
                if ((sr * sr) < 0.000001)
3120
 
                        sr = 0;
3121
 
                tmp += FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+ " 0 0 cm\n";
3122
 
        }
3123
 
        if ((ite->TopLine) || (ite->RightLine) || (ite->BottomLine) || (ite->LeftLine))
3124
 
        {
3125
 
                if (ite->TopLine)
3126
 
                {
3127
 
                        tmp += "0 0 m\n";
3128
 
                        tmp += FToStr(ite->width())+" 0 l\n";
3129
 
                }
3130
 
                if (ite->RightLine)
3131
 
                {
3132
 
                        tmp += FToStr(ite->width())+" 0 m\n";
3133
 
                        tmp += FToStr(ite->width())+" "+FToStr(-ite->height())+" l\n";
3134
 
                }
3135
 
                if (ite->BottomLine)
3136
 
                {
3137
 
                        tmp += "0 "+FToStr(-ite->height())+" m\n";
3138
 
                        tmp += FToStr(ite->width())+" "+FToStr(-ite->height())+" l\n";
3139
 
                }
3140
 
                if (ite->LeftLine)
3141
 
                {
3142
 
                        tmp += "0 0 m\n";
3143
 
                        tmp += "0 "+FToStr(-ite->height())+" l\n";
3144
 
                }
3145
 
                tmp += "S\n";
3146
 
        }
3147
 
        tmp += "Q\n";
3148
 
        return tmp;
3149
 
}
3150
 
 
3151
 
bool PDFLibCore::PDF_ProcessItem(QString& output, PageItem* ite, const Page* pag, uint PNr, bool embedded, bool pattern)
3152
 
{
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);
3166
 
        output.resize(0);
3167
 
        if (!pattern)
3168
 
        {
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)
3172
 
                {
3173
 
                        output = tmp;
3174
 
                        return true;
3175
 
                }
3176
 
//              qDebug() << "bb test done";
3177
 
                if (ite->ChangedMasterItem)
3178
 
                {
3179
 
                        output = tmp;
3180
 
                        return true;
3181
 
                }
3182
 
                if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
3183
 
                {
3184
 
                        output = tmp;
3185
 
                        return true;
3186
 
                }
3187
 
        }
3188
 
 
3189
 
        tmp += "q\n";
3190
 
        if ((ite->doOverprint) && (!Options.UseRGB))
3191
 
        {
3192
 
                QString ShName = ResNam+QString::number(ResCount);
3193
 
                ResCount++;
3194
 
                Transpar[ShName] = writeGState("/OP true\n"
3195
 
                                                                           "/op true\n"
3196
 
                                                                           "/OPM 1\n");
3197
 
                tmp += "/"+ShName+" gs\n";
3198
 
        }
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()));
3203
 
        if (!pattern)
3204
 
        {
3205
 
                if (!ite->printEnabled() || ((ite->itemType() == PageItem::TextFrame) && (!pag->pageName().isEmpty())))
3206
 
                {
3207
 
//                      qDebug() << "Q exit";
3208
 
                        tmp += "Q\n";
3209
 
                        output = tmp;
3210
 
                        return true;
3211
 
                }
3212
 
        }
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)
3219
 
        {
3220
 
                tmp += "[ ";
3221
 
                QVector<double>::iterator it;
3222
 
                for ( it = ite->DashValues.begin(); it != ite->DashValues.end(); ++it )
3223
 
                {
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)+" ";
3229
 
                }
3230
 
                tmp += "] "+QString::number(static_cast<int>(ite->DashOffset))+" d\n";
3231
 
        }
3232
 
        else
3233
 
                tmp += "["+getDashString(ite->PLineArt, ite->lineWidth())+"] 0 d\n";
3234
 
        switch (ite->PLineEnd)
3235
 
        {
3236
 
                case Qt::FlatCap:
3237
 
                        tmp += "0 J\n";
3238
 
                        break;
3239
 
                case Qt::SquareCap:
3240
 
                        tmp += "2 J\n";
3241
 
                        break;
3242
 
                case Qt::RoundCap:
3243
 
                        tmp += "1 J\n";
3244
 
                        break;
3245
 
                default:
3246
 
                        tmp += "0 J\n";
3247
 
                        break;
3248
 
        }
3249
 
        switch (ite->PLineJoin)
3250
 
        {
3251
 
                case Qt::MiterJoin:
3252
 
                        tmp += "0 j\n";
3253
 
                        break;
3254
 
                case Qt::BevelJoin:
3255
 
                        tmp += "2 j\n";
3256
 
                        break;
3257
 
                case Qt::RoundJoin:
3258
 
                        tmp += "1 j\n";
3259
 
                        break;
3260
 
                default:
3261
 
                        tmp += "0 j\n";
3262
 
                        break;
3263
 
        }
3264
 
        if (!embedded)
3265
 
        {
3266
 
                tmp += "1 0 0 1 "+FToStr(ite->xPos() - pag->xOffset())+" "+FToStr(pag->height() - (ite->yPos()  - pag->yOffset()))+" cm\n";
3267
 
        }
3268
 
        if (ite->rotation() != 0)
3269
 
        {
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)
3273
 
                        cr = 0;
3274
 
                if ((sr * sr) < 0.000001)
3275
 
                        sr = 0;
3276
 
                tmp += FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+" 0 0 cm\n";
3277
 
        }
3278
 
        switch (ite->itemType())
3279
 
        {
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))
3286
 
                        {
3287
 
                                if (ite->GrType != 0)
3288
 
                                {
3289
 
                                        if (!PDF_Gradient(tmpOut, ite))
3290
 
                                                return false;
3291
 
                                        tmp += tmpOut;
3292
 
                                }
3293
 
                                else
3294
 
                                {
3295
 
                                        tmp += SetClipPath(ite);
3296
 
                                        tmp += "h\nf*\n";
3297
 
                                }
3298
 
                        }
3299
 
                        tmp += "q\n";
3300
 
                        if (ite->imageClip.size() != 0)
3301
 
                        {
3302
 
                                tmp += SetClipPathImage(ite);
3303
 
                                tmp += "h\nW*\nn\n";
3304
 
                        }
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()))
3312
 
                        {
3313
 
                                if (!PDF_Image(ite, ite->Pfile, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), false, ite->IProfile, ite->UseEmbedded, ite->IRender, &tmpOut))
3314
 
                                        return false;
3315
 
                                tmp += tmpOut;
3316
 
                        }
3317
 
                        tmp += "Q\n";
3318
 
                        if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
3319
 
                        {
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))
3323
 
                                {
3324
 
                                        if (ite->lineColor() != CommonStrings::None)
3325
 
                                        {
3326
 
                                                tmp += SetClipPath(ite);
3327
 
                                                tmp += "h\nS\n";
3328
 
                                        }
3329
 
                                }
3330
 
                                else
3331
 
                                {
3332
 
                                        multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3333
 
                                        for (int it = ml.size()-1; it > -1; it--)
3334
 
                                        {
3335
 
                                                if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3336
 
                                                {
3337
 
                                                        tmp += setStrokeMulti(&ml[it]);
3338
 
                                                        tmp += SetClipPath(ite);
3339
 
                                                        tmp += "h\nS\n";
3340
 
                                                }
3341
 
                                        }
3342
 
                                }
3343
 
                        }
3344
 
                        break;
3345
 
                case PageItem::TextFrame:
3346
 
//                      qDebug() << "case TextFrame";
3347
 
                        if ((ite->isAnnotation()) && (Options.Version != PDFOptions::PDFVersion_X3))
3348
 
                        {
3349
 
//                              qDebug() << "Annotation";
3350
 
                                if (!PDF_Annotation(ite, PNr))
3351
 
                                        return false;
3352
 
                                break;
3353
 
                        }
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))
3357
 
                        {
3358
 
                                if (ite->GrType != 0)
3359
 
                                {
3360
 
                                        if (!PDF_Gradient(tmpOut, ite))
3361
 
                                                return false;
3362
 
                                        tmp += tmpOut;
3363
 
                                }
3364
 
                                else
3365
 
                                {
3366
 
                                        tmp += SetClipPath(ite);
3367
 
                                        tmp += "h\nf*\n";
3368
 
                                }
3369
 
                        }
3370
 
                        tmp += "q\n";
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);
3376
 
                        tmp += "Q\n";
3377
 
                        if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
3378
 
                        {
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))
3382
 
                                {
3383
 
                                        if (ite->lineColor() != CommonStrings::None)
3384
 
                                        {
3385
 
                                                tmp += SetClipPath(ite);
3386
 
                                                tmp += "h\nS\n";
3387
 
                                        }
3388
 
                                }
3389
 
                                else
3390
 
                                {
3391
 
                                        multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3392
 
                                        for (int it = ml.size()-1; it > -1; it--)
3393
 
                                        {
3394
 
                                                if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3395
 
                                                {
3396
 
                                                        tmp += setStrokeMulti(&ml[it]);
3397
 
                                                        tmp += SetClipPath(ite);
3398
 
                                                        tmp += "h\nS\n";
3399
 
                                                }
3400
 
                                        }
3401
 
                                }
3402
 
                        }
3403
 
                        break;
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())
3408
 
                        {
3409
 
                                if (ite->lineColor() != CommonStrings::None)
3410
 
                                {
3411
 
                                        tmp += "0 0 m\n";
3412
 
                                        tmp += FToStr(ite->width())+" 0 l\n";
3413
 
                                        tmp += "S\n";
3414
 
                                }
3415
 
                        }
3416
 
                        else
3417
 
                        {
3418
 
                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3419
 
                                for (int it = ml.size()-1; it > -1; it--)
3420
 
                                {
3421
 
                                        if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3422
 
                                        {
3423
 
                                                tmp += setStrokeMulti(&ml[it]);
3424
 
                                                tmp += "0 0 m\n";
3425
 
                                                tmp += FToStr(ite->width())+" 0 l\n";
3426
 
                                                tmp += "S\n";
3427
 
                                        }
3428
 
                                }
3429
 
                        }
3430
 
                        if (ite->startArrowIndex() != 0)
3431
 
                        {
3432
 
                                QMatrix arrowTrans;
3433
 
                                arrowTrans.scale(-1,1);
3434
 
                                tmp += drawArrow(ite, arrowTrans, ite->startArrowIndex());
3435
 
                        }
3436
 
                        if (ite->endArrowIndex() != 0)
3437
 
                        {
3438
 
                                QMatrix arrowTrans;
3439
 
                                arrowTrans.translate(ite->width(), 0);
3440
 
                                tmp += drawArrow(ite, arrowTrans, ite->endArrowIndex());
3441
 
                        }
3442
 
                        break;
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)
3449
 
                        {
3450
 
                                if (!PDF_Gradient(tmpOut, ite))
3451
 
                                        return false;
3452
 
                                tmp += tmpOut;
3453
 
                        }
3454
 
                        else
3455
 
                        {
3456
 
                                if (ite->fillColor() != CommonStrings::None)
3457
 
                                {
3458
 
                                        tmp += SetClipPath(ite);
3459
 
                                        if (ite->fillRule)
3460
 
                                                tmp += "h\nf*\n";
3461
 
                                        else
3462
 
                                                tmp += "h\nf\n";
3463
 
                                }
3464
 
                        }
3465
 
                        if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3466
 
                        {
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))
3470
 
                                {
3471
 
                                        if (ite->lineColor() != CommonStrings::None)
3472
 
                                        {
3473
 
                                                tmp += SetClipPath(ite);
3474
 
                                                tmp += "h\nS\n";
3475
 
                                        }
3476
 
                                }
3477
 
                                else
3478
 
                                {
3479
 
                                        multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3480
 
                                        for (int it = ml.size()-1; it > -1; it--)
3481
 
                                        {
3482
 
                                                if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3483
 
                                                {
3484
 
                                                        tmp += setStrokeMulti(&ml[it]);
3485
 
                                                        tmp += SetClipPath(ite);
3486
 
                                                        tmp += "h\nS\n";
3487
 
                                                }
3488
 
                                        }
3489
 
                                }
3490
 
                        }
3491
 
                        break;
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))))
3494
 
                        {
3495
 
                                if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3496
 
                                        tmp += PDF_TransparenzFill(ite);
3497
 
                                if (ite->GrType != 0)
3498
 
                                {
3499
 
                                        if (!PDF_Gradient(tmpOut, ite))
3500
 
                                                return false;
3501
 
                                        tmp += tmpOut;
3502
 
                                }
3503
 
                                else
3504
 
                                {
3505
 
                                        if (ite->fillColor() != CommonStrings::None)
3506
 
                                        {
3507
 
                                                tmp += SetClipPath(ite);
3508
 
                                                tmp += "h\nf*\n";
3509
 
                                        }
3510
 
                                }
3511
 
                        }
3512
 
                        if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3513
 
                        {
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))
3517
 
                                {
3518
 
                                        if (ite->lineColor() != CommonStrings::None)
3519
 
                                        {
3520
 
                                                tmp += SetClipPath(ite, false);
3521
 
                                                tmp += "S\n";
3522
 
                                        }
3523
 
                                }
3524
 
                                else
3525
 
                                {
3526
 
                                        multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3527
 
                                        for (int it = ml.size()-1; it > -1; it--)
3528
 
                                        {
3529
 
                                                if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3530
 
                                                {
3531
 
                                                        tmp += setStrokeMulti(&ml[it]);
3532
 
                                                        tmp += SetClipPath(ite, false);
3533
 
                                                        tmp += "S\n";
3534
 
                                                }
3535
 
                                        }
3536
 
                                }
3537
 
                        }
3538
 
                        if (ite->startArrowIndex() != 0)
3539
 
                        {
3540
 
                                FPoint Start = ite->PoLine.point(0);
3541
 
                                for (uint xx = 1; xx < ite->PoLine.size(); xx += 2)
3542
 
                                {
3543
 
                                        FPoint Vector = ite->PoLine.point(xx);
3544
 
                                        if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
3545
 
                                        {
3546
 
                                                double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
3547
 
                                                QMatrix arrowTrans;
3548
 
                                                arrowTrans.translate(Start.x(), Start.y());
3549
 
                                                arrowTrans.rotate(r);
3550
 
                                                tmp += drawArrow(ite, arrowTrans, ite->startArrowIndex());
3551
 
                                                break;
3552
 
                                        }
3553
 
                                }
3554
 
                        }
3555
 
                        if (ite->endArrowIndex() != 0)
3556
 
                        {
3557
 
                                FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
3558
 
                                for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
3559
 
                                {
3560
 
                                        FPoint Vector = ite->PoLine.point(xx);
3561
 
                                        if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
3562
 
                                        {
3563
 
                                                double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
3564
 
                                                QMatrix arrowTrans;
3565
 
                                                arrowTrans.translate(End.x(), End.y());
3566
 
                                                arrowTrans.rotate(r);
3567
 
                                                tmp += drawArrow(ite, arrowTrans, ite->endArrowIndex());
3568
 
                                                break;
3569
 
                                        }
3570
 
                                }
3571
 
                        }
3572
 
                        break;
3573
 
                case PageItem::PathText:
3574
 
                        if (ite->PoShow)
3575
 
                        {
3576
 
                                if (ite->PoLine.size() > 3)
3577
 
                                {
3578
 
                                        tmp += "q\n";
3579
 
                                        if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3580
 
                                        {
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))
3584
 
                                                {
3585
 
                                                        if (ite->lineColor() != CommonStrings::None)
3586
 
                                                        {
3587
 
                                                                tmp += SetClipPath(ite, false);
3588
 
                                                                tmp += "S\n";
3589
 
                                                        }
3590
 
                                                }
3591
 
                                                else
3592
 
                                                {
3593
 
                                                        multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3594
 
                                                        for (int it = ml.size()-1; it > -1; it--)
3595
 
                                                        {
3596
 
                                                                if (ml[it].Color != CommonStrings::None) //&& (ml[it].Width != 0))
3597
 
                                                                {
3598
 
                                                                        tmp += setStrokeMulti(&ml[it]);
3599
 
                                                                        tmp += SetClipPath(ite, false);
3600
 
                                                                        tmp += "S\n";
3601
 
                                                                }
3602
 
                                                        }
3603
 
                                                }
3604
 
                                        }
3605
 
                                        tmp += "Q\n";
3606
 
                                }
3607
 
                        }
3608
 
                        if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= PDFOptions::PDFVersion_14))
3609
 
                                tmp += PDF_TransparenzFill(ite);
3610
 
                        tmp += setTextSt(ite, PNr, pag);
3611
 
                        break;
3612
 
                case PageItem::Multiple:
3613
 
                        Q_ASSERT(false);
3614
 
                        break;
3615
 
        }
3616
 
        tmp += "Q\n";
3617
 
        output = tmp;
3618
 
        return true;
3619
 
}
3620
 
 
3621
 
QString PDFLibCore::drawArrow(PageItem *ite, QMatrix &arrowTrans, int arrowIndex)
3622
 
{
3623
 
        QString tmp = "";
3624
 
        FPointArray arrow = doc.arrowStyles.at(arrowIndex-1).points.copy();
3625
 
        if (ite->NamedLStyle.isEmpty())
3626
 
        {
3627
 
                if (ite->lineWidth() != 0.0)
3628
 
                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3629
 
        }
3630
 
        else
3631
 
        {
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);
3635
 
        }
3636
 
        arrow.map(arrowTrans);
3637
 
        if ((ite->lineTransparency() != 0) && (Options.Version >= PDFOptions::PDFVersion_14))
3638
 
        {
3639
 
                QString ShName = ResNam+QString::number(ResCount);
3640
 
                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"
3644
 
                                                                           + "/BM /Normal\n");
3645
 
                tmp += "/"+ShName+" gs\n";
3646
 
        }
3647
 
        if (ite->NamedLStyle.isEmpty())
3648
 
        {
3649
 
                if (ite->lineColor() != CommonStrings::None)
3650
 
                {
3651
 
                        tmp += putColor(ite->lineColor(), ite->lineShade(), true);
3652
 
                        tmp += SetClipPathArray(&arrow);
3653
 
                        tmp += "h\nf*\n";
3654
 
                }
3655
 
        }
3656
 
        else
3657
 
        {
3658
 
                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3659
 
                if (ml[0].Color != CommonStrings::None)
3660
 
                {
3661
 
                        tmp += putColor(ml[0].Color, ml[0].Shade, true);
3662
 
                        tmp += SetClipPathArray(&arrow);
3663
 
                        tmp += "h\nf*\n";
3664
 
                }
3665
 
                for (int it = ml.size()-1; it > 0; it--)
3666
 
                {
3667
 
                        if (ml[it].Color != CommonStrings::None)
3668
 
                        {
3669
 
                                tmp += setStrokeMulti(&ml[it]);
3670
 
                                tmp += SetClipPathArray(&arrow);
3671
 
                                tmp += "h\nS\n";
3672
 
                        }
3673
 
                }
3674
 
        }
3675
 
        return tmp;
3676
 
}
3677
 
 
3678
 
QString PDFLibCore::putColor(const QString& color, double shade, bool fill)
3679
 
{
3680
 
        QString tmp = "";
3681
 
        QString colString = SetColor(color, shade);
3682
 
        ScColor tmpC;
3683
 
        tmpC = doc.PageColors[color];
3684
 
        if (((tmpC.isSpotColor()) || (tmpC.isRegistrationColor())) && ((Options.isGrayscale == false) && (Options.UseRGB == false))  && (Options.UseSpotColors))
3685
 
        {
3686
 
                if ((color != CommonStrings::None) && (spotMap.contains(color)))
3687
 
                {
3688
 
                        if (fill)
3689
 
                        {
3690
 
                                tmp += "/"+spotMap[color].ResName+" cs\n";
3691
 
                                tmp += FToStr(shade / 100.0)+" scn\n";
3692
 
                        }
3693
 
                        else
3694
 
                        {
3695
 
                                tmp += "/"+spotMap[color].ResName+" CS\n";
3696
 
                                tmp += FToStr(shade / 100.0)+" SCN\n";
3697
 
                        }
3698
 
                }
3699
 
                return tmp;
3700
 
        }
3701
 
        if (Options.isGrayscale)
3702
 
        {
3703
 
                if (color != CommonStrings::None)
3704
 
                {
3705
 
                        if (fill)
3706
 
                                tmp += colString+" g\n";
3707
 
                        else
3708
 
                                tmp += colString+" G\n";
3709
 
                }
3710
 
                return tmp;
3711
 
        }
3712
 
        if (Options.UseRGB)
3713
 
        {
3714
 
                if (color != CommonStrings::None)
3715
 
                {
3716
 
                        if (fill)
3717
 
                                tmp += colString+" rg\n";
3718
 
                        else
3719
 
                                tmp += colString+" RG\n";
3720
 
                }
3721
 
        }
3722
 
        else
3723
 
        {
3724
 
                if ((doc.HasCMS) && (Options.UseProfiles))
3725
 
                {
3726
 
                        if (tmpC.getColorModel() == colorModelCMYK)
3727
 
                        {
3728
 
                                if (color != CommonStrings::None)
3729
 
                                {
3730
 
                                        if (fill)
3731
 
                                                tmp += colString+" k\n";
3732
 
                                        else
3733
 
                                                tmp += colString+" K\n";
3734
 
                                }
3735
 
                        }
3736
 
                        else
3737
 
                        {
3738
 
                                QString tmp2[] = {"/Perceptual", "/RelativeColorimetric", "/Saturation", "/AbsoluteColorimetric"};
3739
 
                                tmp += tmp2[Options.Intent]+ " ri\n";
3740
 
                                if (color != CommonStrings::None)
3741
 
                                {
3742
 
                                        if (fill)
3743
 
                                        {
3744
 
                                                tmp += "/"+ICCProfiles[Options.SolidProf].ResName+" cs\n";
3745
 
                                                tmp += colString+" scn\n";
3746
 
                                        }
3747
 
                                        else
3748
 
                                        {
3749
 
                                                tmp += "/"+ICCProfiles[Options.SolidProf].ResName+" CS\n";
3750
 
                                                tmp += colString+" SCN\n";
3751
 
                                        }
3752
 
                                }
3753
 
                        }
3754
 
                }
3755
 
                else
3756
 
                {
3757
 
                        if (color != CommonStrings::None)
3758
 
                        {
3759
 
                                if (fill)
3760
 
                                        tmp += colString+" k\n";
3761
 
                                else
3762
 
                                        tmp += colString+" K\n";
3763
 
                        }
3764
 
                }
3765
 
        }
3766
 
        return tmp;
3767
 
}
3768
 
 
3769
 
/*CB 2982: cache code is borked somehow, original function is above
3770
 
QString PDFLibCore::putColor(const QString & colorName, int shade, bool fill)
3771
 
{
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
3783
 
        else if (fill)
3784
 
        {
3785
 
                lastBGColorName = colorName;
3786
 
                lastBGShade = shade;
3787
 
                lastBGOutput = putColorUncached(colorName, shade, fill);
3788
 
                return lastBGOutput;
3789
 
        }
3790
 
        else
3791
 
        {
3792
 
                lastFGColorName = colorName;
3793
 
                lastFGShade = shade;
3794
 
                lastFGOutput = putColorUncached(colorName, shade, fill);
3795
 
                return lastFGOutput;
3796
 
        }
3797
 
}
3798
 
*/
3799
 
 
3800
 
QString PDFLibCore::putColorUncached(const QString& color, int shade, bool fill)
3801
 
{
3802
 
        ScColor tmpC(doc.PageColors[color]);
3803
 
        if (((tmpC.isSpotColor()) || (tmpC.isRegistrationColor())) && ((Options.isGrayscale == false) && (Options.UseRGB == false))  && (Options.UseSpotColors))
3804
 
        {
3805
 
                QString tmpSpot("");
3806
 
                if ((color != CommonStrings::None) && (spotMap.contains(color)))
3807
 
                {
3808
 
                        if (fill)
3809
 
                        {
3810
 
                                tmpSpot += "/"+spotMap[color].ResName+" cs\n";
3811
 
                                tmpSpot += FToStr(shade / 100.0)+" scn\n";
3812
 
                        }
3813
 
                        else
3814
 
                        {
3815
 
                                tmpSpot += "/"+spotMap[color].ResName+" CS\n";
3816
 
                                tmpSpot += FToStr(shade / 100.0)+" SCN\n";
3817
 
                        }
3818
 
                }
3819
 
                return tmpSpot;
3820
 
        }
3821
 
        QString colString(SetColor(color, shade));
3822
 
        if (Options.isGrayscale)
3823
 
        {
3824
 
                QString tmpGray("");
3825
 
                if (color != CommonStrings::None)
3826
 
                {
3827
 
                        if (fill)
3828
 
                                tmpGray += colString+" g\n";
3829
 
                        else
3830
 
                                tmpGray += colString+" G\n";
3831
 
                }
3832
 
                return tmpGray;
3833
 
        }
3834
 
        QString tmp("");
3835
 
        if (Options.UseRGB)
3836
 
        {
3837
 
                if (color != CommonStrings::None)
3838
 
                {
3839
 
                        if (fill)
3840
 
                                tmp += colString+" rg\n";
3841
 
                        else
3842
 
                                tmp += colString+" RG\n";
3843
 
                }
3844
 
        }
3845
 
        else
3846
 
        {
3847
 
                if ((doc.HasCMS) && (Options.UseProfiles))
3848
 
                {
3849
 
                        if (tmpC.getColorModel() == colorModelCMYK)
3850
 
                        {
3851
 
                                if (color != CommonStrings::None)
3852
 
                                {
3853
 
                                        if (fill)
3854
 
                                                tmp += colString+" k\n";
3855
 
                                        else
3856
 
                                                tmp += colString+" K\n";
3857
 
                                }
3858
 
                        }
3859
 
                        else
3860
 
                        {
3861
 
                                QString tmp2[] = {"/Perceptual", "/RelativeColorimetric", "/Saturation", "/AbsoluteColorimetric"};
3862
 
                                tmp += tmp2[Options.Intent]+ " ri\n";
3863
 
                                if (color != CommonStrings::None)
3864
 
                                {
3865
 
                                        if (fill)
3866
 
                                        {
3867
 
                                                tmp += "/"+ICCProfiles[Options.SolidProf].ResName+" cs\n";
3868
 
                                                tmp += colString+" scn\n";
3869
 
                                        }
3870
 
                                        else
3871
 
                                        {
3872
 
                                                tmp += "/"+ICCProfiles[Options.SolidProf].ResName+" CS\n";
3873
 
                                                tmp += colString+" SCN\n";
3874
 
                                        }
3875
 
                                }
3876
 
                        }
3877
 
                }
3878
 
                else
3879
 
                {
3880
 
                        if (color != CommonStrings::None)
3881
 
                        {
3882
 
                                if (fill)
3883
 
                                        tmp += colString+" k\n";
3884
 
                                else
3885
 
                                        tmp += colString+" K\n";
3886
 
                        }
3887
 
                }
3888
 
        }
3889
 
        return tmp;
3890
 
}
3891
 
 
3892
 
QString PDFLibCore::setStrokeMulti(struct SingleLine *sl)
3893
 
{
3894
 
        QString tmp(
3895
 
                        putColor(sl->Color, sl->Shade, false) +
3896
 
                        FToStr(sl->Width)+" w\n"
3897
 
                        );
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))
3902
 
        {
3903
 
                case Qt::SolidLine:
3904
 
                        tmp += "[] 0 d\n";
3905
 
                        break;
3906
 
                case Qt::DashLine:
3907
 
                        tmp += "["+Da+" "+Sp+"] 0 d\n";
3908
 
                        break;
3909
 
                case Qt::DotLine:
3910
 
                        tmp += "["+Dt+" "+Sp+"] 0 d\n";
3911
 
                        break;
3912
 
                case Qt::DashDotLine:
3913
 
                        tmp += "["+Da+" "+Sp+" "+Dt+" "+Sp+"] 0 d\n";
3914
 
                        break;
3915
 
                case Qt::DashDotDotLine:
3916
 
                        tmp += "["+Da+" "+Sp+" "+Dt+" "+Sp+" "+Dt+" "+Sp+"] 0 d\n";
3917
 
                        break;
3918
 
                default:
3919
 
                        tmp += "[] 0 d\n";
3920
 
                        break;
3921
 
                }
3922
 
        switch (static_cast<Qt::PenCapStyle>(sl->LineEnd))
3923
 
        {
3924
 
                case Qt::FlatCap:
3925
 
                        tmp += "0 J\n";
3926
 
                        break;
3927
 
                case Qt::SquareCap:
3928
 
                        tmp += "2 J\n";
3929
 
                        break;
3930
 
                case Qt::RoundCap:
3931
 
                        tmp += "1 J\n";
3932
 
                        break;
3933
 
                default:
3934
 
                        tmp += "0 J\n";
3935
 
                        break;
3936
 
        }
3937
 
        switch (static_cast<Qt::PenJoinStyle>(sl->LineJoin))
3938
 
        {
3939
 
                case Qt::MiterJoin:
3940
 
                        tmp += "0 j\n";
3941
 
                        break;
3942
 
                case Qt::BevelJoin:
3943
 
                        tmp += "2 j\n";
3944
 
                        break;
3945
 
                case Qt::RoundJoin:
3946
 
                        tmp += "1 j\n";
3947
 
                        break;
3948
 
                default:
3949
 
                        tmp += "0 j\n";
3950
 
                        break;
3951
 
        }
3952
 
        return tmp;
3953
 
}
3954
 
 
3955
 
// Return a PDF substring representing a PageItem's text
3956
 
QString PDFLibCore::setTextSt(PageItem *ite, uint PNr, const Page* pag)
3957
 
{
3958
 
        int tabCc = 0;
3959
 
        int savedOwnPage = ite->OwnPage;
3960
 
        double tabDist = ite->textToFrameDistLeft();
3961
 
        double colLeft = 0.0;
3962
 
        QString tmp(""), tmp2("");
3963
 
        QList<ParagraphStyle::TabRecord> tTabValues;
3964
 
        ite->OwnPage = PNr;
3965
 
        ite->layout();
3966
 
        ite->OwnPage = savedOwnPage;
3967
 
        if (ite->lineColor() != CommonStrings::None)
3968
 
                tabDist += ite->lineWidth() / 2.0;
3969
 
#ifndef NLS_PROTO
3970
 
        // Loop over each character (!) in the pageItem...
3971
 
        if (ite->itemType() == PageItem::TextFrame)
3972
 
        {
3973
 
                tmp += "BT\n";
3974
 
                for (uint ll=0; ll < ite->itemText.lines(); ++ll)
3975
 
                {
3976
 
                        LineSpec ls = ite->itemText.line(ll);
3977
 
                        colLeft = ls.colLeft;
3978
 
                        tabDist = ls.x;
3979
 
                        double CurX = ls.x;
3980
 
                        for (int d = ls.firstItem; d <= ls.lastItem; ++d)
3981
 
                        {
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))
3987
 
                                        continue;
3988
 
                                if (chstyle.effects() & ScStyle_SuppressSpace)
3989
 
                                        continue;
3990
 
                                tTabValues = pstyle.tabValues();
3991
 
                                if (chstyle.effects() & ScStyle_StartOfLine)
3992
 
                                        tabCc = 0;
3993
 
                                if ((ch == SpecialChars::TAB) && (tTabValues.count() != 0))
3994
 
                                {
3995
 
                                        QChar tabFillChar;
3996
 
                                        const TabLayout* tabLayout = dynamic_cast<const TabLayout*>(hl->glyph.more);
3997
 
                                        if (tabLayout)
3998
 
                                                tabFillChar = tabLayout->fillChar;
3999
 
                                        if (!tabFillChar.isNull())
4000
 
                                        {
4001
 
                                                ScText hl2;
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;
4011
 
                                                hl2.setTracking(0);
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)
4017
 
                                                {
4018
 
                                                        hl2.glyph.xoffset =  sPos + wt * cx;
4019
 
                                                        if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
4020
 
                                                        {
4021
 
                                                                ScText hl3;
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));
4026
 
                                                                hl3.ch = hl2.ch;
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);
4033
 
                                                        }
4034
 
                                                        setTextCh(ite, PNr, CurX, ls.y, d, tmp, tmp2, &hl2, pstyle, pag);
4035
 
                                                }
4036
 
                                        }
4037
 
                                        tabCc++;
4038
 
                                }
4039
 
                                if (ch == SpecialChars::TAB) 
4040
 
                                {
4041
 
                                        CurX += hl->glyph.wide();
4042
 
                                        continue;
4043
 
                                }
4044
 
                                if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
4045
 
                                {
4046
 
                                        ScText hl2;
4047
 
                                        hl2.ch = ch;
4048
 
                                        hl2.glyph.glyph = hl->glyph.glyph;
4049
 
                                        const GlyphLayout *gl1 = &hl->glyph;
4050
 
                                        GlyphLayout     *gl2 = &hl2.glyph;
4051
 
                                        while (gl1->more)
4052
 
                                        {
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;
4057
 
                                                gl1 = gl1->more;
4058
 
                                                gl2 = gl2->more;
4059
 
                                        }
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);
4073
 
                                }
4074
 
                                setTextCh(ite, PNr, CurX, ls.y, d, tmp, tmp2, hl, pstyle, pag);
4075
 
                                if (hl->ch == SpecialChars::OBJECT)
4076
 
                                {
4077
 
                                        InlineFrame& embedded(const_cast<InlineFrame&>(hl->embedded));
4078
 
                                        CurX += (embedded.getItem()->gWidth + embedded.getItem()->lineWidth()) * hl->glyph.scaleH;
4079
 
                                }
4080
 
                                else
4081
 
                                        CurX += hl->glyph.wide();
4082
 
                                tabDist = CurX;
4083
 
                        }
4084
 
                }
4085
 
        }
4086
 
        else
4087
 
        {
4088
 
                double CurX = 0;
4089
 
                for (int d = ite->firstInFrame(); d <= ite->lastInFrame(); ++d)
4090
 
                {
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))
4096
 
                                continue;
4097
 
                        if (chstyle.effects() & ScStyle_SuppressSpace)
4098
 
                                continue;
4099
 
                        tTabValues = pstyle.tabValues();
4100
 
                        if (chstyle.effects() & ScStyle_StartOfLine)
4101
 
                                tabCc = 0;
4102
 
                        if ((ch == SpecialChars::TAB) && (tTabValues.count() != 0))
4103
 
                        {
4104
 
                                if ((tabCc < tTabValues.count()) && (!tTabValues[tabCc].tabFillChar.isNull()))
4105
 
                                {
4106
 
                                        ScText hl2;
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;
4113
 
                                        hl2.setTracking(0);
4114
 
                                        hl2.setScaleH(1000);
4115
 
                                        hl2.setScaleV(1000);
4116
 
                                        hl2.glyph.yoffset = hl->glyph.yoffset;
4117
 
                                        for (int cx = 0; cx < coun; ++cx)
4118
 
                                        {
4119
 
                                                hl2.glyph.xoffset =  sPos + wt * cx;
4120
 
                                                if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
4121
 
                                                {
4122
 
                                                        ScText hl3;
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));
4127
 
                                                        hl3.ch = hl2.ch;
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);
4134
 
                                                }
4135
 
                                                setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, &hl2, pstyle, pag);
4136
 
                                        }
4137
 
                                        tabCc++;
4138
 
                                }
4139
 
                                else
4140
 
                                {
4141
 
                                        tabCc++;
4142
 
                                }
4143
 
                        }
4144
 
                        if (ch == SpecialChars::TAB) 
4145
 
                        {
4146
 
                                CurX += hl->glyph.wide();
4147
 
                                continue;
4148
 
                        }
4149
 
                        if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
4150
 
                        {
4151
 
                                ScText hl2;
4152
 
                                hl2.ch = ch;
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;
4167
 
                                hl2.PDx = hl->PDx;
4168
 
                                setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, &hl2, pstyle, pag);
4169
 
                        }
4170
 
                        setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, hl, pstyle, pag);
4171
 
                        CurX += hl->glyph.wide();
4172
 
                        tabDist = CurX;
4173
 
                }
4174
 
        }
4175
 
#endif
4176
 
        if (ite->itemType() == PageItem::TextFrame)
4177
 
                tmp += "ET\n"+tmp2;
4178
 
        return tmp;
4179
 
}
4180
 
 
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)
4182
 
{
4183
 
#ifndef NLS_PROTO
4184
 
        QString output;
4185
 
        QString FillColor = "";
4186
 
        QString StrokeColor = "";
4187
 
        if (ite->asPathText())
4188
 
        {
4189
 
                tmp += "q\n";
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)
4199
 
                {
4200
 
                        double a = 1;
4201
 
                        double b = -1;
4202
 
                        if (tangt.x() < 0)
4203
 
                        {
4204
 
                                a = -1;
4205
 
                                b = 1;
4206
 
                        }
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
4209
 
                        else
4210
 
                                trafo *= QMatrix( a, 6 * b, 0, -1, hl->PtransX, -hl->PtransY );
4211
 
                }
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)
4218
 
                        tmp += "BT\n";
4219
 
        }
4220
 
        double tsz = hl->fontSize();
4221
 
        QChar chstr = hl->ch;
4222
 
        const CharStyle& style(*hl);
4223
 
        
4224
 
/*      if (hl->effects() & ScStyle_DropCap)
4225
 
        {
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))));
4228
 
                else
4229
 
                {
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))));
4232
 
                        else
4233
 
                        {
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)));
4236
 
                        }
4237
 
                }
4238
 
        }
4239
 
        */
4240
 
        InlineFrame& embedded(const_cast<InlineFrame&>(hl->embedded));
4241
 
        if ((hl->ch == SpecialChars::OBJECT) && (embedded.hasItem()))
4242
 
        {
4243
 
                if (!ite->asPathText())
4244
 
                {
4245
 
                        tmp += "ET\n"+tmp2;
4246
 
                        tmp2 = "";
4247
 
                }
4248
 
                QList<PageItem*> emG = embedded.getGroupedItems();
4249
 
                QStack<PageItem*> groupStack;
4250
 
                for (int em = 0; em < emG.count(); ++em)
4251
 
                {
4252
 
                        PageItem* embedded = emG.at(em);
4253
 
                        if (embedded->isGroupControl)
4254
 
                        {
4255
 
                                tmp2 += "q\n";
4256
 
                                FPointArray cl = embedded->PoLine.copy();
4257
 
                                FPointArray clb = embedded->PoLine.copy();
4258
 
                                QMatrix mm;
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);
4261
 
                                else
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());
4270
 
                                cl.map( mm );
4271
 
                                embedded->PoLine = cl;
4272
 
                                tmp2 += SetClipPath(embedded);
4273
 
                                tmp2 += "h W* n\n";
4274
 
                                groupStack.push(embedded->groupsLastItem);
4275
 
                                embedded->PoLine = clb.copy();
4276
 
                                continue;
4277
 
                        }
4278
 
                        tmp2 += "q\n";
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";
4281
 
                        else
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))
4284
 
                                return false;
4285
 
                        tmp2 +=output;
4286
 
                        tmp2 += "Q\n";
4287
 
                        if (groupStack.count() != 0)
4288
 
                        {
4289
 
                                while (embedded == groupStack.top())
4290
 
                                {
4291
 
                                        tmp2 += "Q\n";
4292
 
                                        groupStack.pop();
4293
 
                                        if (groupStack.count() == 0)
4294
 
                                                break;
4295
 
                                }
4296
 
                        }
4297
 
                }
4298
 
                for (int em = 0; em < emG.count(); ++em)
4299
 
                {
4300
 
                        PageItem* embedded = emG.at(em);
4301
 
                        if (!embedded->isTableItem)
4302
 
                                continue;
4303
 
                        if ((embedded->lineColor() == CommonStrings::None) || (embedded->lineWidth() == 0.0))
4304
 
                                continue;
4305
 
                        tmp2 += "q\n";
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";
4308
 
                        else
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";
4310
 
 
4311
 
                        if ((embedded->doOverprint) && (!Options.UseRGB))
4312
 
                        {
4313
 
                                QString ShName = ResNam+QString::number(ResCount);
4314
 
                                ResCount++;
4315
 
                                Transpar[ShName] = writeGState("/OP true\n"
4316
 
                                                                                        "/op true\n"
4317
 
                                                                                        "/OPM 1\n");
4318
 
                                tmp2 += "/"+ShName+" gs\n";
4319
 
                        }
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)
4326
 
                        {
4327
 
                                tmp2 += "[ ";
4328
 
                                QVector<double>::iterator it;
4329
 
                                for ( it = embedded->DashValues.begin(); it != embedded->DashValues.end(); ++it )
4330
 
                                {
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)+" ";
4336
 
                                }
4337
 
                                tmp2 += "] "+QString::number(static_cast<int>(embedded->DashOffset))+" d\n";
4338
 
                        }
4339
 
                        else
4340
 
                                tmp2 += "["+getDashString(embedded->PLineArt, embedded->lineWidth())+"] 0 d\n";
4341
 
                        tmp2 += "2 J\n";
4342
 
                        switch (embedded->PLineJoin)
4343
 
                        {
4344
 
                                case Qt::MiterJoin:
4345
 
                                        tmp2 += "0 j\n";
4346
 
                                        break;
4347
 
                                case Qt::BevelJoin:
4348
 
                                        tmp2 += "2 j\n";
4349
 
                                        break;
4350
 
                                case Qt::RoundJoin:
4351
 
                                        tmp2 += "1 j\n";
4352
 
                                        break;
4353
 
                                default:
4354
 
                                        tmp2 += "0 j\n";
4355
 
                                        break;
4356
 
                        }
4357
 
                        if ((embedded->TopLine) || (embedded->RightLine) || (embedded->BottomLine) || (embedded->LeftLine))
4358
 
                        {
4359
 
                                if (embedded->TopLine)
4360
 
                                {
4361
 
                                        tmp2 += "0 0 m\n";
4362
 
                                        tmp2 += FToStr(embedded->width())+" 0 l\n";
4363
 
                                }
4364
 
                                if (embedded->RightLine)
4365
 
                                {
4366
 
                                        tmp2 += FToStr(embedded->width())+" 0 m\n";
4367
 
                                        tmp2 += FToStr(embedded->width())+" "+FToStr(-embedded->height())+" l\n";
4368
 
                                }
4369
 
                                if (embedded->BottomLine)
4370
 
                                {
4371
 
                                        tmp2 += "0 "+FToStr(-embedded->height())+" m\n";
4372
 
                                        tmp2 += FToStr(embedded->width())+" "+FToStr(-embedded->height())+" l\n";
4373
 
                                }
4374
 
                                if (embedded->LeftLine)
4375
 
                                {
4376
 
                                        tmp2 += "0 0 m\n";
4377
 
                                        tmp2 += "0 "+FToStr(-embedded->height())+" l\n";
4378
 
                                }
4379
 
                                tmp2 += "S\n";
4380
 
                        }
4381
 
                        tmp2 += "Q\n";
4382
 
                }
4383
 
                tmp += tmp2+"\n";
4384
 
                tmp2 = "";
4385
 
                if (ite->asPathText())
4386
 
                        tmp += "Q\n";
4387
 
                else
4388
 
                        tmp += "BT\n";
4389
 
                return true;
4390
 
        }
4391
 
 
4392
 
        uint glyph = hl->glyph.glyph;
4393
 
 
4394
 
        if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode()) ||
4395
 
                glyph == (ScFace::CONTROL_GLYPHS + 32)) 
4396
 
        {
4397
 
                glyph = style.font().char2CMap(QChar(' '));
4398
 
                chstr = ' ';
4399
 
        }
4400
 
        else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode()))
4401
 
        {
4402
 
                glyph = style.font().char2CMap(QChar('-'));
4403
 
                chstr = '-';
4404
 
        }
4405
 
        
4406
 
        if (glyph < ScFace::CONTROL_GLYPHS)
4407
 
        {
4408
 
                if (style.strokeColor() != CommonStrings::None)
4409
 
                {
4410
 
                        StrokeColor = "";
4411
 
                        StrokeColor += putColor(style.strokeColor(), style.strokeShade(), false);
4412
 
                }
4413
 
                if (style.fillColor() != CommonStrings::None)
4414
 
                {
4415
 
                        FillColor = "";
4416
 
                        FillColor += putColor(style.fillColor(), style.fillShade(), true);
4417
 
                }
4418
 
                if (((style.effects() & ScStyle_Underline) && (chstr != SpecialChars::PARSEP))  || ((style.effects() & ScStyle_UnderlineWords) && (!chstr.isSpace())))
4419
 
                {
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)
4424
 
                                kern = 0;
4425
 
                        else
4426
 
                                kern = style.fontSize() * style.tracking() / 10000.0;
4427
 
                        if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
4428
 
                        {
4429
 
                                if (style.underlineOffset() != -1)
4430
 
                                        Upos = (style.underlineOffset() / 1000.0) * (style.font().descent(style.fontSize() / 10.0));
4431
 
                                else
4432
 
                                        Upos = style.font().underlinePos(style.fontSize() / 10.0);
4433
 
                                if (style.underlineWidth() != -1)
4434
 
                                        Uwid = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
4435
 
                                else
4436
 
                                        Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
4437
 
                        }
4438
 
                        else
4439
 
                        {
4440
 
                                Upos = style.font().underlinePos(style.fontSize() / 10.0);
4441
 
                                Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
4442
 
                        }
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)
4449
 
                        {
4450
 
                                if (style.effects() & ScStyle_Subscript)
4451
 
                                {
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";
4454
 
                                }
4455
 
                                else
4456
 
                                {
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";
4459
 
                                }
4460
 
                        }
4461
 
                        else
4462
 
                        {
4463
 
                                if (style.effects() & ScStyle_Subscript)
4464
 
                                {
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";
4467
 
                                }
4468
 
                                else
4469
 
                                {
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";
4472
 
                                }
4473
 
                        }
4474
 
                        tmp2 += "S\n";
4475
 
                }
4476
 
                if (!style.font().hasNames())
4477
 
                {
4478
 
                        if (glyph != style.font().char2CMap(QChar(' ')))
4479
 
                        {
4480
 
                                if ((style.strokeColor() != CommonStrings::None) && (style.effects() & ScStyle_Outline))
4481
 
                                {
4482
 
                                        tmp2 += FToStr((tsz * style.outlineWidth() / 1000.0) / tsz)+" w\n[] 0 d\n0 J\n0 j\n";
4483
 
                                        tmp2 += StrokeColor;
4484
 
                                }
4485
 
                                if (style.fillColor() != CommonStrings::None)
4486
 
                                        tmp2 += FillColor;
4487
 
                                tmp2 += "q\n";
4488
 
                                // #see 8257 : transform is already computed at beginning of the function
4489
 
                                /*if (ite->itemType() == PageItem::PathText)
4490
 
                                {
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";
4500
 
                                }*/
4501
 
                                if (!ite->asPathText())
4502
 
                                {
4503
 
                                        if (ite->reversed())
4504
 
                                        {
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";
4510
 
                                        }
4511
 
                                        else
4512
 
                                        {
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";
4514
 
                                        }
4515
 
                                }
4516
 
                                else
4517
 
                                {
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";
4521
 
                                }
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)
4528
 
                                {
4529
 
                                        FPointArray gly = style.font().glyphOutline(glyph);
4530
 
                                        QMatrix mat;
4531
 
                                        mat.scale(0.1, 0.1);
4532
 
                                        gly.map(mat);
4533
 
                                        bool nPath = true;
4534
 
                                        FPoint np;
4535
 
                                        if (gly.size() > 3)
4536
 
                                        {
4537
 
                                                for (uint poi=0; poi<gly.size()-3; poi += 4)
4538
 
                                                {
4539
 
                                                        if (gly.point(poi).x() > 900000)
4540
 
                                                        {
4541
 
                                                                tmp2 += "h\n";
4542
 
                                                                nPath = true;
4543
 
                                                                continue;
4544
 
                                                        }
4545
 
                                                        if (nPath)
4546
 
                                                        {
4547
 
                                                                np = gly.point(poi);
4548
 
                                                                tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
4549
 
                                                                nPath = false;
4550
 
                                                        }
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";
4557
 
                                                }
4558
 
                                        }
4559
 
                                        tmp2 += "h s\n";
4560
 
                                }
4561
 
                                tmp2 += "Q\n";
4562
 
                        }
4563
 
                }
4564
 
                else
4565
 
                {
4566
 
                        if (style.strokeColor() != CommonStrings::None)
4567
 
                        {
4568
 
                                if ((style.effects() & ScStyle_Underline) || (style.effects() & ScStyle_Strikethrough) || (style.effects() & ScStyle_Outline))
4569
 
                                        tmp2 += StrokeColor;
4570
 
                        }
4571
 
                        if (style.fillColor() != CommonStrings::None)
4572
 
                        {
4573
 
                                if ((style.effects() & ScStyle_Underline) || (style.effects() & ScStyle_Strikethrough))
4574
 
                                        tmp2 += FillColor;
4575
 
                        }
4576
 
                        if (glyph != style.font().char2CMap(QChar(' ')))
4577
 
                        {
4578
 
                                uint idx = hl->glyph.glyph;
4579
 
                                uint idx1;
4580
 
                                if (Options.SubsetList.contains(style.font().replacementName()))
4581
 
                                        idx1 = Type3Fonts[UsedFontsP[style.font().replacementName()]][idx] / 256;
4582
 
                                else
4583
 
                                        idx1 = idx / 224;
4584
 
                                tmp += UsedFontsP[style.font().replacementName()]+"S"+QString::number(idx1)+" "+FToStr(tsz / 10.0)+" Tf\n";
4585
 
                                if (style.strokeColor() != CommonStrings::None)
4586
 
                                        tmp += StrokeColor;
4587
 
                                if (style.fillColor() != CommonStrings::None)
4588
 
                                        tmp += FillColor;
4589
 
                                if ((Options.SubsetList.contains(style.font().replacementName())) && (style.effects() & ScStyle_Outline) && (style.strokeColor() != CommonStrings::None))
4590
 
                                {
4591
 
                                        tmp2 += "q\n";
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)
4595
 
                                        {
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";
4605
 
                                        }*/
4606
 
                                        if (!ite->asPathText())
4607
 
                                        {
4608
 
                                                if (ite->reversed())
4609
 
                                                {
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";
4615
 
                                                }
4616
 
                                                else
4617
 
                                                {
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";
4619
 
                                                }
4620
 
                                        }
4621
 
                                        else
4622
 
                                        {
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";
4626
 
                                        }
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);
4631
 
                                        QMatrix mat;
4632
 
                                        mat.scale(0.1, 0.1);
4633
 
                                        gly.map(mat);
4634
 
                                        bool nPath = true;
4635
 
                                        FPoint np;
4636
 
                                        if (gly.size() > 3)
4637
 
                                        {
4638
 
                                                for (uint poi=0; poi<gly.size()-3; poi += 4)
4639
 
                                                {
4640
 
                                                        if (gly.point(poi).x() > 900000)
4641
 
                                                        {
4642
 
                                                                tmp2 += "h\n";
4643
 
                                                                nPath = true;
4644
 
                                                                continue;
4645
 
                                                        }
4646
 
                                                        if (nPath)
4647
 
                                                        {
4648
 
                                                                np = gly.point(poi);
4649
 
                                                                tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
4650
 
                                                                nPath = false;
4651
 
                                                        }
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";
4658
 
                                                }
4659
 
                                        }
4660
 
                                        tmp2 += "h s\n";
4661
 
                                        tmp2 += "Q\n";
4662
 
                                }
4663
 
                                else
4664
 
                                {
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");
4667
 
                                        else
4668
 
                                                tmp += "0 Tr\n";
4669
 
                                }
4670
 
                                if (!ite->asPathText())
4671
 
                                {
4672
 
                                        if (ite->reversed())
4673
 
                                        {
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";
4676
 
                                        }
4677
 
                                        else
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";
4679
 
                                }
4680
 
                                else
4681
 
                                        tmp += FToStr(qMax(hl->glyph.scaleH, 0.1))+" 0 0 "+FToStr(qMax(hl->glyph.scaleV, 0.1))+" 0 0 Tm\n";
4682
 
                                uchar idx2;
4683
 
                                if (Options.SubsetList.contains(style.font().replacementName()))
4684
 
                                {
4685
 
                                        if (style.fillColor() != CommonStrings::None)
4686
 
                                        {
4687
 
                                                idx2 = Type3Fonts[UsedFontsP[style.font().replacementName()]][idx] % 256;
4688
 
                                                tmp += "<"+QString(toHex(idx2))+"> Tj\n";
4689
 
                                        }
4690
 
                                }
4691
 
                                else
4692
 
                                {
4693
 
                                        idx2 = idx % 224 + 32;
4694
 
                                        tmp += "<"+QString(toHex(idx2))+"> Tj\n";
4695
 
                                }
4696
 
                        }
4697
 
                }
4698
 
                if ((style.effects() & ScStyle_Strikethrough) && (chstr != SpecialChars::PARSEP))
4699
 
                {
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)
4704
 
                                kern = 0;
4705
 
                        else
4706
 
                                kern = style.fontSize() * style.tracking() / 10000.0;
4707
 
                        if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
4708
 
                        {
4709
 
                                if (style.strikethruOffset() != -1)
4710
 
                                        Upos = (style.strikethruOffset() / 1000.0) * (style.font().ascent(style.fontSize() / 10.0));
4711
 
                                else
4712
 
                                        Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
4713
 
                                if (style.strikethruWidth() != -1)
4714
 
                                        Uwid = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
4715
 
                                else
4716
 
                                        Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
4717
 
                        }
4718
 
                        else
4719
 
                        {
4720
 
                                Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
4721
 
                                Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
4722
 
                        }
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)
4729
 
                        {
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";
4732
 
                        }
4733
 
                        else
4734
 
                        {
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";
4737
 
                        }
4738
 
                        tmp2 += "S\n";
4739
 
                }
4740
 
                if (ite->asPathText())
4741
 
                {
4742
 
                        tmp += "ET\n"+tmp2+"Q\n";
4743
 
                        tmp2 = "";
4744
 
                }
4745
 
        }
4746
 
        if (hl->glyph.more) {
4747
 
                // ugly hack until setTextCh interface is changed
4748
 
                ScText hl2(*hl);
4749
 
                hl2.glyph = *(hl->glyph.more);
4750
 
                if (!setTextCh(ite, PNr, x + hl->glyph.xadvance, y, d, tmp, tmp2, &hl2, pstyle, pag))
4751
 
                        return false;
4752
 
                // don't let hl2's destructor delete these!
4753
 
                hl2.glyph.more = 0;
4754
 
        }
4755
 
        return true;
4756
 
#endif
4757
 
}
4758
 
 
4759
 
QString PDFLibCore::SetColor(const QString& farbe, double Shade)
4760
 
{
4761
 
        const ScColor& col = doc.PageColors[farbe];
4762
 
        return SetColor(col, Shade);
4763
 
}
4764
 
 
4765
 
QString PDFLibCore::SetColor(const ScColor& farbe, double Shade)
4766
 
{
4767
 
        QString tmp;
4768
 
        RGBColor rgb;
4769
 
        CMYKColor cmyk;
4770
 
        int h, s, v, k;
4771
 
        ScColor tmpC(farbe);
4772
 
        QColor tmpR;
4773
 
        if (Options.isGrayscale)
4774
 
        {
4775
 
                bool kToGray = false;
4776
 
                if (tmpC.getColorModel() == colorModelCMYK)
4777
 
                {
4778
 
                        ScColorEngine::getShadeColorCMYK(tmpC, &doc, cmyk, Shade);
4779
 
                        cmyk.getValues(h, s, v, k);
4780
 
                        kToGray = (h == 0 && s == 0 && v == 0);
4781
 
                }
4782
 
                if (kToGray)
4783
 
                        tmp = FToStr(1.0 - k / 255.0);
4784
 
                else
4785
 
                {
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);
4789
 
                }
4790
 
                return tmp;
4791
 
        }
4792
 
        if (Options.UseRGB)
4793
 
        {
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);
4797
 
        }
4798
 
        else
4799
 
        {
4800
 
                if ((doc.HasCMS) && (Options.UseProfiles))
4801
 
                {
4802
 
                        if (tmpC.getColorModel() == colorModelCMYK)
4803
 
                        {
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);
4807
 
                        }
4808
 
                        else
4809
 
                        {
4810
 
                                if (Options.SComp == 3)
4811
 
                                {
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);
4815
 
                                }
4816
 
                                else
4817
 
                                {
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);
4821
 
                                }
4822
 
                        }
4823
 
                }
4824
 
                else
4825
 
                {
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);
4829
 
                }
4830
 
        }
4831
 
        return tmp;
4832
 
}
4833
 
 
4834
 
QString PDFLibCore::SetGradientColor(const QString& farbe, double Shade)
4835
 
{
4836
 
        QString tmp;
4837
 
        RGBColor rgb;
4838
 
        CMYKColor cmyk;
4839
 
        int h, s, v, k;
4840
 
        ScColor tmpC(doc.PageColors[farbe]);
4841
 
        QColor tmpR;
4842
 
        if (Options.isGrayscale)
4843
 
        {
4844
 
                bool kToGray = false;
4845
 
                if (tmpC.getColorModel() == colorModelCMYK)
4846
 
                {
4847
 
                        ScColorEngine::getShadeColorCMYK(tmpC, &doc, cmyk, Shade);
4848
 
                        cmyk.getValues(h, s, v, k);
4849
 
                        kToGray = (h == 0 && s == 0 && v == 0);
4850
 
                }
4851
 
                if (kToGray)
4852
 
                        tmp = FToStr(1.0 - k / 255.0);
4853
 
                else
4854
 
                {
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);
4858
 
                }
4859
 
                return tmp;
4860
 
        }
4861
 
        if (Options.UseRGB)
4862
 
        {
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);
4866
 
        }
4867
 
        else
4868
 
        {
4869
 
                if ((doc.HasCMS) && (Options.UseProfiles))
4870
 
                {
4871
 
                        if (Options.SComp == 3)
4872
 
                        {
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);
4876
 
                        }
4877
 
                        else
4878
 
                        {
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);
4882
 
                        }
4883
 
                }
4884
 
                else
4885
 
                {
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);
4889
 
                }
4890
 
        }
4891
 
        return tmp;
4892
 
}
4893
 
 
4894
 
QString PDFLibCore::SetClipPathImage(PageItem *ite)
4895
 
{
4896
 
        QString tmp("");
4897
 
        if (ite->imageClip.size() > 3)
4898
 
        {
4899
 
                bool nPath = true;
4900
 
                for (uint poi=0; poi<ite->imageClip.size()-3; poi += 4)
4901
 
                {
4902
 
                        if (ite->imageClip.point(poi).x() > 900000)
4903
 
                        {
4904
 
                                tmp += "h\n";
4905
 
                                nPath = true;
4906
 
                                continue;
4907
 
                        }
4908
 
                        FPoint np, np1, np2, np3;
4909
 
                        if (nPath)
4910
 
                        {
4911
 
                                np = ite->imageClip.point(poi);
4912
 
                                tmp += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
4913
 
                                nPath = false;
4914
 
                        }
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";
4921
 
                        else
4922
 
                        {
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";
4926
 
                        }
4927
 
                }
4928
 
        }
4929
 
        return tmp;
4930
 
}
4931
 
 
4932
 
QString PDFLibCore::SetClipPath(PageItem *ite, bool poly)
4933
 
{
4934
 
        QString tmp("");
4935
 
        if (ite->PoLine.size() > 3)
4936
 
        {
4937
 
                bool nPath = true;
4938
 
                for (uint poi=0; poi<ite->PoLine.size()-3; poi += 4)
4939
 
                {
4940
 
                        if (ite->PoLine.point(poi).x() > 900000)
4941
 
                        {
4942
 
                                if (poly)
4943
 
                                        tmp += "h\n";
4944
 
                                nPath = true;
4945
 
                                continue;
4946
 
                        }
4947
 
                        FPoint np, np1, np2, np3;
4948
 
                        if (nPath)
4949
 
                        {
4950
 
                                np = ite->PoLine.point(poi);
4951
 
                                tmp += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
4952
 
                                nPath = false;
4953
 
                        }
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";
4960
 
                        else
4961
 
                        {
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";
4965
 
                        }
4966
 
                }
4967
 
        }
4968
 
        return tmp;
4969
 
}
4970
 
 
4971
 
QString PDFLibCore::SetClipPathArray(FPointArray *ite, bool poly)
4972
 
{
4973
 
        QString tmp("");
4974
 
        if (ite->size() > 3)
4975
 
        {
4976
 
                bool nPath = true;
4977
 
                for (uint poi=0; poi<ite->size()-3; poi += 4)
4978
 
                {
4979
 
                        if (ite->point(poi).x() > 900000)
4980
 
                        {
4981
 
                                if (poly)
4982
 
                                        tmp += "h\n";
4983
 
                                nPath = true;
4984
 
                                continue;
4985
 
                        }
4986
 
                        FPoint np, np1, np2, np3;
4987
 
                        if (nPath)
4988
 
                        {
4989
 
                                np = ite->point(poi);
4990
 
                                tmp += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
4991
 
                                nPath = false;
4992
 
                        }
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";
4999
 
                        else
5000
 
                        {
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";
5004
 
                        }
5005
 
                }
5006
 
        }
5007
 
        return tmp;
5008
 
}
5009
 
 
5010
 
void PDFLibCore::getBleeds(const Page* page, double &left, double &right)
5011
 
{
5012
 
        MarginStruct values;
5013
 
        doc.getBleeds(page, Options.bleeds, values);
5014
 
        left   = values.Left;
5015
 
        right  = values.Right;
5016
 
}
5017
 
 
5018
 
void PDFLibCore::getBleeds(const Page* page, double &left, double &right, double &bottom, double& top)
5019
 
{
5020
 
        MarginStruct values;
5021
 
        doc.getBleeds(page, Options.bleeds, values);
5022
 
        left   = values.Left;
5023
 
        right  = values.Right;
5024
 
        bottom = values.Bottom;
5025
 
        top    = values.Top;
5026
 
}
5027
 
 
5028
 
QString PDFLibCore::PDF_TransparenzFill(PageItem *currItem)
5029
 
{
5030
 
        QString ShName = ResNam+QString::number(ResCount);
5031
 
        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");
5036
 
        return tmp;
5037
 
}
5038
 
 
5039
 
QString PDFLibCore::PDF_TransparenzStroke(PageItem *currItem)
5040
 
{
5041
 
        QString ShName = ResNam+QString::number(ResCount);
5042
 
        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");
5047
 
        return tmp;
5048
 
}
5049
 
 
5050
 
bool PDFLibCore::PDF_Gradient(QString& output, PageItem *currItem)
5051
 
{
5052
 
        if (currItem->GrType == 8)
5053
 
        {
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)
5058
 
                {
5059
 
                        PageItem* item = pat->items.at(em);
5060
 
                        if (item->isGroupControl)
5061
 
                        {
5062
 
                                tmp2 += "q\n";
5063
 
                                FPointArray cl = item->PoLine.copy();
5064
 
                                FPointArray clb = item->PoLine.copy();
5065
 
                                QMatrix mm;
5066
 
                                mm.translate(item->gXpos, item->gYpos - pat->height);
5067
 
                                mm.rotate(item->rotation());
5068
 
                                cl.map( mm );
5069
 
                                item->PoLine = cl;
5070
 
                                tmp2 += SetClipPath(item);
5071
 
                                tmp2 += "h W* n\n";
5072
 
                                groupStack.push(item->groupsLastItem);
5073
 
                                item->PoLine = clb.copy();
5074
 
                                continue;
5075
 
                        }
5076
 
                        tmp2 += "q\n";
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);
5079
 
                        inPattern++;
5080
 
                        if (!PDF_ProcessItem(tmpOut, item, doc.DocPages.at(0), 0, true, true))
5081
 
                                return false;
5082
 
                        tmp2 += tmpOut;
5083
 
                        item->setXYPos(item->xPos() - ActPageP->xOffset(), item->yPos() - ActPageP->yOffset(), true);
5084
 
                        inPattern--;
5085
 
                        tmp2 += "Q\n";
5086
 
                        if (groupStack.count() != 0)
5087
 
                        {
5088
 
                                while (item == groupStack.top())
5089
 
                                {
5090
 
                                        tmp2 += "Q\n";
5091
 
                                        groupStack.pop();
5092
 
                                        if (groupStack.count() == 0)
5093
 
                                                break;
5094
 
                                }
5095
 
                        }
5096
 
                }
5097
 
                for (int em = 0; em < pat->items.count(); ++em)
5098
 
                {
5099
 
                        PageItem* item = pat->items.at(em);
5100
 
                        if (!item->isTableItem)
5101
 
                                continue;
5102
 
                        if ((item->lineColor() == CommonStrings::None) || (item->lineWidth() == 0.0))
5103
 
                                continue;
5104
 
                        tmp2 += "q\n";
5105
 
                        if ((item->doOverprint) && (!Options.UseRGB))
5106
 
                        {
5107
 
                                QString ShName = ResNam+QString::number(ResCount);
5108
 
                                ResCount++;
5109
 
                                Transpar[ShName] = writeGState("/OP true\n"
5110
 
                                                                                        "/op true\n"
5111
 
                                                                                        "/OPM 1\n");
5112
 
                                tmp2 += "/"+ShName+" gs\n";
5113
 
                        }
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)
5120
 
                        {
5121
 
                                tmp2 += "[ ";
5122
 
                                QVector<double>::iterator it;
5123
 
                                for ( it = item->DashValues.begin(); it != item->DashValues.end(); ++it )
5124
 
                                {
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)+" ";
5130
 
                                }
5131
 
                                tmp2 += "] "+QString::number(static_cast<int>(item->DashOffset))+" d\n";
5132
 
                        }
5133
 
                        else
5134
 
                                tmp2 += "["+getDashString(item->PLineArt, item->lineWidth())+"] 0 d\n";
5135
 
                        tmp2 += "2 J\n";
5136
 
                        switch (item->PLineJoin)
5137
 
                        {
5138
 
                                case Qt::MiterJoin:
5139
 
                                        tmp2 += "0 j\n";
5140
 
                                        break;
5141
 
                                case Qt::BevelJoin:
5142
 
                                        tmp2 += "2 j\n";
5143
 
                                        break;
5144
 
                                case Qt::RoundJoin:
5145
 
                                        tmp2 += "1 j\n";
5146
 
                                        break;
5147
 
                                default:
5148
 
                                        tmp2 += "0 j\n";
5149
 
                                        break;
5150
 
                        }
5151
 
                        tmp2 +=  "1 0 0 1 "+FToStr(item->gXpos)+" "+FToStr(-(item->gYpos - pat->height))+" cm\n";
5152
 
                        if (item->rotation() != 0)
5153
 
                        {
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)
5157
 
                                        cr = 0;
5158
 
                                if ((sr * sr) < 0.000001)
5159
 
                                        sr = 0;
5160
 
                                tmp2 += FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+ " 0 0 cm\n";
5161
 
                        }
5162
 
                        if ((item->TopLine) || (item->RightLine) || (item->BottomLine) || (item->LeftLine))
5163
 
                        {
5164
 
                                if (item->TopLine)
5165
 
                                {
5166
 
                                        tmp2 += "0 0 m\n";
5167
 
                                        tmp2 += FToStr(item->width())+" 0 l\n";
5168
 
                                }
5169
 
                                if (item->RightLine)
5170
 
                                {
5171
 
                                        tmp2 += FToStr(item->width())+" 0 m\n";
5172
 
                                        tmp2 += FToStr(item->width())+" "+FToStr(-item->height())+" l\n";
5173
 
                                }
5174
 
                                if (item->BottomLine)
5175
 
                                {
5176
 
                                        tmp2 += "0 "+FToStr(-item->height())+" m\n";
5177
 
                                        tmp2 += FToStr(item->width())+" "+FToStr(-item->height())+" l\n";
5178
 
                                }
5179
 
                                if (item->LeftLine)
5180
 
                                {
5181
 
                                        tmp2 += "0 0 m\n";
5182
 
                                        tmp2 += "0 "+FToStr(-item->height())+" l\n";
5183
 
                                }
5184
 
                                tmp2 += "S\n";
5185
 
                        }
5186
 
                        tmp2 += "Q\n";
5187
 
                }
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");
5197
 
                QMatrix mpa;
5198
 
                if (inPattern == 0)
5199
 
                {
5200
 
                        mpa.translate(currItem->xPos() - ActPageP->xOffset(), ActPageP->height() - (currItem->yPos() - ActPageP->yOffset()));
5201
 
                        mpa.rotate(-currItem->rotation());
5202
 
                }
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)
5214
 
                {
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");
5219
 
                        PutDoc(">>\n");
5220
 
                }
5221
 
                if (Seite.FObjects.count() != 0)
5222
 
                {
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");
5227
 
                        PutDoc(">>\n");
5228
 
                }
5229
 
                if (Shadings.count() != 0)
5230
 
                {
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");
5235
 
                        PutDoc(">>\n");
5236
 
                }
5237
 
                if (Patterns.count() != 0)
5238
 
                {
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");
5243
 
                        PutDoc(">>\n");
5244
 
                }
5245
 
                if (Transpar.count() != 0)
5246
 
                {
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");
5251
 
                        PutDoc(">>\n");
5252
 
                }
5253
 
                if ((ICCProfiles.count() != 0) || (spotMap.count() != 0))
5254
 
                {
5255
 
                        PutDoc("/ColorSpace << \n");
5256
 
                        QMap<QString,ICCD>::Iterator it3c;
5257
 
                        if (ICCProfiles.count() != 0)
5258
 
                        {
5259
 
                                for (it3c = ICCProfiles.begin(); it3c != ICCProfiles.end(); ++it3c)
5260
 
                                        PutDoc("/"+it3c.value().ResName+" "+QString::number(it3c.value().ResNum)+" 0 R\n");
5261
 
                        }
5262
 
                        QMap<QString,SpotC>::Iterator it3sc;
5263
 
                        if (spotMap.count() != 0)
5264
 
                        {
5265
 
                                for (it3sc = spotMap.begin(); it3sc != spotMap.end(); ++it3sc)
5266
 
                                        PutDoc("/"+it3sc.value().ResName+" "+QString::number(it3sc.value().ResNum)+" 0 R\n");
5267
 
                        }
5268
 
                        PutDoc(">>\n");
5269
 
                }
5270
 
                PutDoc(">>\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)
5280
 
                        tmp += "h\nf*\n";
5281
 
                else
5282
 
                        tmp += "h\nf\n";
5283
 
                ResCount++;
5284
 
                output = tmp;
5285
 
                return true;
5286
 
        }
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();
5297
 
        StopVec.clear();
5298
 
        TransVec.clear();
5299
 
        Gcolors.clear();
5300
 
        colorNames.clear();
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))
5306
 
        {
5307
 
                for (uint cst = 0; cst < currItem->fill_gradient.Stops(); ++cst)
5308
 
                {
5309
 
                        actualStop = cstops.at(cst)->rampPoint;
5310
 
                        if ((actualStop != lastStop) || (isFirst))
5311
 
                        {
5312
 
                                isFirst = false;
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);
5319
 
                        }
5320
 
                }
5321
 
        }
5322
 
        else
5323
 
        {
5324
 
                for (uint cst = 0; cst < currItem->fill_gradient.Stops(); ++cst)
5325
 
                {
5326
 
                        actualStop = cstops.at(cst)->rampPoint;
5327
 
                        if ((actualStop != lastStop) || (isFirst))
5328
 
                        {
5329
 
                                isFirst = false;
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);
5334
 
                                StopVec.append(x);
5335
 
                                StopVec.append(y);
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);
5339
 
                        }
5340
 
                }
5341
 
        }
5342
 
        output = PDF_DoLinGradient(currItem, StopVec, TransVec, Gcolors, colorNames, colorShades);
5343
 
        return true;
5344
 
}
5345
 
 
5346
 
QString PDFLibCore::PDF_DoLinGradient(PageItem *currItem, QList<double> Stops, QList<double> Trans, const QStringList& Colors, QStringList colorNames, QList<int> colorShades)
5347
 
{
5348
 
        QString tmp("");
5349
 
        bool first = true;
5350
 
        bool oneSameSpot = false;
5351
 
        bool oneSpot1 = false;
5352
 
        bool oneSpot2 = false;
5353
 
        bool twoSpot  = false;
5354
 
        bool spotMode = false;
5355
 
        uint spotObject = 0;
5356
 
        int cc, mc, yc, kc;
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)
5364
 
        {
5365
 
                oneSameSpot = false;
5366
 
                oneSpot1 = false;
5367
 
                oneSpot2 = false;
5368
 
                twoSpot = false;
5369
 
                spotMode = 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" );
5372
 
                QString TRes("");
5373
 
                if ((Options.Version >= PDFOptions::PDFVersion_14) && ((Trans.at(c+1) != 1) || (Trans.at(c) != 1)))
5374
 
                {
5375
 
                        uint shadingObject = newObject();
5376
 
                        StartObj(shadingObject);
5377
 
                        QString ShName = ResNam+QString::number(ResCount);
5378
 
                        Shadings[ShName] = shadingObject;
5379
 
                        ResCount++;
5380
 
                        PutDoc("<<\n");
5381
 
                        if ((currItem->GrType == 5) || (currItem->GrType == 7))
5382
 
                                PutDoc("/ShadingType 3\n");
5383
 
                        else
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))
5388
 
                        {
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");
5394
 
                        }
5395
 
                        else
5396
 
                        {
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");
5402
 
                        }
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)
5412
 
                        {
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");
5417
 
                                PutDoc(">>\n");
5418
 
                        }
5419
 
                        PutDoc(">>\n");
5420
 
                        QString stre = "";
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;
5429
 
                        ResCount++;
5430
 
                        QString GXName = ResNam+QString::number(ResCount);
5431
 
                        ResCount++;
5432
 
                        Transpar[GXName] = writeGState("/SMask << /S /Luminosity /G "+QString::number(formObject)+" 0 R >>\n"
5433
 
                                                                                   + "/BM /Normal\n");
5434
 
                        TRes = GXName;
5435
 
                }
5436
 
                uint shadingObject2 = newObject();
5437
 
                StartObj(shadingObject2);
5438
 
                QString ShName = ResNam+QString::number(ResCount);
5439
 
                Shadings[ShName] = shadingObject2;
5440
 
                ResCount++;
5441
 
                PutDoc("<<\n");
5442
 
                if ((currItem->GrType == 5) || (currItem->GrType == 7))
5443
 
                        PutDoc("/ShadingType 3\n");
5444
 
                else
5445
 
                        PutDoc("/ShadingType 2\n");
5446
 
                if (Options.UseRGB)
5447
 
                        PutDoc("/ColorSpace /DeviceRGB\n");
5448
 
                else
5449
 
                {
5450
 
                        if (Options.isGrayscale)
5451
 
                                PutDoc("/ColorSpace /DeviceGray\n");
5452
 
                        else
5453
 
                        {
5454
 
                                if ((doc.HasCMS) && (Options.UseProfiles))
5455
 
                                        PutDoc("/ColorSpace "+ICCProfiles[Options.SolidProf].ICCArray+"\n");
5456
 
                                else
5457
 
                                {
5458
 
                                        if (spotMap.contains(colorNames[c]))
5459
 
                                                oneSpot1 = true;
5460
 
                                        if  (spotMap.contains(colorNames[c+1]))
5461
 
                                                oneSpot2 = true;
5462
 
                                        if (oneSpot1 && oneSpot2)
5463
 
                                        {
5464
 
                                                oneSpot1 = oneSpot2 = false;
5465
 
                                                oneSameSpot = (colorNames[c] == colorNames[c+1]);
5466
 
                                                twoSpot  = true;
5467
 
                                        }
5468
 
                                        if (((!oneSpot1) && (!oneSpot2) && (!twoSpot)) || (!Options.UseSpotColors)) 
5469
 
                                                PutDoc("/ColorSpace /DeviceCMYK\n");
5470
 
                                        else
5471
 
                                        {
5472
 
                                                spotMode = true;
5473
 
                                                spotObject = newObject();
5474
 
                                                PutDoc("/ColorSpace [ /DeviceN [");
5475
 
                                                if (oneSameSpot)
5476
 
                                                        PutDoc(" /"+spot1+" ]\n");
5477
 
                                                else if (oneSpot1)
5478
 
                                                        PutDoc(" /Cyan /Magenta /Yellow /Black /"+spot1+" ]\n");
5479
 
                                                else if (oneSpot2)
5480
 
                                                        PutDoc(" /Cyan /Magenta /Yellow /Black /"+spot2+" ]\n");
5481
 
                                                else if (twoSpot)
5482
 
                                                        PutDoc(" /"+spot1+" /"+spot2+" ]\n");
5483
 
                                                PutDoc("/DeviceCMYK\n");
5484
 
                                                PutDoc(QString::number(spotObject)+" 0 R\n");
5485
 
                                                PutDoc("]\n");
5486
 
                                        }
5487
 
                                }
5488
 
                        }
5489
 
                }
5490
 
                PutDoc("/BBox [0 "+FToStr(h)+" "+FToStr(w)+" 0]\n");
5491
 
                if ((currItem->GrType == 5) || (currItem->GrType == 7))
5492
 
                {
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");
5496
 
                        else
5497
 
                        {
5498
 
                                if (first)
5499
 
                                        PutDoc("/Extend [false true]\n");
5500
 
                                else
5501
 
                                {
5502
 
                                        if (c == Colors.count()-2)
5503
 
                                                PutDoc("/Extend [true false]\n");
5504
 
                                        else
5505
 
                                                PutDoc("/Extend [false false]\n");
5506
 
                                }
5507
 
                        }
5508
 
                        first = false;
5509
 
                        PutDoc("/Function\n<<\n/FunctionType 2\n/Domain [0 1]\n");
5510
 
                        if (Options.UseSpotColors)
5511
 
                        {
5512
 
                                if (oneSameSpot)
5513
 
                                {
5514
 
                                        PutDoc("/C0 ["+FToStr(colorShades[c] / 100.0)+"]\n");
5515
 
                                        PutDoc("/C1 ["+FToStr(colorShades[c+1] / 100.0)+"]\n");
5516
 
                                }
5517
 
                                else if (oneSpot1)
5518
 
                                {
5519
 
                                        PutDoc("/C1 [0 0 0 0 "+FToStr(colorShades[c] / 100.0)+"]\n");
5520
 
                                        PutDoc("/C0 ["+Colors[c+1]+" 0 ]\n");
5521
 
                                }
5522
 
                                else if (oneSpot2)
5523
 
                                {
5524
 
                                        PutDoc("/C1 ["+Colors[c]+" 0 ]\n");
5525
 
                                        PutDoc("/C0 [0 0 0 0 "+FToStr(colorShades[c+1] / 100.0)+"]\n");
5526
 
                                }
5527
 
                                else if (twoSpot)
5528
 
                                {
5529
 
                                        PutDoc("/C1 ["+FToStr(colorShades[c] / 100.0)+" 0]\n");
5530
 
                                        PutDoc("/C0 [0 "+FToStr(colorShades[c+1] / 100.0)+"]\n");
5531
 
                                }
5532
 
                                else
5533
 
                                {
5534
 
                                        PutDoc("/C1 ["+Colors[c]+"]\n");
5535
 
                                        PutDoc("/C0 ["+Colors[c+1]+"]\n");
5536
 
                                }
5537
 
                        }
5538
 
                        else
5539
 
                        {
5540
 
                                PutDoc("/C0 ["+Colors[c+1]+"]\n");
5541
 
                                PutDoc("/C1 ["+Colors[c]+"]\n");
5542
 
                        }
5543
 
                }
5544
 
                else
5545
 
                {
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");
5549
 
                        else
5550
 
                        {
5551
 
                                if (first)
5552
 
                                        PutDoc("/Extend [true false]\n");
5553
 
                                else
5554
 
                                {
5555
 
                                        if (c == Colors.count()-2)
5556
 
                                                PutDoc("/Extend [false true]\n");
5557
 
                                        else
5558
 
                                                PutDoc("/Extend [false false]\n");
5559
 
                                }
5560
 
                        }
5561
 
                        first = false;
5562
 
                        PutDoc("/Function\n<<\n/FunctionType 2\n/Domain [0 1]\n");
5563
 
                        if (Options.UseSpotColors)
5564
 
                        {
5565
 
                                if (oneSameSpot)
5566
 
                                {
5567
 
                                        PutDoc("/C0 ["+FToStr(colorShades[c] / 100.0)+"]\n");
5568
 
                                        PutDoc("/C1 ["+FToStr(colorShades[c+1] / 100.0)+"]\n");
5569
 
                                }
5570
 
                                else if (oneSpot1)
5571
 
                                {
5572
 
                                        PutDoc("/C0 [0 0 0 0 "+FToStr(colorShades[c] / 100.0)+"]\n");
5573
 
                                        PutDoc("/C1 ["+Colors[c+1]+" 0 ]\n");
5574
 
                                }
5575
 
                                else if (oneSpot2)
5576
 
                                {
5577
 
                                        PutDoc("/C0 ["+Colors[c]+" 0 ]\n");
5578
 
                                        PutDoc("/C1 [0 0 0 0 "+FToStr(colorShades[c+1] / 100.0)+"]\n");
5579
 
                                }
5580
 
                                else if (twoSpot)
5581
 
                                {
5582
 
                                        PutDoc("/C0 ["+FToStr(colorShades[c] / 100.0)+" 0]\n");
5583
 
                                        PutDoc("/C1 [0 "+FToStr(colorShades[c+1] / 100.0)+"]\n");
5584
 
                                }
5585
 
                                else
5586
 
                                {
5587
 
                                        PutDoc("/C0 ["+Colors[c]+"]\n");
5588
 
                                        PutDoc("/C1 ["+Colors[c+1]+"]\n");
5589
 
                                }
5590
 
                        }
5591
 
                        else
5592
 
                        {
5593
 
                                PutDoc("/C0 ["+Colors[c]+"]\n");
5594
 
                                PutDoc("/C1 ["+Colors[c+1]+"]\n");
5595
 
                        }
5596
 
                }
5597
 
                PutDoc("/N 1\n>>\n>>\nendobj\n");
5598
 
                if (spotMode)
5599
 
                {
5600
 
                        QString colorDesc;
5601
 
                        StartObj(spotObject);
5602
 
                        PutDoc("<<\n/FunctionType 4\n");
5603
 
                        if (oneSameSpot)
5604
 
                        {
5605
 
                                PutDoc("/Domain [0.0 1.0]\n");
5606
 
                                ScColorEngine::getCMYKValues(doc.PageColors[colorNames[c]], &doc, cmykValues);
5607
 
                                cmykValues.getValues(cc, mc, yc, kc);
5608
 
                                colorDesc = "{\n";
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";
5613
 
                        }
5614
 
                        else if (twoSpot)
5615
 
                        {
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";
5630
 
                        }
5631
 
                        else
5632
 
                        {
5633
 
                                PutDoc("/Domain [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]\n");
5634
 
                                if (oneSpot1)
5635
 
                                {
5636
 
                                        ScColorEngine::getCMYKValues(doc.PageColors[colorNames[c]], &doc, cmykValues);
5637
 
                                        cmykValues.getValues(cc, mc, yc, kc);
5638
 
                                }
5639
 
                                else
5640
 
                                {
5641
 
                                        ScColorEngine::getCMYKValues(doc.PageColors[colorNames[c+1]], &doc, cmykValues);
5642
 
                                        cmykValues.getValues(cc, mc, yc, kc);
5643
 
                                }
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";
5648
 
                        }
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");
5652
 
                }
5653
 
                tmp += "q\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);
5657
 
                tmp += "h\nW* n\n";
5658
 
                tmp += "/"+ShName+" sh\nQ\n";
5659
 
        }
5660
 
        return tmp;
5661
 
}
5662
 
 
5663
 
bool PDFLibCore::PDF_Annotation(PageItem *ite, uint)
5664
 
{
5665
 
        ScImage img;
5666
 
        ScImage img2;
5667
 
        ScImage img3;
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("");
5681
 
        QString cc;
5682
 
        QFileInfo fiBase(Spool.fileName());
5683
 
        QString baseDir = fiBase.absolutePath();
5684
 
        if (!((ite->itemText.length() == 1) && (ite->itemText.text(0, 1) == QChar(13))))
5685
 
        {
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)
5689
 
                {
5690
 
                        cc = ite->itemText.text(d, 1);
5691
 
                        bmUtf16 += cc;
5692
 
                        if ((cc == "(") || (cc == ")") || (cc == "\\"))
5693
 
                                bm += "\\";
5694
 
                        if (cc == QChar(13))
5695
 
                                cc = "\\r";
5696
 
                        bm += cc;
5697
 
                }
5698
 
        }
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;
5706
 
        uint icon1Obj = 0;
5707
 
        uint icon2Obj = 0;
5708
 
        uint icon3Obj = 0;
5709
 
        uint actionObj = 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())
5717
 
        {
5718
 
                case 0:
5719
 
                case 10:
5720
 
                        PutDoc("/Subtype /Text\n");
5721
 
                        PutDoc("/Contents "+EncStringUTF16("("+bmUtf16+")",annotationObj)+"\n");
5722
 
                        break;
5723
 
                case 1:
5724
 
                case 11:
5725
 
                        PutDoc("/Subtype /Link\n");
5726
 
                        if (ite->annotation().ActionType() == 2)
5727
 
                        {
5728
 
                                PutDoc("/Dest /"+NDnam+QString::number(NDnum)+"\n");
5729
 
                                Dest de;
5730
 
                                de.Name = NDnam+QString::number(NDnum);
5731
 
                                de.Seite = ite->annotation().Ziel();
5732
 
                                de.Act = ite->annotation().Action();
5733
 
                                NamedDest.append(de);
5734
 
                                NDnum++;
5735
 
                        }
5736
 
                        if (ite->annotation().ActionType() == 7)
5737
 
                        {
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");
5740
 
                        }
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)
5744
 
                        {
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");
5747
 
                        }
5748
 
                        break;
5749
 
                case 2:
5750
 
                case 3:
5751
 
                case 4:
5752
 
                case 5:
5753
 
                case 6:
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");
5759
 
                        PutDoc("/F ");
5760
 
                        QString mm[] = {"4", "2", "0", "32"};
5761
 
                        PutDoc(mm[ite->annotation().Vis()]);
5762
 
                        PutDoc("\n");
5763
 
                        PutDoc("/BS << /Type /Border /W ");
5764
 
                        PutDoc(ite->annotation().borderColor() != CommonStrings::None ? QString::number(ite->annotation().Bwid()) : QString("0"));
5765
 
                        PutDoc(" /S /");
5766
 
                        const QString x[] = {"S", "D", "U", "B", "I"};
5767
 
                        PutDoc(x[ite->annotation().Bsty()]);
5768
 
                        PutDoc(" >>\n");
5769
 
                        QString cnx = "(";
5770
 
                        if (ite->annotation().Type() == 4)
5771
 
                                cnx += "/"+StdFonts["/ZapfDingbats"];
5772
 
                        else
5773
 
                        {
5774
 
                                if (Options.Version < PDFOptions::PDFVersion_14)
5775
 
                                        cnx += "/"+StdFonts[ind2PDFabr[ite->annotation().Font()]];
5776
 
                                else
5777
 
                                        cnx += UsedFontsF[ite->itemText.defaultStyle().charStyle().font().replacementName()];
5778
 
//                                      cnx += UsedFontsP[ite->itemText.defaultStyle().charStyle().font().replacementName()]+"Form";
5779
 
                        }
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);
5785
 
                        cnx += ")";
5786
 
                        PutDoc("/DA "+EncString(cnx,annotationObj)+"\n");
5787
 
                        int flg = ite->annotation().Flag();
5788
 
                        if (Options.Version == PDFOptions::PDFVersion_13)
5789
 
                                flg = flg & 522247;
5790
 
                        PutDoc("/Ff "+QString::number(flg)+"\n");
5791
 
                        QString xs[] = {"N", "I", "O", "P"};
5792
 
                        switch (ite->annotation().Type())
5793
 
                        {
5794
 
                                case 2:
5795
 
                                        PutDoc("/FT /Btn\n");
5796
 
                                        PutDoc("/H /");
5797
 
                                        PutDoc(xs[ite->annotation().Feed()]);
5798
 
                                        PutDoc("\n");
5799
 
                                        PutDoc("/Q 0\n");
5800
 
                                        break;
5801
 
                                case 3:
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");
5810
 
                                        break;
5811
 
                                case 4:
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");
5817
 
                                        break;
5818
 
                                case 5:
5819
 
                                case 6:
5820
 
                                        PutDoc("/FT /Ch\n/V (");
5821
 
                                        if (bmst.count() > 0)
5822
 
                                                PutDoc(bmst[0]);
5823
 
                                        PutDoc(")\n/DV ");
5824
 
                                        cnx = "(";
5825
 
                                        if (bmstUtf16.count() > 0)
5826
 
                                                cnx += bmstUtf16[0];
5827
 
                                        cnx += ")";
5828
 
                                        PutDoc(EncStringUTF16(cnx,annotationObj)+"\n");
5829
 
                                        PutDoc("/Opt [ ");
5830
 
                                        for (int bmc = 0; bmc < bmstUtf16.count(); ++bmc)
5831
 
                                                PutDoc(EncStringUTF16("("+bmstUtf16[bmc]+")",annotationObj)+"\n");
5832
 
                                        PutDoc("]\n");
5833
 
                                        appearanceObj = newObject();
5834
 
                                        PutDoc("/AP << /N "+QString::number(appearanceObj)+" 0 R >>\n");
5835
 
                                        break;
5836
 
                        }
5837
 
                        PutDoc("/MK << ");
5838
 
                        if ((ite->annotation().Type() == 5) || (ite->annotation().Type() == 6))
5839
 
                        {
5840
 
                                PutDoc("/BG [ 1 1 1 ] ");
5841
 
                                if (ite->annotation().borderColor() != CommonStrings::None)
5842
 
                                        PutDoc("/BC [ "+SetColor(ite->annotation().borderColor(), 100)+" ] ");
5843
 
                        }
5844
 
                        else
5845
 
                        {
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)+" ] ");
5850
 
                        }
5851
 
                        int IconOb = 0;
5852
 
                        switch (ite->annotation().Type())
5853
 
                        {
5854
 
                                case 2:
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())
5861
 
                                        {
5862
 
                                                if (!ite->Pfile.isEmpty())
5863
 
                                                {
5864
 
                                                        IconOb += ite->pixm.hasAlpha() ? 3 : 2;
5865
 
                                                        icon1Obj = newObject();
5866
 
                                                        PutDoc("/I "+QString::number(icon1Obj)+" 0 R ");
5867
 
                                                }
5868
 
                                                if (!ite->Pfile2.isEmpty())
5869
 
                                                {
5870
 
                                                        CMSettings cms(ite->doc(), "", Intent_Perceptual);
5871
 
                                                        img.LoadPicture(ite->Pfile2, 1, cms, false, false, ScImage::RGBData, 72);
5872
 
                                                        QByteArray im;
5873
 
                                                        img3.getAlpha(ite->Pfile2, 1, im, true, false);
5874
 
                                                        IconOb += !im.isEmpty() ? 3 : 2;
5875
 
                                                        im.resize(0);
5876
 
                                                        icon2Obj = newObject();
5877
 
                                                        PutDoc("/IX "+QString::number(icon2Obj)+" 0 R ");
5878
 
                                                }
5879
 
                                                if (!ite->Pfile3.isEmpty())
5880
 
                                                {
5881
 
                                                        CMSettings cms(ite->doc(), "", Intent_Perceptual);
5882
 
                                                        img2.LoadPicture(ite->Pfile3, 1, cms, false, false, ScImage::RGBData, 72);
5883
 
                                                        QByteArray im;
5884
 
                                                        img3.getAlpha(ite->Pfile3, 1, im, true, false);
5885
 
                                                        IconOb += !im.isEmpty() ? 3 : 2;
5886
 
                                                        im.resize(0);
5887
 
                                                        icon3Obj = newObject();
5888
 
                                                        PutDoc("/RI "+QString::number(icon3Obj)+" 0 R ");
5889
 
                                                }
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()]);
5894
 
                                                PutDoc(" /S /");
5895
 
                                                PutDoc(ite->imageXScale() != ite->imageYScale() ? "A" : "P");
5896
 
                                                PutDoc(" /A [ ");
5897
 
                                                if ((ite->width()/ite->imageXScale() - ite->pixm.width()) != 0)
5898
 
                                                {
5899
 
                                                        if (ite->annotation().ScaleW() == 3)
5900
 
                                                                PutDoc(FToStr(qMax(ite->imageXOffset() / (ite->width()/ite->imageXScale() - ite->pixm.width()), 0.01))+" ");
5901
 
                                                        else
5902
 
                                                                PutDoc("0.5 ");
5903
 
                                                }
5904
 
                                                else
5905
 
                                                        PutDoc("0 ");
5906
 
                                                if ((ite->height()/ite->imageYScale() - ite->pixm.height()) != 0)
5907
 
                                                {
5908
 
                                                        if (ite->annotation().ScaleW() == 3)
5909
 
                                                                PutDoc(FToStr(1.0 - qMax(ite->imageYOffset() / (ite->height()/ite->imageYScale() - ite->pixm.height()), 0.01)));
5910
 
                                                        else
5911
 
                                                                PutDoc("0.5");
5912
 
                                                }
5913
 
                                                else
5914
 
                                                        PutDoc("0");
5915
 
                                                PutDoc(" ] >> ");
5916
 
                                        }
5917
 
                                        break;
5918
 
                                case 6:
5919
 
                                case 5:
5920
 
                                case 3:
5921
 
                                        break;
5922
 
                                case 4:
5923
 
                                        PutDoc("/CA "+EncString("("+ct+")",annotationObj)+" ");
5924
 
                                        break;
5925
 
                        }
5926
 
                        if (ite->rotation() != 0)
5927
 
                                PutDoc("/R "+QString::number((abs(static_cast<int>(ite->rotation())) / 90)*90)+" ");
5928
 
                        PutDoc(">>\n");
5929
 
                        if ((ite->annotation().ActionType() != 0) || (ite->annotation().AAact()))
5930
 
                        {
5931
 
                                if (ite->annotation().ActionType() == 7)
5932
 
                                {
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");
5935
 
                                }
5936
 
                                if (ite->annotation().ActionType() == 9)
5937
 
                                {
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");
5940
 
                                }
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)
5946
 
                                {
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()) 
5951
 
                                        {
5952
 
                                        case 1:
5953
 
                                          // HTML
5954
 
                                          PutDoc("/Flags 4"); // bit 3 on
5955
 
                                          break;
5956
 
                                        case 2:
5957
 
                                          // XFDF
5958
 
                                          PutDoc("/Flags 64"); // bit 6 on
5959
 
                                          break;
5960
 
                                        case 3:
5961
 
                                          // PDF
5962
 
                                          PutDoc("/Flags 512"); // bit 9 on
5963
 
                                          break;
5964
 
                                        case 0:
5965
 
                                        default:
5966
 
                                          // FDF
5967
 
                                          // bit 3 off
5968
 
                                          break;
5969
 
                                        }
5970
 
                                        PutDoc(">>\n");
5971
 
                                }
5972
 
                                if (ite->annotation().ActionType() == 1)
5973
 
                                {
5974
 
                                        if (!ite->annotation().Action().isEmpty())
5975
 
                                        {
5976
 
                                                PutDoc("/A << /Type /Action /S /JavaScript /JS " + QString::number(actionObj) + " 0 R >>\n");
5977
 
                                        }
5978
 
                                }
5979
 
                                if (ite->annotation().AAact())
5980
 
                                {
5981
 
                                        if (!ite->annotation().Action().isEmpty())
5982
 
                                        {
5983
 
                                                PutDoc("/A << /Type /Action /S /JavaScript /JS " + QString::number(actionObj) + " 0 R >>\n");
5984
 
                                        }
5985
 
                                        PutDoc("/AA " + QString::number(AActionObj) + " 0 R\n");
5986
 
                                }
5987
 
                                if (ite->annotation().ActionType() == 2)
5988
 
                                {
5989
 
                                        PutDoc("/A << /Type /Action /S /GoTo /D /" + NDnam + QString::number(NDnum) + " >>\n");
5990
 
                                        Dest de;
5991
 
                                        de.Name = NDnam+QString::number(NDnum);
5992
 
                                        de.Seite = ite->annotation().Ziel();
5993
 
                                        de.Act = ite->annotation().Action();
5994
 
                                        NamedDest.append(de);
5995
 
                                        NDnum++;
5996
 
                                }
5997
 
                        }
5998
 
                        break;
5999
 
                }
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))
6003
 
        {
6004
 
                case 0:
6005
 
                        break;
6006
 
                case 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();
6011
 
                        break;
6012
 
                case 180:
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();
6017
 
                        break;
6018
 
                case 270:
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());
6023
 
                        break;
6024
 
        }
6025
 
        PutDoc("/Rect [ "+FToStr(x+bleedDisplacementX)+" "+FToStr(y2+bleedDisplacementY)+" "+FToStr(x2+bleedDisplacementX)+" "+FToStr(y+bleedDisplacementY)+" ]\n");
6026
 
        PutDoc(">>\nendobj\n");
6027
 
        // write icons
6028
 
        if ((ite->annotation().Type() == 2) && (ite->annotation().UseIcons()))
6029
 
        {
6030
 
                if (!ite->Pfile.isEmpty())
6031
 
                {
6032
 
                        if (!PDF_Image(ite, ite->Pfile, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), true))
6033
 
                                return false;
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);
6037
 
                }
6038
 
                if (!ite->Pfile2.isEmpty())
6039
 
                {
6040
 
                        if (!PDF_Image(ite, ite->Pfile2, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), true))
6041
 
                                return false;
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);
6045
 
                }
6046
 
                if (!ite->Pfile3.isEmpty())
6047
 
                {
6048
 
                        if (!PDF_Image(ite, ite->Pfile3, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), true))
6049
 
                                return false;
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);
6053
 
                }
6054
 
        }
6055
 
        // write Appearance?
6056
 
        if (ite->annotation().Type() == 3)
6057
 
        {
6058
 
                cc = "";
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()]];
6067
 
                else
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)
6072
 
                {
6073
 
                        cc += "1 0 0 1 0 0 Tm\n0 0 Td\n";
6074
 
                        for (int mz = 0; mz < bmst.count(); ++mz)
6075
 
                        {
6076
 
                                cc += EncStringUTF16("("+bmst[mz]+")",annotationObj);
6077
 
                                cc += " Tj\nT*\n";
6078
 
                        }
6079
 
                        cc += "ET\nEMC";
6080
 
                }
6081
 
                else
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);
6084
 
        }
6085
 
        if (ite->annotation().Type() == 4)
6086
 
        {
6087
 
                cc = "q\nBT\n";
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);
6093
 
        }
6094
 
        if ((ite->annotation().Type() == 5) || (ite->annotation().Type() == 6))
6095
 
        {
6096
 
                cc = "";
6097
 
                cc += "1 g\n";
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);
6102
 
                else
6103
 
                        cc += "0 G\n";
6104
 
                cc += "0 0 "+FToStr(x2-x)+" "+FToStr(y-y2)+" re\nS\n";
6105
 
                cc += "/Tx BMC\nq\nBT\n";
6106
 
                cc += "0 g\n";
6107
 
                if (Options.Version < PDFOptions::PDFVersion_14)
6108
 
                        cc += "/"+StdFonts[ind2PDFabr[ite->annotation().Font()]];
6109
 
                else
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);
6118
 
        }
6119
 
        return true;
6120
 
}               
6121
 
                
6122
 
uint PDFLibCore::writeActions(const Annotation& annot, uint annotationObj)
6123
 
{
6124
 
        // write actions
6125
 
        if ((annot.Type() > 1) && (annot.AAact()))
6126
 
        {
6127
 
                uint E = 0;
6128
 
                if (!annot.E_act().isEmpty())
6129
 
                        E = WritePDFString(annot.E_act());
6130
 
                uint X = 0;
6131
 
                if (!annot.X_act().isEmpty())
6132
 
                        X = WritePDFString(annot.X_act());
6133
 
                uint D = 0;
6134
 
                if (!annot.D_act().isEmpty())
6135
 
                        D = WritePDFString(annot.D_act());
6136
 
                uint Fo = 0;
6137
 
                if (!annot.Fo_act().isEmpty())
6138
 
                        Fo = WritePDFString(annot.Fo_act());
6139
 
                uint Bl = 0;
6140
 
                if (!annot.Bl_act().isEmpty())
6141
 
                        Bl = WritePDFString(annot.Bl_act());
6142
 
                uint K = 0;
6143
 
                uint F = 0;
6144
 
                uint V = 0;
6145
 
                uint C = 0;
6146
 
                if ((annot.Type() == 3) || (annot.Type() == 5) || (annot.Type() == 6))
6147
 
                {
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())
6155
 
                        {
6156
 
                                C = WritePDFString(annot.C_act());
6157
 
                                CalcFields.append(annotationObj);
6158
 
                        }
6159
 
                }
6160
 
 
6161
 
                uint result = newObject();
6162
 
                StartObj(result);
6163
 
                PutDoc("<<\n");
6164
 
                if (E)
6165
 
                {
6166
 
                        PutDoc("/E << /Type /Action /S /JavaScript /JS "+QString::number(E)+" 0 R >>\n");
6167
 
                }
6168
 
                if (X)
6169
 
                {
6170
 
                        PutDoc("/X << /Type /Action /S /JavaScript /JS "+QString::number(X)+" 0 R >>\n");
6171
 
                }
6172
 
                if (D)
6173
 
                {
6174
 
                        PutDoc("/D << /Type /Action /S /JavaScript /JS "+QString::number(D)+" 0 R >>\n");
6175
 
                }
6176
 
                if (Fo)
6177
 
                {
6178
 
                        PutDoc("/Fo << /Type /Action /S /JavaScript /JS "+QString::number(Fo)+" 0 R >>\n");
6179
 
                }
6180
 
                if (Bl)
6181
 
                {
6182
 
                        PutDoc("/Bl << /Type /Action /S /JavaScript /JS "+QString::number(Bl)+" 0 R >>\n");
6183
 
                }
6184
 
                if ((annot.Type() == 3) || (annot.Type() == 5) || (annot.Type() == 6))
6185
 
                {
6186
 
                        if (K)
6187
 
                        {
6188
 
                                PutDoc("/K << /Type /Action /S /JavaScript /JS "+QString::number(K) + " 0 R >>\n");
6189
 
                        }
6190
 
                        if (F)
6191
 
                        {
6192
 
                                PutDoc("/F << /Type /Action /S /JavaScript /JS "+QString::number(F) + " 0 R >>\n");
6193
 
                        }
6194
 
                        if (V)
6195
 
                        {
6196
 
                                PutDoc("/V << /Type /Action /S /JavaScript /JS "+QString::number(V)+" 0 R >>\n");
6197
 
                        }
6198
 
                        if (C)
6199
 
                        {
6200
 
                                PutDoc("/C << /Type /Action /S /JavaScript /JS "+QString::number(C)+" 0 R >>\n");
6201
 
                        }
6202
 
                }
6203
 
                PutDoc(">>\nendobj\n");
6204
 
                return result;
6205
 
        }
6206
 
        return 0;
6207
 
}
6208
 
 
6209
 
uint PDFLibCore::WritePDFStream(const QString& cc)
6210
 
{
6211
 
        uint result = newObject();
6212
 
        QString tmp(cc);
6213
 
        if (Options.Compress)
6214
 
                tmp = CompressStr(&tmp);
6215
 
        StartObj(result);
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");
6220
 
        return result;
6221
 
}
6222
 
 
6223
 
uint PDFLibCore::WritePDFString(const QString& cc)
6224
 
{       
6225
 
        QString tmp;
6226
 
        for (int i = 0; i < cc.length(); ++i)
6227
 
        {
6228
 
                if (cc[i].unicode() > 255)
6229
 
                {
6230
 
                        tmp += "\\u";
6231
 
                        tmp += toHex(cc[i].row());
6232
 
                        tmp += toHex(cc[i].cell());
6233
 
                }
6234
 
                else
6235
 
                        tmp += cc[i];
6236
 
        }
6237
 
        return WritePDFStream(tmp);
6238
 
}
6239
 
 
6240
 
void PDFLibCore::PDF_xForm(uint objNr, double w, double h, QString im)
6241
 
{
6242
 
        StartObj(objNr);
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)
6247
 
        {
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");
6252
 
                PutDoc(">>\n");
6253
 
        }
6254
 
        if (Seite.FObjects.count() != 0)
6255
 
        {
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");
6260
 
                PutDoc(">>\n");
6261
 
        }
6262
 
        PutDoc(">>\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;
6266
 
        ResCount++;
6267
 
}
6268
 
 
6269
 
void PDFLibCore::PDF_Form(const QString& im) // unused? - av
6270
 
{
6271
 
        uint form = newObject();
6272
 
        StartObj(form);
6273
 
        PutDoc("<<\n");
6274
 
        PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
6275
 
        if (Seite.FObjects.count() != 0)
6276
 
        {
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");
6281
 
                PutDoc(">>\n");
6282
 
        }
6283
 
        PutDoc(">>\n");
6284
 
        PutDoc("/Length "+QString::number(im.length())+"\n");
6285
 
        PutDoc(">>\nstream\n"+EncStream(im, form)+"\nendstream\nendobj\n");
6286
 
}
6287
 
 
6288
 
void PDFLibCore::PDF_Bookmark(PageItem *currItem, double ypos)
6289
 
{
6290
 
        Bvie->SetAction(currItem, "/XYZ 0 "+FToStr(ypos)+" 0]");
6291
 
        BookMinUse = true;
6292
 
}
6293
 
 
6294
 
 
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)
6296
 
{
6297
 
        if (!Options.embedPDF)
6298
 
                return false;
6299
 
        
6300
 
#ifdef HAVE_PODOFO
6301
 
        try
6302
 
        {
6303
 
                PoDoFo::PdfError::EnableDebug( false );
6304
 
#if (PODOFO_VERSION == 0 && PODOFO_MINOR > 6)
6305
 
                PoDoFo::PdfError::EnableLogging( false );
6306
 
#endif
6307
 
#if (PODOFO_VERSION == 0 && PODOFO_MINOR == 5 && PODOFO_REVISION == 99) || PODOFO_MINOR > 5
6308
 
                PoDoFo::PdfMemDocument doc( fn.toLocal8Bit().data() );
6309
 
#else
6310
 
                PoDoFo::PdfDocument doc( fn.toLocal8Bit().data() );
6311
 
#endif
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"))
6316
 
                {
6317
 
                        resources = par->GetIndirectKey("Resources");
6318
 
                }
6319
 
                if (contents && contents->GetDataType() ==  PoDoFo::ePdfDataType_Dictionary)
6320
 
                {
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();
6327
 
                        uint xParents = 0;
6328
 
                        importedObjects[page->GetObject()->Reference()] = xObj;
6329
 
                        StartObj(xObj);
6330
 
                        PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1");
6331
 
                        PoDoFo::PdfRect pagesize = page->GetPageSize();
6332
 
                        int rotation = page->GetRotation();
6333
 
                        QMatrix pageM;
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'));
6340
 
                        PutDoc("]");
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') + " ");
6345
 
                        if (rotation == 0)
6346
 
                                PutDoc("0 0");
6347
 
                        else if (rotation == 90)
6348
 
                                PutDoc("0 1");
6349
 
                        else if (rotation == 180)
6350
 
                                PutDoc("1 1");
6351
 
                        else if (rotation == 270)
6352
 
                                PutDoc(QString::number(pagesize.GetHeight() / pagesize.GetWidth()) + " " + QString::number(1.0 - 1.0 / (pagesize.GetHeight() / pagesize.GetWidth())));
6353
 
                        else
6354
 
                                PutDoc("0 0");
6355
 
                        PutDoc("]");
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");
6359
 
                        if (nextObj)
6360
 
                        {
6361
 
                                PutDoc("\n/Group "); // PDF 1.4
6362
 
                                copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6363
 
                        }
6364
 
                        /*
6365
 
                        PoDoFo::PdfObject parents = page->GetObject()->GetIndirectKey("StructParents");
6366
 
                        if (parents)
6367
 
                        {
6368
 
                                xParents = newObject();
6369
 
                                PutDoc("\n/StructParents " + QString::number(xParents)); // required if page uses structured content
6370
 
                        }
6371
 
                        */
6372
 
                        char * mbuffer = NULL;
6373
 
#if (PODOFO_MAJOR == 0 && PODOFO_MINOR >= 8)
6374
 
                        PoDoFo::pdf_long mlen = 0;
6375
 
#elif defined(pdf_long)
6376
 
                        pdf_long mlen = 0;
6377
 
#else
6378
 
                        long mlen = 0;
6379
 
#endif
6380
 
                        stream->GetCopy(&mbuffer, &mlen);
6381
 
                        if (mbuffer[mlen-1] == '\n')
6382
 
                                --mlen;
6383
 
                        PutDoc("\n/Length " + QString::number(mlen));
6384
 
                        nextObj = contents->GetIndirectKey("Filter");
6385
 
                        if (nextObj)
6386
 
                        {
6387
 
                                PutDoc("\n/Filter ");
6388
 
                                copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6389
 
                        }
6390
 
                        nextObj = contents->GetIndirectKey("DecodeParms");
6391
 
                        if (nextObj)
6392
 
                        {
6393
 
                                PutDoc("\n/DecodeParms ");
6394
 
                                copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6395
 
                        }
6396
 
                        PutDoc("\n>>\nstream\n");
6397
 
                        {
6398
 
                                QByteArray buffer = QByteArray::fromRawData(mbuffer, mlen);
6399
 
                                EncodeArrayToStream(buffer, xObj);
6400
 
                        }  // disconnect QByteArray from raw data
6401
 
                        free (mbuffer);
6402
 
                        PutDoc("\nendstream\nendobj\n");
6403
 
                        // write resources
6404
 
                        if (resources)
6405
 
                        {
6406
 
                                copyPoDoFoObject(resources, xResources, importedObjects);
6407
 
                        }
6408
 
                        else
6409
 
                        {
6410
 
                                StartObj(xResources);
6411
 
                                PutDoc("<< >>\nendobj\n");
6412
 
                        }
6413
 
                        if (xParents)
6414
 
                        {
6415
 
                                // create structured parents
6416
 
                        }
6417
 
                        // write referenced objects
6418
 
                        PoDoFo::PdfVecObjects* allObjects = contents->GetOwner();
6419
 
                        for (int i=0; i < referencedObjects.size();  ++i)
6420
 
                        {
6421
 
                                nextObj = allObjects->GetObject(referencedObjects[i]);
6422
 
                                copyPoDoFoObject(nextObj, importedObjects[nextObj->Reference()], importedObjects);
6423
 
                        }
6424
 
                        
6425
 
                        Seite.ImgObjects[ResNam+"I"+QString::number(ResCount)] = xObj;
6426
 
                        imgInfo.ResNum = ResCount;
6427
 
                        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;
6437
 
                        
6438
 
                        return true;
6439
 
                }
6440
 
                else if (contents && contents->GetDataType() ==  PoDoFo::ePdfDataType_Array)//Page contents might be an array 
6441
 
                {
6442
 
                        QMap<PoDoFo::PdfReference, uint> importedObjects;
6443
 
                        QList<PoDoFo::PdfReference> referencedObjects;
6444
 
                        PoDoFo::PdfObject* nextObj;
6445
 
                        uint xObj = newObject();
6446
 
                        uint xResources = newObject();
6447
 
                        uint xParents = 0;
6448
 
                        importedObjects[page->GetObject()->Reference()] = xObj;
6449
 
                        StartObj(xObj);
6450
 
                        PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1");
6451
 
                        PoDoFo::PdfRect pagesize = page->GetPageSize();
6452
 
                        int rotation = page->GetRotation();
6453
 
                        QMatrix pageM;
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'));
6460
 
                        PutDoc("]");
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') + " ");
6465
 
                        if (rotation == 0)
6466
 
                                PutDoc("0 0");
6467
 
                        else if (rotation == 90)
6468
 
                                PutDoc("0 1");
6469
 
                        else if (rotation == 180)
6470
 
                                PutDoc("1 1");
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'));
6473
 
                        else
6474
 
                                PutDoc("0 0");
6475
 
                        PutDoc("]");
6476
 
                        PutDoc("\n/Resources " + QString::number(xResources) + " 0 R");
6477
 
                        nextObj = page->GetObject()->GetIndirectKey("Group");
6478
 
                        if (nextObj)
6479
 
                        {
6480
 
                                PutDoc("\n/Group "); // PDF 1.4
6481
 
                                copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6482
 
                        }
6483
 
                        
6484
 
                        char * mbuffer = NULL;
6485
 
                        long mlen = 0;
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)
6491
 
                        {
6492
 
                                if(carray[ci].HasStream())
6493
 
                                {
6494
 
                                        carray[ci].GetStream()->GetFilteredCopy ( &outMemStream );
6495
 
                                }
6496
 
                                else if(carray[ci].IsReference())
6497
 
                                {
6498
 
                                
6499
 
                                        nextObj = doc.GetObjects().GetObject(carray[ci].GetReference());
6500
 
                                
6501
 
                                        while(nextObj != NULL)
6502
 
                                        {
6503
 
                                        
6504
 
                                                if(nextObj->IsReference())
6505
 
                                                {
6506
 
                                                        nextObj = doc.GetObjects().GetObject(nextObj->GetReference());
6507
 
                                                }
6508
 
                                                else if(nextObj->HasStream())
6509
 
                                                {
6510
 
                                                        nextObj->GetStream()->GetFilteredCopy ( &outMemStream );
6511
 
                                                        break;
6512
 
                                                }
6513
 
                                        }
6514
 
                                
6515
 
                                }
6516
 
                        
6517
 
                        }
6518
 
                        // end of copy
6519
 
                        mlen = outMemStream.GetLength();
6520
 
                        mbuffer = outMemStream.TakeBuffer();
6521
 
//                      if (mbuffer[mlen-1] == '\n')
6522
 
//                              --mlen;
6523
 
                        PutDoc("\n/Length " + QString::number(mlen));
6524
 
/*
6525
 
 nextObj = contents->GetIndirectKey("Filter");
6526
 
                        if (nextObj)
6527
 
                        {
6528
 
                                PutDoc("\n/Filter ");
6529
 
                                copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6530
 
                        }
6531
 
                        nextObj = contents->GetIndirectKey("DecodeParms");
6532
 
                        if (nextObj)
6533
 
                        {
6534
 
                                PutDoc("\n/DecodeParms ");
6535
 
                                copyPoDoFoDirect(nextObj, referencedObjects, importedObjects);
6536
 
                        }
6537
 
*/
6538
 
                        PutDoc("\n>>\nstream\n");
6539
 
                        {
6540
 
                                QByteArray buffer = QByteArray::fromRawData(mbuffer, mlen);
6541
 
                                EncodeArrayToStream(buffer, xObj);
6542
 
                        }  // disconnect QByteArray from raw data
6543
 
                        free (mbuffer);
6544
 
                        PutDoc("\nendstream\nendobj\n");
6545
 
                        // write resources
6546
 
                        if (resources)
6547
 
                        {
6548
 
                                copyPoDoFoObject(resources, xResources, importedObjects);
6549
 
                        }
6550
 
                        else
6551
 
                        {
6552
 
                                StartObj(xResources);
6553
 
                                PutDoc("<< >>\nendobj\n");
6554
 
                        }
6555
 
                        if (xParents)
6556
 
                        {
6557
 
                                // create structured parents
6558
 
                        }
6559
 
                        // write referenced objects
6560
 
                        PoDoFo::PdfVecObjects* allObjects = contents->GetOwner();
6561
 
                        for (int i=0; i < referencedObjects.size();  ++i)
6562
 
                        {
6563
 
                                nextObj = allObjects->GetObject(referencedObjects[i]);
6564
 
                                copyPoDoFoObject(nextObj, importedObjects[nextObj->Reference()], importedObjects);
6565
 
                        }
6566
 
                        
6567
 
                        Seite.ImgObjects[ResNam+"I"+QString::number(ResCount)] = xObj;
6568
 
                        imgInfo.ResNum = ResCount;
6569
 
                        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;
6579
 
                        
6580
 
                        return true;
6581
 
                }
6582
 
                
6583
 
        }
6584
 
        catch(PoDoFo::PdfError& e)
6585
 
        {
6586
 
                qDebug() << "PoDoFo error!";
6587
 
                e.PrintErrorMsg();
6588
 
                assert (false);
6589
 
                return false;
6590
 
        }       
6591
 
#endif
6592
 
        return false;
6593
 
}
6594
 
 
6595
 
 
6596
 
#if HAVE_PODOFO
6597
 
 
6598
 
void PDFLibCore::copyPoDoFoDirect(const PoDoFo::PdfVariant* obj, QList<PoDoFo::PdfReference>& referencedObjects, QMap<PoDoFo::PdfReference, uint>& importedObjects)
6599
 
{
6600
 
        switch (obj->GetDataType())
6601
 
        {
6602
 
        case PoDoFo::ePdfDataType_Reference:
6603
 
                {
6604
 
                const PoDoFo::PdfReference reference(obj->GetReference());
6605
 
                uint objNr;
6606
 
                if (!importedObjects.contains(reference))
6607
 
                {
6608
 
                        objNr = newObject();
6609
 
                        importedObjects[reference] = objNr;
6610
 
                        referencedObjects.append(reference);
6611
 
                }
6612
 
                else
6613
 
                {
6614
 
                        objNr = importedObjects[reference];
6615
 
                }
6616
 
                PutDoc(" " + QString::number(objNr) + " 0 R");
6617
 
                }
6618
 
                break;
6619
 
        case PoDoFo::ePdfDataType_Array:
6620
 
                {
6621
 
                const PoDoFo::PdfArray& array(obj->GetArray());
6622
 
                PutDoc("[");
6623
 
                for (uint i=0; i < array.size(); ++i)
6624
 
                        copyPoDoFoDirect( &(array[i]), referencedObjects, importedObjects);
6625
 
                        PutDoc("]");
6626
 
                }
6627
 
                break;
6628
 
        case PoDoFo::ePdfDataType_Dictionary:
6629
 
                {
6630
 
                const PoDoFo::PdfDictionary& dict(obj->GetDictionary());
6631
 
                const PoDoFo::TKeyMap keys = dict.GetKeys();
6632
 
                PutDoc("<<");
6633
 
                for (PoDoFo::TCIKeyMap k=keys.begin(); k != keys.end(); ++k)
6634
 
                {
6635
 
                        PutDoc("\n/" + k->first.GetEscapedName());
6636
 
                        copyPoDoFoDirect(k->second, referencedObjects, importedObjects);
6637
 
                }
6638
 
                PutDoc(" >>");
6639
 
                }
6640
 
                break;
6641
 
        default:
6642
 
                {
6643
 
                std::string str;
6644
 
                obj->ToString(str);
6645
 
                PutDoc(" " + str);
6646
 
                }
6647
 
        }
6648
 
        
6649
 
}
6650
 
 
6651
 
void PDFLibCore::copyPoDoFoObject(const PoDoFo::PdfObject* obj, uint scObjID, QMap<PoDoFo::PdfReference, uint>& importedObjects)
6652
 
{
6653
 
        PoDoFo::PdfVecObjects* allObjects = obj->GetOwner();
6654
 
        QList<PoDoFo::PdfReference> referencedObjects;
6655
 
        StartObj(scObjID);
6656
 
        copyPoDoFoDirect(obj, referencedObjects, importedObjects);
6657
 
        if (obj->HasStream())
6658
 
        {
6659
 
                char * mbuffer = NULL;
6660
 
#if (PODOFO_MAJOR == 0 && PODOFO_MINOR >= 8)
6661
 
                        PoDoFo::pdf_long mlen = 0;
6662
 
#elif defined(pdf_long)
6663
 
                        pdf_long mlen = 0;
6664
 
#else
6665
 
                        long mlen = 0;
6666
 
#endif
6667
 
                const PoDoFo::PdfStream* stream = obj->GetStream();
6668
 
                stream->GetCopy(&mbuffer, &mlen);
6669
 
                if (mbuffer[mlen-1] == '\n')
6670
 
                        --mlen;
6671
 
                PutDoc("\nstream\n");
6672
 
                {
6673
 
                        QByteArray buffer = QByteArray::fromRawData(mbuffer, mlen);
6674
 
                        EncodeArrayToStream(buffer, scObjID);
6675
 
                }  // disconnect QByteArray from raw data
6676
 
                free (mbuffer);         
6677
 
                PutDoc("\nendstream");
6678
 
        }
6679
 
        PutDoc("\nendobj\n");
6680
 
        // recurse:
6681
 
        for (int i=0; i < referencedObjects.size();  ++i)
6682
 
        {
6683
 
                PoDoFo::PdfObject* nextObj = allObjects->GetObject(referencedObjects[i]);
6684
 
                copyPoDoFoObject(nextObj, importedObjects[nextObj->Reference()], importedObjects);
6685
 
        }
6686
 
}
6687
 
#endif
6688
 
 
6689
 
 
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)
6691
 
{
6692
 
        QFileInfo fi = QFileInfo(fn);
6693
 
        QString ext = fi.suffix().toLower();
6694
 
        if (ext.isEmpty())
6695
 
                ext = getImageType(fn);
6696
 
        ScImage img;
6697
 
        QString tmp, tmpy, dummy, cmd1, cmd2, BBox;
6698
 
        QChar  tc;
6699
 
        bool   found = false;
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;
6708
 
        int    origWidth = 1;
6709
 
        int    origHeight = 1;
6710
 
        ShIm   ImInfo;
6711
 
        ImInfo.ResNum = 0;
6712
 
        ImInfo.sxa = 0;
6713
 
        ImInfo.sya = 0;
6714
 
        if (Options.RecalcPic)
6715
 
                ImInfo.reso = Options.PicRes / 72.0;
6716
 
        else
6717
 
                ImInfo.reso = Options.Resolution / 72.0;
6718
 
        ImInfo.Width = 0;
6719
 
        ImInfo.Height = 0;
6720
 
        ImInfo.Page = 0;
6721
 
        ImInfo.xa = x;
6722
 
        ImInfo.ya = y;
6723
 
        ImInfo.origXsc = c->imageXScale();
6724
 
        ImInfo.origYsc = c->imageYScale();
6725
 
        ShIm   ImInfo2;
6726
 
        ImInfo2.origXsc = c->imageXScale();
6727
 
        ImInfo2.origYsc = c->imageYScale();
6728
 
        if (SharedImages.contains(fn))
6729
 
                ImInfo2 = SharedImages[fn];
6730
 
        if ((!SharedImages.contains(fn))
6731
 
                 || (fromAN)
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))
6737
 
        {
6738
 
                bool imageLoaded = false;
6739
 
                if ((extensionIndicatesPDF(ext) || ((extensionIndicatesEPSorPS(ext)) && (c->pixm.imgInfo.type != ImageType7))) && c->effectsInUse.count() == 0)
6740
 
                {
6741
 
                        if (extensionIndicatesEPSorPS(ext))
6742
 
                        {
6743
 
                                QString tmpFile = QDir::convertSeparators(ScPaths::getTempFileDir() + "sc.pdf");
6744
 
                                QStringList opts;
6745
 
                                opts.append("-dEPSCrop");
6746
 
                                if (Options.Version >= PDFOptions::PDFVersion_14)
6747
 
                                        opts.append( "-dCompatibilityLevel=1.4" );
6748
 
                                else
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" );
6753
 
                                else
6754
 
                                        opts.append( "-sProcessColorModel=/DeviceCMYK" ); */
6755
 
                                if (convertPS2PDF(fn, tmpFile, opts) == 0)
6756
 
                                {
6757
 
                                        imageLoaded = PDF_EmbeddedPDF(c, tmpFile, sx, sy, x, y, fromAN, Profil, Embedded, Intent, ImInfo, output);
6758
 
                                        QFile::remove(tmpFile);
6759
 
                                }
6760
 
                        }
6761
 
                        else
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;
6765
 
                }
6766
 
                if(!imageLoaded && extensionIndicatesPDF(ext) && c->effectsInUse.count() == 0 && Options.embedPDF)
6767
 
                        qDebug() << "Failed to embed the PDF file";
6768
 
                // no embedded PDF:
6769
 
                if (!imageLoaded)
6770
 
                { 
6771
 
                        if ((extensionIndicatesPDF(ext) || extensionIndicatesEPSorPS(ext)) && (c->pixm.imgInfo.type != ImageType7))
6772
 
                        {
6773
 
                                bitmapFromGS = true;
6774
 
                                if (Options.RecalcPic)
6775
 
                                {
6776
 
                                        afl = qMin(Options.PicRes, Options.Resolution);
6777
 
                                        ImInfo.reso = afl / 72.0;
6778
 
                                }
6779
 
                                else
6780
 
                                        afl = Options.Resolution;
6781
 
                                if (ext == "pdf")
6782
 
                                {
6783
 
                                        CMSettings cms(c->doc(), Profil, Intent);
6784
 
                                        if (Options.UseRGB)
6785
 
                                                imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6786
 
                                        else
6787
 
                                        {
6788
 
                                                if ((doc.HasCMS) && (Options.UseProfiles2))
6789
 
                                                        imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6790
 
                                                else
6791
 
                                                {
6792
 
                                                        if (Options.isGrayscale)
6793
 
                                                                imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6794
 
                                                        else
6795
 
                                                                imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::CMYKData, afl);
6796
 
                                                }
6797
 
                                        }
6798
 
                                }
6799
 
                                else
6800
 
                                {
6801
 
                                        QFile f(fn);
6802
 
                                        if (f.open(QIODevice::ReadOnly))
6803
 
                                        {
6804
 
                                                QDataStream ts(&f);
6805
 
                                                while (!ts.atEnd())
6806
 
                                                {
6807
 
                                                        tmp = readLinefromDataStream(ts);
6808
 
                                                        if (tmp.startsWith("%%BoundingBox:"))
6809
 
                                                        {
6810
 
                                                                found = true;
6811
 
                                                                BBox = tmp.remove("%%BoundingBox:");
6812
 
                                                        }
6813
 
                                                        if (!found)
6814
 
                                                        {
6815
 
                                                                if (tmp.startsWith("%%BoundingBox"))
6816
 
                                                                {
6817
 
                                                                        found = true;
6818
 
                                                                        BBox = tmp.remove("%%BoundingBox");
6819
 
                                                                }
6820
 
                                                        }
6821
 
                                                        if (tmp.startsWith("%%EndComments"))
6822
 
                                                                break;
6823
 
                                                }
6824
 
                                                f.close();
6825
 
                                                if (found)
6826
 
                                                {
6827
 
                                                        CMSettings cms(c->doc(), Profil, Intent);
6828
 
                                                        if (Options.UseRGB)
6829
 
                                                                imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6830
 
                                                        else
6831
 
                                                        {
6832
 
                                                                if ((doc.HasCMS) && (Options.UseProfiles2))
6833
 
                                                                        imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6834
 
                                                                else
6835
 
                                                                {
6836
 
                                                                        if (Options.isGrayscale)
6837
 
                                                                                imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, afl);
6838
 
                                                                        else
6839
 
                                                                                imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::CMYKData, afl);
6840
 
                                                                }
6841
 
                                                        }
6842
 
                                                }
6843
 
                                        }
6844
 
                                }
6845
 
                                if (!imageLoaded)
6846
 
                                {
6847
 
                                        PDF_Error_ImageLoadFailure(fn);
6848
 
                                        return false;
6849
 
                                }
6850
 
                                if (Options.RecalcPic)
6851
 
                                {
6852
 
                                        ImInfo.sxa = sx * (1.0 / ImInfo.reso);
6853
 
                                        ImInfo.sya = sy * (1.0 / ImInfo.reso);
6854
 
                                }
6855
 
                        }
6856
 
                        // not PS/PDF
6857
 
                        else
6858
 
                        {
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);
6866
 
                                if (Options.UseRGB)
6867
 
                                        imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, 72, &realCMYK);
6868
 
                                else
6869
 
                                {
6870
 
                                        if ((doc.HasCMS) && (Options.UseProfiles2))
6871
 
                                                imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RawData, 72, &realCMYK);
6872
 
                                        else
6873
 
                                        {
6874
 
                                                if (Options.isGrayscale)
6875
 
                                                        imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::RGBData, 72, &realCMYK);
6876
 
                                                else
6877
 
                                                        imageLoaded = img.LoadPicture(fn, c->pixm.imgInfo.actualPageNumber, cms, Embedded, true, ScImage::CMYKData, 72, &realCMYK);
6878
 
                                        }
6879
 
                                }
6880
 
                                if (!imageLoaded)
6881
 
                                {
6882
 
                                        PDF_Error_ImageLoadFailure(fn);
6883
 
                                        return false;
6884
 
                                }
6885
 
                                if ((Options.RecalcPic) && (Options.PicRes < (qMax(72.0 / c->imageXScale(), 72.0 / c->imageYScale()))))
6886
 
                                {
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)) )
6895
 
                                        {
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;
6901
 
                                        }
6902
 
                                        else
6903
 
                                                img.scaleImage(qRound(ax), qRound(ay));
6904
 
                                        ImInfo.sxa = sx * a2;
6905
 
                                        ImInfo.sya = sy * a1;
6906
 
                                }
6907
 
                                ImInfo.reso = 1;
6908
 
                        }
6909
 
                        bool hasColorEffect = false;
6910
 
                        if (c->effectsInUse.count() != 0)
6911
 
                        {
6912
 
                                for (int a = 0; a < c->effectsInUse.count(); ++a)
6913
 
                                {
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;
6922
 
                                }
6923
 
                        }
6924
 
                        if ((doc.HasCMS) && (Options.UseProfiles2))
6925
 
                        {
6926
 
                                if (!ICCProfiles.contains(Profil))
6927
 
                                {
6928
 
                                        ScImage img3;
6929
 
                                        int components = 0;
6930
 
                                        uint embeddedProfile = newObject();
6931
 
                                        StartObj(embeddedProfile);
6932
 
                                        QByteArray dataP;
6933
 
                                        struct ICCD dataD;
6934
 
                                        if ((Embedded) && (!Options.EmbeddedI))
6935
 
                                                img3.getEmbeddedProfile(fn, &dataP, &components);
6936
 
                                        if ((dataP.isEmpty()) || ((img.imgInfo.colorspace == ColorSpaceGray) && (hasColorEffect) && (components == 1)))
6937
 
                                        {
6938
 
                                                if (img.imgInfo.colorspace == ColorSpaceCMYK)
6939
 
                                                {
6940
 
                                                        QString profilePath;
6941
 
                                                        if (Embedded && ScCore->InputProfilesCMYK.contains(Options.ImageProf))
6942
 
                                                        {
6943
 
                                                                profilePath = ScCore->InputProfilesCMYK[Options.ImageProf];
6944
 
                                                                profInUse = Options.ImageProf;
6945
 
                                                        }
6946
 
                                                        else if (ScCore->InputProfilesCMYK.contains(Profil))
6947
 
                                                                profilePath = ScCore->InputProfilesCMYK[Profil];
6948
 
                                                        else
6949
 
                                                        {
6950
 
                                                                profilePath = ScCore->InputProfilesCMYK[c->doc()->CMSSettings.DefaultImageCMYKProfile];
6951
 
                                                                profInUse = c->doc()->CMSSettings.DefaultImageCMYKProfile;
6952
 
                                                        }
6953
 
                                                        loadRawBytes(profilePath, dataP);
6954
 
                                                        components = 4;
6955
 
                                                }
6956
 
                                                else
6957
 
                                                {
6958
 
                                                        QString profilePath;
6959
 
                                                        if (Embedded && ScCore->InputProfiles.contains(Options.ImageProf))
6960
 
                                                        {
6961
 
                                                                profilePath = ScCore->InputProfiles[Options.ImageProf];
6962
 
                                                                profInUse = Options.ImageProf;
6963
 
                                                        }
6964
 
                                                        else if (ScCore->InputProfiles.contains(Profil))
6965
 
                                                                profilePath = ScCore->InputProfiles[Profil];
6966
 
                                                        else
6967
 
                                                        {
6968
 
                                                                profilePath = ScCore->InputProfiles[c->doc()->CMSSettings.DefaultImageRGBProfile];
6969
 
                                                                profInUse = c->doc()->CMSSettings.DefaultImageRGBProfile;
6970
 
                                                        }
6971
 
                                                        loadRawBytes(profilePath, dataP);
6972
 
                                                        components = 3;
6973
 
                                                }
6974
 
                                        }
6975
 
                                        if (!ICCProfiles.contains(profInUse))
6976
 
                                        {
6977
 
                                                PutDoc("<<\n");
6978
 
                                                if ((Options.CompressMethod != PDFOptions::Compression_None) && Options.Compress)
6979
 
                                                {
6980
 
                                                        QByteArray compData = CompressArray(dataP);
6981
 
                                                        if (compData.size() > 0)
6982
 
                                                        {
6983
 
                                                                PutDoc("/Filter /FlateDecode\n");
6984
 
                                                                dataP = compData;
6985
 
                                                        }
6986
 
                                                }
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");
7000
 
                                                PutDoc("endobj\n");
7001
 
                                                ResCount++;
7002
 
                                        }
7003
 
                                        if (components == 1)
7004
 
                                                hasGrayProfile = true;
7005
 
                                }
7006
 
                                else
7007
 
                                {
7008
 
                                        if (ICCProfiles[Profil].components == 1)
7009
 
                                        {
7010
 
                                                if ((img.imgInfo.colorspace == ColorSpaceGray) && (hasColorEffect))
7011
 
                                                {
7012
 
                                                        profInUse = c->doc()->CMSSettings.DefaultImageRGBProfile;
7013
 
                                                        if (!ICCProfiles.contains(profInUse))
7014
 
                                                        {
7015
 
                                                                int components = 3;
7016
 
                                                                uint embeddedProfile = newObject();
7017
 
                                                                StartObj(embeddedProfile);
7018
 
                                                                QByteArray dataP;
7019
 
                                                                struct ICCD dataD;
7020
 
                                                                loadRawBytes(ScCore->InputProfiles[c->doc()->CMSSettings.DefaultImageRGBProfile], dataP);
7021
 
                                                                components = 3;
7022
 
                                                                PutDoc("<<\n");
7023
 
                                                                if ((Options.CompressMethod != PDFOptions::Compression_None) && Options.Compress)
7024
 
                                                                {
7025
 
                                                                        QByteArray compData = CompressArray(dataP);
7026
 
                                                                        if (compData.size() > 0)
7027
 
                                                                        {
7028
 
                                                                                PutDoc("/Filter /FlateDecode\n");
7029
 
                                                                                dataP = compData;
7030
 
                                                                        }
7031
 
                                                                }
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");
7045
 
                                                                PutDoc("endobj\n");
7046
 
                                                                ResCount++;
7047
 
                                                        }
7048
 
                                                }
7049
 
                                                else
7050
 
                                                        hasGrayProfile = true;
7051
 
                                        }
7052
 
                                }
7053
 
                        }
7054
 
                        QByteArray im2;
7055
 
                        ScImage img2;
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)
7062
 
                                alphaM = false;
7063
 
                        else
7064
 
                        {
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());
7068
 
                                if (!gotAlpha)
7069
 
                                {
7070
 
                                        PDF_Error_MaskLoadFailure(fn);
7071
 
                                        return false;
7072
 
                                }
7073
 
                                alphaM = !im2.isEmpty();
7074
 
                        }
7075
 
                        bool imgE = false;
7076
 
                        if ((Options.UseRGB) || (Options.isGrayscale))
7077
 
                                imgE = false;
7078
 
                        else
7079
 
                        {
7080
 
                                if ((Options.UseProfiles2) && (img.imgInfo.colorspace != ColorSpaceCMYK))
7081
 
                                        imgE = false;
7082
 
                                else
7083
 
                                        imgE = true;
7084
 
                        }
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())))))
7089
 
                        {
7090
 
                                ImInfo.sxa = sx * (1.0 / ImInfo.reso);
7091
 
                                ImInfo.sya = sy * (1.0 / ImInfo.reso);
7092
 
                        }
7093
 
                        uint maskObj = 0;
7094
 
                        if (alphaM)
7095
 
                        {
7096
 
                                bool compAlphaAvail = false;
7097
 
                                maskObj = newObject();
7098
 
                                StartObj(maskObj);
7099
 
                                PutDoc("<<\n/Type /XObject\n/Subtype /Image\n");
7100
 
                                if (Options.CompressMethod != PDFOptions::Compression_None)
7101
 
                                {
7102
 
                                        QByteArray compAlpha = CompressArray(im2);
7103
 
                                        if (compAlpha.size() > 0)
7104
 
                                        {
7105
 
                                                im2 = compAlpha;
7106
 
                                                compAlphaAvail = true;
7107
 
                                        }
7108
 
                                }
7109
 
                                if (Options.Version >= PDFOptions::PDFVersion_14)
7110
 
                                {
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");
7116
 
                                }
7117
 
                                else
7118
 
                                {
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");
7123
 
                                }
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;
7130
 
                                ResCount++;
7131
 
                        }
7132
 
                        uint imageObj = newObject();
7133
 
                        StartObj(imageObj);
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))
7138
 
                        {
7139
 
                                PutDoc("/ColorSpace "+ICCProfiles[profInUse].ICCArray+"\n");
7140
 
                                PutDoc("/Intent /");
7141
 
                                int inte2 = Intent;
7142
 
                                if (Options.EmbeddedI)
7143
 
                                        inte2 = Options.Intent2;
7144
 
                                static const QString cmsmode[] = {"Perceptual", "RelativeColorimetric", "Saturation", "AbsoluteColorimetric"};
7145
 
                                PutDoc(cmsmode[inte2] + "\n");
7146
 
                        }
7147
 
                        else
7148
 
                        {
7149
 
                                if (Options.UseRGB)
7150
 
                                        PutDoc("/ColorSpace /DeviceRGB\n");
7151
 
                                else
7152
 
                                {
7153
 
                                        if (Options.isGrayscale)
7154
 
                                                PutDoc("/ColorSpace /DeviceGray\n");
7155
 
                                        else
7156
 
                                                PutDoc("/ColorSpace /DeviceCMYK\n");
7157
 
                                }
7158
 
                        }
7159
 
                        enum PDFOptions::PDFCompression cm = Options.CompressMethod;
7160
 
                        bool exportToCMYK = false, exportToGrayscale = false, jpegUseOriginal = false;
7161
 
                        if (!Options.UseRGB && !(doc.HasCMS && Options.UseProfiles2 && !realCMYK))
7162
 
                        {
7163
 
                                exportToGrayscale = Options.isGrayscale;
7164
 
                                if (exportToGrayscale)
7165
 
                                        exportToCMYK      = !Options.isGrayscale;
7166
 
                                else
7167
 
                                        exportToCMYK      = !Options.UseRGB;
7168
 
                        }
7169
 
                        if (extensionIndicatesJPEG(ext) && (cm != PDFOptions::Compression_None))
7170
 
                        {
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()))))))
7172
 
                                {
7173
 
                                        jpegUseOriginal = true;
7174
 
                                        cm = PDFOptions::Compression_JPEG;
7175
 
                                }
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))
7180
 
                                {
7181
 
                                        jpegUseOriginal = false;
7182
 
                                        exportToCMYK = true;
7183
 
                                        cm = PDFOptions::Compression_JPEG;
7184
 
                                }*/
7185
 
                                else
7186
 
                                {
7187
 
                                        if (Options.CompressMethod == PDFOptions::Compression_JPEG)
7188
 
                                        {
7189
 
                                                if (realCMYK || !((Options.UseRGB) || (Options.UseProfiles2)))
7190
 
                                                {
7191
 
                                                        exportToGrayscale = Options.isGrayscale;
7192
 
                                                        if (exportToGrayscale)
7193
 
                                                                exportToCMYK      = !Options.isGrayscale;
7194
 
                                                        else
7195
 
                                                                exportToCMYK      = !Options.UseRGB;
7196
 
                                                }
7197
 
                                                cm = PDFOptions::Compression_JPEG;
7198
 
                                        }
7199
 
                                        else
7200
 
                                                cm = PDFOptions::Compression_ZIP;
7201
 
                                }
7202
 
                        }
7203
 
                        else
7204
 
                        {
7205
 
                                if ((Options.CompressMethod == PDFOptions::Compression_JPEG) || (Options.CompressMethod == PDFOptions::Compression_Auto))
7206
 
                                {
7207
 
                                        if (realCMYK || !((Options.UseRGB) || (Options.UseProfiles2)))
7208
 
                                        {
7209
 
                                                exportToGrayscale = Options.isGrayscale;
7210
 
                                                if (exportToGrayscale)
7211
 
                                                        exportToCMYK      = !Options.isGrayscale;
7212
 
                                                else
7213
 
                                                        exportToCMYK      = !Options.UseRGB;
7214
 
                                        }
7215
 
                                        cm = PDFOptions::Compression_JPEG;
7216
 
                                        /*if (Options.CompressMethod == PDFOptions::Compression_Auto)
7217
 
                                        {
7218
 
                                                QFileInfo fi(tmpFile);
7219
 
                                                if (fi.size() < im.size())
7220
 
                                                {
7221
 
                                                        im.resize(0);
7222
 
                                                        if (!loadRawBytes(tmpFile, im))
7223
 
                                                                return false;
7224
 
                                                        cm = PDFOptions::Compression_JPEG;
7225
 
                                                }
7226
 
                                                else
7227
 
                                                        cm = PDFOptions::Compression_ZIP;
7228
 
                                        }*/
7229
 
                                }
7230
 
                        }
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");
7241
 
                        if (alphaM)
7242
 
                        {
7243
 
                                if (Options.Version >= PDFOptions::PDFVersion_14)
7244
 
                                        PutDoc("/SMask "+QString::number(maskObj)+" 0 R\n");
7245
 
                                else
7246
 
                                        PutDoc("/Mask "+QString::number(maskObj)+" 0 R\n");
7247
 
                        }
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));
7255
 
                        else
7256
 
                                bytesWritten = WriteImageToStream(img, imageObj, exportToCMYK, exportToGrayscale, (!hasColorEffect && hasGrayProfile));
7257
 
                        PutDoc("\nendstream\nendobj\n");
7258
 
                        if (bytesWritten <= 0)
7259
 
                        {
7260
 
                                PDF_Error_ImageWriteFailure(fn);
7261
 
                                return false;
7262
 
                        }
7263
 
                        StartObj(lengthObj);
7264
 
                        PutDoc(QString("    %1\n").arg(bytesWritten));
7265
 
                        PutDoc("endobj\n");
7266
 
                        Seite.ImgObjects[ResNam+"I"+QString::number(ResCount)] = imageObj;
7267
 
                        ImInfo.ResNum = ResCount;
7268
 
                        ImInfo.Width = img.width();
7269
 
                        ImInfo.Height = img.height();
7270
 
                        ImInfo.xa = sx;
7271
 
                        ImInfo.ya = sy;
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);
7276
 
                ResCount++;
7277
 
        }
7278
 
        else
7279
 
        {
7280
 
                ImInfo = SharedImages[fn];
7281
 
                ImInfo.sxa *= sx / ImInfo.xa;
7282
 
                ImInfo.sya *= sy / ImInfo.ya;
7283
 
                /*
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;
7290
 
                */
7291
 
        }
7292
 
        QString embedPre = "";
7293
 
        if ((bitmapFromGS) || (isEmbeddedPDF)) // compensate gsResolution setting
7294
 
        {
7295
 
                if (isEmbeddedPDF)
7296
 
                {
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";
7302
 
                        else
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
7306
 
                }
7307
 
                if (c->asLatexFrame())
7308
 
                {
7309
 
                        ImInfo.sxa *= 1.0 / c->imageXScale();
7310
 
                        ImInfo.sya *= 1.0 / c->imageYScale();
7311
 
                }
7312
 
                else
7313
 
                {
7314
 
                        ImInfo.sxa *= PrefsManager::instance()->appPrefs.gs_Resolution / 72.0;
7315
 
                        ImInfo.sya *= PrefsManager::instance()->appPrefs.gs_Resolution / 72.0;
7316
 
                }
7317
 
        }
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");
7320
 
        else if (output)
7321
 
                *output = QString("");
7322
 
        return true;
7323
 
}
7324
 
 
7325
 
bool PDFLibCore::PDF_End_Doc(const QString& PrintPr, const QString& Name, int Components)
7326
 
{
7327
 
        QString tmp;
7328
 
        int ResO;
7329
 
        BookMItem* ip;
7330
 
        QTreeWidgetItem* pp;
7331
 
        QString Inhal = "";
7332
 
        QMap<int,QString> Inha;
7333
 
        if ((Bvie->topLevelItemCount() != 0) && (Options.Bookmarks) && (BookMinUse))
7334
 
        {
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);
7342
 
                while (*it)
7343
 
                {
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";
7348
 
                        if (ip->Pare == 0)
7349
 
                                Inhal += "/Parent 3 0 R\n";
7350
 
                        else
7351
 
                                Inhal += "/Parent "+QString::number(ip->Pare+Basis)+" 0 R\n";
7352
 
                        if (ip->Prev != 0)
7353
 
                                Inhal += "/Prev "+QString::number(ip->Prev+Basis)+" 0 R\n";
7354
 
                        if (ip->Next != 0)
7355
 
                                Inhal += "/Next "+QString::number(ip->Next+Basis)+" 0 R\n";
7356
 
                        if (ip->First != 0)
7357
 
                                Inhal += "/First "+QString::number(ip->First+Basis)+" 0 R\n";
7358
 
                        if (ip->Last != 0)
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))
7363
 
                        {
7364
 
                                QString action = ip->Action;
7365
 
                                if (action.isEmpty())
7366
 
                                {
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);
7370
 
                                }
7371
 
                                Inhal += "/Dest ["+QString::number(PageTree.Kids[ip->PageObject->OwnPage])+" 0 R "+action+"\n";
7372
 
                        }
7373
 
                        Inhal += ">>\nendobj\n";
7374
 
                        Inha[ip->ItemNr] = Inhal;
7375
 
                        ++it;
7376
 
                }
7377
 
                QMap<int,QString> ::ConstIterator contentIt;
7378
 
                for (contentIt = Inha.begin(); contentIt != Inha.end(); ++contentIt)
7379
 
                {
7380
 
                        XRef.append(bytesWritten());
7381
 
                        PutDoc(contentIt.value());
7382
 
                        ObjCounter++;
7383
 
                }
7384
 
        }
7385
 
        StartObj(ObjCounter);
7386
 
        ResO = ObjCounter;
7387
 
        PutDoc("<< /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
7388
 
        if ((Seite.ImgObjects.count() != 0) || (Seite.XObjects.count() != 0))
7389
 
        {
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");
7397
 
                PutDoc(">>\n");
7398
 
        }
7399
 
        if (Seite.FObjects.count() != 0)
7400
 
        {
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");
7405
 
                PutDoc(">>\n");
7406
 
        }
7407
 
        if (Shadings.count() != 0)
7408
 
        {
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");
7413
 
                PutDoc(">>\n");
7414
 
        }
7415
 
        if (Patterns.count() != 0)
7416
 
        {
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");
7421
 
                PutDoc(">>\n");
7422
 
        }
7423
 
        if (Transpar.count() != 0)
7424
 
        {
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");
7429
 
                PutDoc(">>\n");
7430
 
        }
7431
 
        if ((ICCProfiles.count() != 0) || (spotMap.count() != 0) || (spotMapReg.count() != 0))
7432
 
        {
7433
 
                PutDoc("/ColorSpace << \n");
7434
 
                QMap<QString,ICCD>::Iterator it3c;
7435
 
                if (ICCProfiles.count() != 0)
7436
 
                {
7437
 
                        for (it3c = ICCProfiles.begin(); it3c != ICCProfiles.end(); ++it3c)
7438
 
                                PutDoc("/"+it3c.value().ResName+" "+QString::number(it3c.value().ResNum)+" 0 R\n");
7439
 
                }
7440
 
                QMap<QString,SpotC>::Iterator it3sc;
7441
 
                if (spotMap.count() != 0)
7442
 
                {
7443
 
                        for (it3sc = spotMap.begin(); it3sc != spotMap.end(); ++it3sc)
7444
 
                                PutDoc("/"+it3sc.value().ResName+" "+QString::number(it3sc.value().ResNum)+" 0 R\n");
7445
 
                }
7446
 
                QMap<QString,SpotC>::Iterator it3scr;
7447
 
                if (spotMapReg.count() != 0)
7448
 
                {
7449
 
                        for (it3scr = spotMapReg.begin(); it3scr != spotMapReg.end(); ++it3scr)
7450
 
                                PutDoc("/"+it3scr.value().ResName+" "+QString::number(it3scr.value().ResNum)+" 0 R\n");
7451
 
                }
7452
 
                PutDoc(">>\n");
7453
 
        }
7454
 
        if ((Options.Version == PDFOptions::PDFVersion_15) && (Options.useLayers))
7455
 
        {
7456
 
                PutDoc("/Properties <<\n");
7457
 
                ScLayer ll;
7458
 
                ll.isPrintable = false;
7459
 
                ll.LNr = 0;
7460
 
                int Lnr = 0;
7461
 
                for (int la = 0; la < doc.Layers.count(); ++la)
7462
 
                {
7463
 
                        doc.Layers.levelToLayer(ll, la);
7464
 
                        PutDoc("/"+OCGEntries[ll.Name].Name+" "+QString::number(OCGEntries[ll.Name].ObjNum)+" 0 R\n");
7465
 
                        Lnr++;
7466
 
                }
7467
 
                PutDoc(">>\n");
7468
 
        }
7469
 
        PutDoc(">>\nendobj\n");
7470
 
        ObjCounter++;
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))
7476
 
        {
7477
 
                PutDoc("/First "+QString::number(Outlines.First)+" 0 R\n");
7478
 
                PutDoc("/Last "+QString::number(Outlines.Last)+" 0 R\n");
7479
 
        }
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 ");
7486
 
        PutDoc("]\n");
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)
7493
 
        {
7494
 
                QList<Dest>::Iterator vt;
7495
 
                for (vt = NamedDest.begin(); vt != NamedDest.end(); ++vt)
7496
 
                {
7497
 
                        if (PageTree.Kids.contains((*vt).Seite))
7498
 
                                PutDoc("/"+(*vt).Name+" ["+QString::number(PageTree.Kids[(*vt).Seite])+" 0 R /XYZ "+(*vt).Act+"]\n");
7499
 
                }
7500
 
        }
7501
 
        PutDoc(">>\nendobj\n");
7502
 
        XRef[5] = bytesWritten();
7503
 
        PutDoc("6 0 obj\n<<\n");
7504
 
        PutDoc("/Fields [ ");
7505
 
        if (Seite.FormObjects.count() != 0)
7506
 
        {
7507
 
                for (int fo = 0; fo < Seite.FormObjects.count(); ++fo)
7508
 
                        PutDoc(QString::number(Seite.FormObjects[fo])+" 0 R ");
7509
 
        }
7510
 
        PutDoc(" ]\n");
7511
 
        if (CalcFields.count() != 0)
7512
 
        {
7513
 
                PutDoc("/CO [ ");
7514
 
                for (int foc = 0; foc < CalcFields.count(); ++foc)
7515
 
                        PutDoc(QString::number(CalcFields[foc])+" 0 R ");
7516
 
                PutDoc(" ]\n");
7517
 
        }
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)
7522
 
        {
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)
7530
 
                {
7531
 
                        StartObj(ObjCounter);
7532
 
                        ObjCounter++;
7533
 
                        PutDoc("<< /S /JavaScript /JS "+QString::number(Fjav0)+" 0 R >>\n");
7534
 
                        PutDoc("endobj\n");
7535
 
                        Fjav0++;
7536
 
                }
7537
 
                StartObj(ObjCounter);
7538
 
                ObjCounter++;
7539
 
                PutDoc("<< /Names [ ");
7540
 
                QMap<QString,QString>::Iterator itja2;
7541
 
                for (itja2 = doc.JavaScripts.begin(); itja2 != doc.JavaScripts.end(); ++itja2)
7542
 
                {
7543
 
                        PutDoc(EncString("("+itja2.key()+")", 6)+" "+QString::number(Fjav)+" 0 R ");
7544
 
                        Fjav++;
7545
 
                }
7546
 
                PutDoc("] >>\nendobj\n");
7547
 
        }
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");
7553
 
        Threads.clear();
7554
 
        if (Options.Articles)
7555
 
        {
7556
 
                for (int ele = 0; ele < doc.DocItems.count(); ++ele)
7557
 
                {
7558
 
                        PageItem* tel = doc.DocItems.at(ele);
7559
 
                        if ((tel->asTextFrame()) && (tel->prevInChain() == 0) && (tel->nextInChain() != 0) &&
7560
 
                                        (!tel->inPdfArticle))
7561
 
                        {
7562
 
                                Beads.clear();
7563
 
                                struct Bead bd;
7564
 
                                int fir = ObjCounter + 1;
7565
 
                                int ccb = ObjCounter + 1;
7566
 
                                bd.Parent = ObjCounter;
7567
 
                                while (tel->nextInChain() != 0)
7568
 
                                {
7569
 
                                        if ((tel->OwnPage != -1) && PageTree.Kids.contains(tel->OwnPage))
7570
 
                                        {
7571
 
                                                bd.Next = ccb + 1;
7572
 
                                                bd.Prev = ccb - 1;
7573
 
                                                ccb++;
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()));
7579
 
                                                Beads.append(bd);
7580
 
                                        }
7581
 
                                        tel->inPdfArticle = true;
7582
 
                                        tel = tel->nextInChain();
7583
 
                                }
7584
 
                                bd.Next = ccb + 1;
7585
 
                                bd.Prev = ccb - 1;
7586
 
                                if ((tel->OwnPage != -1) && PageTree.Kids.contains(tel->OwnPage))
7587
 
                                {
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()));
7593
 
                                        Beads.append(bd);
7594
 
                                }
7595
 
                                tel->inPdfArticle = true;
7596
 
                                if (Beads.count() > 0)
7597
 
                                {
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;
7606
 
                                }
7607
 
                                for (int beac = 0; beac < Beads.count(); ++beac)
7608
 
                                {
7609
 
                                        StartObj(ObjCounter);
7610
 
                                        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");
7620
 
                                }
7621
 
                        }
7622
 
                }
7623
 
                for (int ele = 0; ele < doc.DocItems.count(); ++ele)
7624
 
                        doc.DocItems.at(ele)->inPdfArticle = false;
7625
 
        }
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))
7632
 
        {
7633
 
                XRef[8] = bytesWritten();
7634
 
                QStringList lay;
7635
 
                PutDoc("9 0 obj\n<<\n");
7636
 
                PutDoc("/D << /Order [ ");
7637
 
                ScLayer ll;
7638
 
                ll.isPrintable = false;
7639
 
                ll.LNr = 0;
7640
 
                int Lnr = 0;
7641
 
                for (int la = 0; la < doc.Layers.count(); ++la)
7642
 
                {
7643
 
                        doc.Layers.levelToLayer(ll, la);
7644
 
                        if (ll.isEditable)
7645
 
                                lay.prepend(QString::number(OCGEntries[ll.Name].ObjNum)+" 0 R ");
7646
 
                        Lnr++;
7647
 
                }
7648
 
                for (int layc = 0; layc < lay.count(); ++layc)
7649
 
                {
7650
 
                        PutDoc(lay[layc]);
7651
 
                }
7652
 
                PutDoc("]\n");
7653
 
                PutDoc("/OFF [ ");
7654
 
                QHash<QString, OCGInfo>::Iterator itoc;
7655
 
                for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
7656
 
                {
7657
 
                        if (!itoc.value().visible)
7658
 
                                PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
7659
 
                }
7660
 
                PutDoc("]\n");
7661
 
                PutDoc("/AS [<</Event /Print /OCGs [ ");
7662
 
                for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
7663
 
                {
7664
 
                        PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
7665
 
                }
7666
 
                PutDoc("] /Category [/Print]>> <</Event /View /OCGs [");
7667
 
                for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
7668
 
                {
7669
 
                        PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
7670
 
                }
7671
 
                PutDoc("] /Category [/View]>>]\n");
7672
 
                PutDoc(">>\n");
7673
 
                PutDoc("/OCGs [ ");
7674
 
                for (itoc = OCGEntries.begin(); itoc != OCGEntries.end(); ++itoc)
7675
 
                {
7676
 
                        PutDoc(QString::number(itoc.value().ObjNum)+" 0 R ");
7677
 
                }
7678
 
                PutDoc("]\n");
7679
 
                PutDoc(">>\nendobj\n");
7680
 
        }
7681
 
        if (Options.Version == PDFOptions::PDFVersion_X3)
7682
 
        {
7683
 
                StartObj(ObjCounter);
7684
 
                ObjCounter++;
7685
 
                QByteArray dataP;
7686
 
                loadRawBytes(PrintPr, dataP);
7687
 
                PutDoc("<<\n");
7688
 
                if (Options.Compress)
7689
 
                {
7690
 
                        QByteArray compData = CompressArray(dataP);
7691
 
                        if (compData.size() > 0)
7692
 
                        {
7693
 
                                PutDoc("/Filter /FlateDecode\n");
7694
 
                                dataP = compData;
7695
 
                        }
7696
 
                }
7697
 
                PutDoc("/Length "+QString::number(dataP.size()+1)+"\n");
7698
 
                PutDoc("/N "+QString::number(Components)+"\n");
7699
 
                PutDoc(">>\nstream\n");
7700
 
                PutDoc(dataP);
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");
7710
 
        }
7711
 
        uint StX = bytesWritten();
7712
 
        PutDoc("xref\n");
7713
 
        PutDoc("0 "+QString::number(ObjCounter)+"\n");
7714
 
        PutDoc("0000000000 65535 f \n");
7715
 
        for (int a = 0; a < XRef.count(); ++a)
7716
 
        {
7717
 
                if (XRef[a] > 0)
7718
 
                {
7719
 
                        tmp.sprintf("%10d", XRef[a]);
7720
 
                        tmp.replace(QRegExp(" "), "0");
7721
 
                        PutDoc(tmp+" 00000 n \n");
7722
 
                }
7723
 
                else
7724
 
                {
7725
 
                        // unused object, mark as free-never-to-be-used-again
7726
 
                        PutDoc("0000000000 65535 f \n");
7727
 
                }
7728
 
        }
7729
 
        PutDoc("trailer\n<<\n/Size "+QString::number(XRef.count()+1)+"\n");
7730
 
        QString IDs ="";
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();
7740
 
}
7741
 
 
7742
 
void PDFLibCore::PDF_Error(const QString& errorMsg)
7743
 
{
7744
 
        ErrorMessage = errorMsg;
7745
 
        if (!ScCore->usingGUI())
7746
 
                qDebug("%s", errorMsg.toLocal8Bit().data());
7747
 
}
7748
 
 
7749
 
void PDFLibCore::PDF_Error_WriteFailure(void)
7750
 
{
7751
 
        PDF_Error( tr("A write error occurred, please check available disk space") );
7752
 
}
7753
 
 
7754
 
void PDFLibCore::PDF_Error_ImageLoadFailure(const QString& fileName)
7755
 
{
7756
 
        PDF_Error( tr("Failed to load an image : %1").arg(fileName) );
7757
 
}
7758
 
 
7759
 
void PDFLibCore::PDF_Error_ImageWriteFailure(const QString& fileName)
7760
 
{
7761
 
        PDF_Error( tr("Failed to write an image : %1").arg(fileName) );
7762
 
}
7763
 
 
7764
 
void PDFLibCore::PDF_Error_MaskLoadFailure(const QString& fileName)
7765
 
{
7766
 
        PDF_Error( tr("Failed to load an image mask : %1").arg(fileName) );
7767
 
}
7768
 
 
7769
 
void PDFLibCore::PDF_Error_InsufficientMemory(void)
7770
 
{
7771
 
        PDF_Error( tr("Insufficient memory for processing an image"));
7772
 
}
7773
 
 
7774
 
bool PDFLibCore::closeAndCleanup()
7775
 
{
7776
 
        bool writeSucceed = (Spool.error() == QFile::NoError);
7777
 
        if (!writeSucceed)
7778
 
                PDF_Error_WriteFailure();
7779
 
        Spool.close();
7780
 
        if (abortExport || !writeSucceed)
7781
 
        {
7782
 
                if (Spool.exists())
7783
 
                        Spool.remove();
7784
 
        }
7785
 
        Seite.XObjects.clear();
7786
 
        Seite.ImgObjects.clear();
7787
 
        Seite.FObjects.clear();
7788
 
        Seite.AObjects.clear();
7789
 
        Seite.FormObjects.clear();
7790
 
        CalcFields.clear();
7791
 
        Shadings.clear();
7792
 
        Transpar.clear();
7793
 
        ICCProfiles.clear();
7794
 
        return writeSucceed;
7795
 
}
7796
 
 
7797
 
void PDFLibCore::cancelRequested()
7798
 
{
7799
 
        abortExport=true;
7800
 
}