Subversion Repositories Scribus

Rev

Rev 6922 | Rev 6926 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 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
*/
3133 fschmid 7
/***************************************************************************
8
                          pdflib.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
#include "pdflib.h"
25
#include "pdflib.moc"
26
 
27
#include "scconfig.h"
28
 
4229 craig 29
#include <string>
3133 fschmid 30
#include <qstring.h>
31
#include <qrect.h>
32
#include <qimage.h>
33
#include <qregexp.h>
34
#include <qdatetime.h>
35
#include <qfileinfo.h>
36
#include <qtextstream.h>
37
#include <qdir.h>
38
#include <cstdlib>
39
#include <cmath>
6451 fschmid 40
#include <qptrstack.h>
3133 fschmid 41
#ifdef HAVE_UNISTD_H
42
#include <unistd.h>
43
#endif
44
#include "rc4.h"
45
 
4028 cbradney 46
#include "commonstrings.h"
3670 cbradney 47
#include "page.h"
3133 fschmid 48
#include "pageitem.h"
49
#include "bookmwin.h"
5917 jghali 50
#include "scpaths.h"
3133 fschmid 51
#include "scribus.h"
5243 cbradney 52
#include "scribuscore.h"
3699 cbradney 53
#include "scribusdoc.h"
4028 cbradney 54
#include "multiprogressdialog.h"
3133 fschmid 55
#include "bookpalette.h"
5993 avox 56
#include "scfonts.h"
3133 fschmid 57
#include "util.h"
58
#include "prefsmanager.h"
3252 craig 59
#include "prefscontext.h"
3133 fschmid 60
#include "pdfoptions.h"
4007 fschmid 61
#include "sccolor.h"
6378 fschmid 62
#include "scpattern.h"
3133 fschmid 63
 
5184 avox 64
#include "text/nlsconfig.h"
65
 
3133 fschmid 66
using namespace std;
67
 
6562 fschmid 68
#include <tiffio.h>
3133 fschmid 69
 
6562 fschmid 70
 
4264 craig 71
PDFlib::PDFlib(ScribusDoc & docu)
72
        : QObject(&docu),
4223 craig 73
        doc(docu),
74
        ActPageP(0),
4264 craig 75
        Options(doc.PDF_Options),
4223 craig 76
        Bvie(0),
77
        ObjCounter(7),
78
        ResNam("RE"),
79
        ResCount(0),
80
        NDnam("LI"),
81
        NDnum(0),
82
        KeyGen(32),
83
        OwnerKey(32),
84
        UserKey(32),
85
        FileID(16),
86
        EncryKey(5),
87
        Encrypt(0),
88
        KeyLen(5),
89
        colorsToUse(),
90
        spotNam("Spot"),
91
        spotCount(0),
4225 craig 92
        progressDialog(0),
4223 craig 93
        abortExport(false),
5243 cbradney 94
        usingGUI(ScCore->usingGUI())
3133 fschmid 95
{
96
        Catalog.Outlines = 2;
97
        Catalog.PageTree = 3;
98
        Catalog.Dest = 4;
99
        PageTree.Count = 0;
100
        Outlines.First = 0;
101
        Outlines.Last = 0;
102
        Outlines.Count = 0;
103
        Seite.ObjNum = 0;
104
        Seite.Thumb = 0;
105
#ifdef HAVE_LIBZ
106
        CompAvail = true;
107
#else
108
        CompAvail = false;
109
#endif
110
        int kg_array[] = {0x28, 0xbf, 0x4e, 0x5e, 0x4e, 0x75, 0x8a, 0x41, 0x64, 0x00, 0x4e, 0x56, 0xff, 0xfa,
111
                          0x01, 0x08, 0x2e, 0x2e, 0x00, 0xb6, 0xd0, 0x68, 0x3e, 0x80, 0x2f, 0x0c, 0xa9, 0xfe,
112
                          0x64, 0x53, 0x69, 0x7a};
113
        for (int a = 0; a < 32; ++a)
114
                KeyGen[a] = kg_array[a];
4028 cbradney 115
        if (usingGUI)
116
        {
6260 fschmid 117
                progressDialog = new MultiProgressDialog( tr("Saving PDF"), CommonStrings::tr_Cancel, doc.scMW(), "pdfexportprogress");
4224 craig 118
                Q_CHECK_PTR(progressDialog);
119
                QStringList barNames, barTexts;
120
                barNames << "EMP" << "EP" << "ECPI";
5370 cbradney 121
                barTexts << tr("Exporting Master Page:") << tr("Exporting Page:") << tr("Exporting Items on Current Page:");
122
                QValueList<bool> barsNumeric;
123
                barsNumeric << true << true << false;
124
                progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
4224 craig 125
                connect(progressDialog->buttonCancel, SIGNAL(clicked()), this, SLOT(cancelRequested()));
4028 cbradney 126
        }
3133 fschmid 127
}
128
 
4224 craig 129
PDFlib::~PDFlib()
130
{
131
        delete progressDialog;
132
}
133
 
4229 craig 134
static inline QString FToStr(double c)
135
{
136
        return QString::number(c, 'f', 5);
137
};
138
 
4264 craig 139
bool PDFlib::doExport(const QString& fn, const QString& nam, int Components,
140
                                          const std::vector<int> & pageNs, const QMap<int,QPixmap> & thumbs)
3133 fschmid 141
{
142
        QPixmap pm;
143
        bool ret = false;
4028 cbradney 144
        int pc_exportpages=0;
145
        int pc_exportmasterpages=0;
4224 craig 146
        if (usingGUI)
147
                progressDialog->show();
5387 avox 148
        QMap<QString, QMap<uint, FPointArray> > usedFonts;
149
        usedFonts.clear();
150
        doc.getUsedFonts(usedFonts);
5781 cbradney 151
        if (PDF_Begin_Doc(fn, PrefsManager::instance()->appPrefs.AvailFonts, usedFonts, doc.scMW()->bookmarkPalette->BView))
3133 fschmid 152
        {
153
                QMap<int, int> pageNsMpa;
154
                for (uint a = 0; a < pageNs.size(); ++a)
155
                {
4264 craig 156
                        pageNsMpa.insert(doc.MasterNames[doc.Pages->at(pageNs[a]-1)->MPageNam], 0);
3133 fschmid 157
                }
4028 cbradney 158
                if (usingGUI)
3133 fschmid 159
                {
4028 cbradney 160
                        progressDialog->setOverallTotalSteps(pageNsMpa.count()+pageNs.size());
161
                        progressDialog->setTotalSteps("EMP", pageNsMpa.count());
162
                        progressDialog->setTotalSteps("EP", pageNs.size());
163
                        progressDialog->setOverallProgress(0);
164
                        progressDialog->setProgress("EMP", 0);
165
                        progressDialog->setProgress("EP", 0);
166
                }
4264 craig 167
                for (uint ap = 0; ap < doc.MasterPages.count() && !abortExport; ++ap)
4028 cbradney 168
                {
4264 craig 169
                        if (doc.MasterItems.count() != 0)
3133 fschmid 170
                        {
171
                                if (pageNsMpa.contains(ap))
172
                                {
5243 cbradney 173
                                        qApp->processEvents();
4264 craig 174
                                        PDF_TemplatePage(doc.MasterPages.at(ap));
4028 cbradney 175
                                        ++pc_exportmasterpages;
3133 fschmid 176
                                }
177
                        }
4546 subik 178
 
179
                        if (usingGUI)
180
                        {
4028 cbradney 181
                                progressDialog->setProgress("EMP", pc_exportmasterpages);
182
                                progressDialog->setOverallProgress(pc_exportmasterpages+pc_exportpages);
183
                        }
3133 fschmid 184
                }
4028 cbradney 185
                for (uint a = 0; a < pageNs.size() && !abortExport; ++a)
3133 fschmid 186
                {
4264 craig 187
                        if (doc.PDF_Options.Thumbnails)
3133 fschmid 188
                                pm = thumbs[pageNs[a]];
5243 cbradney 189
                        qApp->processEvents();
4028 cbradney 190
                        if (abortExport) break;
4264 craig 191
                        PDF_Begin_Page(doc.Pages->at(pageNs[a]-1), pm);
5243 cbradney 192
                        qApp->processEvents();
4028 cbradney 193
                        if (abortExport) break;
4649 fschmid 194
                        PDF_ProcessPage(doc.Pages->at(pageNs[a]-1), pageNs[a]-1, doc.PDF_Options.doClip);
5243 cbradney 195
                        qApp->processEvents();
4028 cbradney 196
                        if (abortExport) break;
3133 fschmid 197
                        PDF_End_Page();
4028 cbradney 198
                        pc_exportpages++;
199
                        if (usingGUI)
200
                        {
201
                                progressDialog->setProgress("EP", pc_exportpages);
202
                                progressDialog->setOverallProgress(pc_exportmasterpages+pc_exportpages);
203
                        }
3133 fschmid 204
                }
4028 cbradney 205
                ret = true;//Even when aborting we return true. Dont want that "couldnt write msg"
206
                if (!abortExport)
207
                {
4264 craig 208
                        if (doc.PDF_Options.Version == PDFOptions::PDFVersion_X3)
5243 cbradney 209
                                PDF_End_Doc(ScCore->PrinterProfiles[doc.PDF_Options.PrintProf], nam, Components);
4028 cbradney 210
                        else
211
                                PDF_End_Doc();
212
                }
3133 fschmid 213
                else
4028 cbradney 214
                        closeAndCleanup();
3133 fschmid 215
        }
4029 cbradney 216
        if (usingGUI)
217
                progressDialog->close();
3133 fschmid 218
        return ret;
219
}
220
 
221
void PDFlib::StartObj(int nr)
222
{
4229 craig 223
        XRef.append(bytesWritten());
224
        PutDoc(QString::number(nr)+ " 0 obj\n");
3133 fschmid 225
}
226
 
4229 craig 227
// Encode a string for inclusion in a
228
// PDF (literal) .
229
QString PDFlib::PDFEncode(const QString & in)
3133 fschmid 230
{
4229 craig 231
        QString tmp("");
3133 fschmid 232
        for (uint d = 0; d < in.length(); ++d)
233
        {
4229 craig 234
                QChar cc(in.at(d));
4230 craig 235
                if ((cc == '(') || (cc == ')') || (cc == '\\'))
236
                        tmp += '\\';
3133 fschmid 237
                tmp += cc;
238
        }
239
        return tmp;
240
}
241
 
4229 craig 242
QString PDFlib::EncStream(const QString & in, int ObjNum)
3133 fschmid 243
{
4229 craig 244
        if (in.length() < 1)
245
                return QString("");
4264 craig 246
        else if (!Options.Encrypt)
4229 craig 247
                return in;
248
        rc4_context_t rc4;
3133 fschmid 249
        int dlen = 0;
4229 craig 250
        QString tmp(in);
251
        QByteArray us(tmp.length());
252
        QByteArray ou(tmp.length());
253
        for (uint a = 0; a < tmp.length(); ++a)
254
                us[a] = uchar(QChar(tmp.at(a)));
255
        QByteArray data(10);
256
        if (KeyLen > 5)
257
                data.resize(21);
258
        for (int cd = 0; cd < KeyLen; ++cd)
3133 fschmid 259
        {
4229 craig 260
                data[cd] = EncryKey[cd];
261
                dlen++;
3133 fschmid 262
        }
4229 craig 263
        data[dlen++] = ObjNum;
264
        data[dlen++] = ObjNum >> 8;
265
        data[dlen++] = ObjNum >> 16;
266
        data[dlen++] = 0;
267
        data[dlen++] = 0;
268
        QByteArray step1(16);
269
        step1 = ComputeMD5Sum(&data);
270
        rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), QMIN(KeyLen+5, 16));
271
        rc4_encrypt(&rc4, reinterpret_cast<uchar*>(us.data()), reinterpret_cast<uchar*>(ou.data()), tmp.length());
272
        QString uk = "";
273
        for (uint cl = 0; cl < tmp.length(); ++cl)
274
                uk += QChar(ou[cl]);
275
        return uk;
3133 fschmid 276
}
277
 
5234 fschmid 278
QByteArray PDFlib::EncStreamArray(const QByteArray & in, int ObjNum)
279
{
280
        if (in.size() < 1)
281
                return QByteArray();
282
        else if (!Options.Encrypt)
283
                return in;
284
        rc4_context_t rc4;
285
        int dlen = 0;
286
        QByteArray out(in.size());
287
        QByteArray data(10);
288
        if (KeyLen > 5)
289
                data.resize(21);
290
        for (int cd = 0; cd < KeyLen; ++cd)
291
        {
292
                data[cd] = EncryKey[cd];
293
                dlen++;
294
        }
295
        data[dlen++] = ObjNum;
296
        data[dlen++] = ObjNum >> 8;
297
        data[dlen++] = ObjNum >> 16;
298
        data[dlen++] = 0;
299
        data[dlen++] = 0;
300
        QByteArray step1(16);
301
        step1 = ComputeMD5Sum(&data);
302
        rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), QMIN(KeyLen+5, 16));
303
        rc4_encrypt(&rc4, reinterpret_cast<uchar*>(in.data()), reinterpret_cast<uchar*>(out.data()), in.size());
304
        return out;
305
}
306
 
4229 craig 307
QString PDFlib::EncString(const QString & in, int ObjNum)
3133 fschmid 308
{
4264 craig 309
        if (!Options.Encrypt)
4229 craig 310
                return in;
311
        rc4_context_t rc4;
3133 fschmid 312
        QString tmp;
313
        int dlen = 0;
4229 craig 314
        if (in.length() < 3)
315
                return "<>";
316
        tmp = in.mid(1, in.length()-2);
317
        QByteArray us(tmp.length());
318
        QByteArray ou(tmp.length());
319
        for (uint a = 0; a < tmp.length(); ++a)
320
                us[a] = static_cast<uchar>(QChar(tmp.at(a)));
321
        QByteArray data(10);
322
        if (KeyLen > 5)
323
                data.resize(21);
324
        for (int cd = 0; cd < KeyLen; ++cd)
3133 fschmid 325
        {
4229 craig 326
                data[cd] = EncryKey[cd];
327
                dlen++;
3133 fschmid 328
        }
4229 craig 329
        data[dlen++] = ObjNum;
330
        data[dlen++] = ObjNum >> 8;
331
        data[dlen++] = ObjNum >> 16;
332
        data[dlen++] = 0;
333
        data[dlen++] = 0;
334
        QByteArray step1(16);
335
        step1 = ComputeMD5Sum(&data);
336
        rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), QMIN(KeyLen+5, 16));
337
        rc4_encrypt(&rc4, reinterpret_cast<uchar*>(us.data()), reinterpret_cast<uchar*>(ou.data()), tmp.length());
338
        QString uk = "";
339
        for (uint cl = 0; cl < tmp.length(); ++cl)
340
                uk += QChar(ou[cl]);
341
        tmp = "<"+String2Hex(&uk, false)+">";
3133 fschmid 342
        return tmp;
343
}
344
 
4229 craig 345
QString PDFlib::FitKey(const QString & pass)
3133 fschmid 346
{
4229 craig 347
        QString pw(pass);
3133 fschmid 348
        if (pw.length() < 32)
349
        {
350
                uint l = pw.length();
351
                for (uint a = 0; a < 32 - l; ++a)
352
                        pw += QChar(KeyGen[a]);
353
        }
354
        else
355
                pw = pw.left(32);
356
        return pw;
357
}
358
 
4229 craig 359
void PDFlib::CalcOwnerKey(const QString & Owner, const QString & User)
3133 fschmid 360
{
4229 craig 361
        rc4_context_t rc4;
362
        QString pw(FitKey(User));
363
        QString pw2(FitKey(Owner.isEmpty() ? User : Owner));
3133 fschmid 364
        QByteArray step1(16);
365
        step1 = ComputeMD5(pw2);
366
        if (KeyLen > 5)
367
        {
368
                for (int kl = 0; kl < 50; ++kl)
369
                        step1 = ComputeMD5Sum(&step1);
370
        }
371
        QByteArray us(32);
372
        QByteArray enk(16);
373
        if (KeyLen > 5)
374
        {
375
                for (uint a2 = 0; a2 < 32; ++a2)
376
                        OwnerKey[a2] = static_cast<uchar>(QChar(pw.at(a2)));
377
                for (int rl = 0; rl < 20; rl++)
378
                {
4229 craig 379
                        for (int j = 0; j < 16; j ++)
380
                                enk[j] = step1[j] ^ rl;
3133 fschmid 381
                        rc4_init(&rc4, reinterpret_cast<uchar*>(enk.data()), 16);
4229 craig 382
                        rc4_encrypt(&rc4, reinterpret_cast<uchar*>(OwnerKey.data()),
3133 fschmid 383
                                         reinterpret_cast<uchar*>(OwnerKey.data()), 32);
384
                }
385
        }
386
        else
387
        {
388
                for (uint a = 0; a < 32; ++a)
389
                        us[a] = static_cast<uchar>(QChar(pw.at(a)));
390
                rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), 5);
4546 subik 391
                rc4_encrypt(&rc4, reinterpret_cast<uchar*>(us.data()),
3133 fschmid 392
                                        reinterpret_cast<uchar*>(OwnerKey.data()), 32);
393
        }
394
}
395
 
4229 craig 396
void PDFlib::CalcUserKey(const QString & User, int Permission)
3133 fschmid 397
{
398
        rc4_context_t   rc4;
4229 craig 399
        QString pw(FitKey(User));
3133 fschmid 400
        QByteArray step1(16);
401
        QByteArray perm(4);
402
        uint perm_value = static_cast<uint>(Permission);
403
        perm[0] = perm_value;
404
        perm[1] = perm_value >> 8;
405
        perm[2] = perm_value >> 16;
406
        perm[3] = perm_value >> 24;
407
        for (uint a = 0; a < 32; ++a)
408
                pw += QChar(OwnerKey[a]);
409
        for (uint a1 = 0; a1 < 4; ++a1)
410
                pw += QChar(perm[a1]);
411
        for (uint a3 = 0; a3 < 16; ++a3)
412
                pw += QChar(FileID[a3]);
413
        step1 = ComputeMD5(pw);
414
        if (KeyLen > 5)
415
        {
416
                for (int kl = 0; kl < 50; ++kl)
417
                        step1 = ComputeMD5Sum(&step1);
418
                EncryKey.resize(16);
419
        }
420
        for (int a2 = 0; a2 < KeyLen; ++a2)
421
                EncryKey[a2] = step1[a2];
422
        if (KeyLen > 5)
423
        {
4229 craig 424
                QString pr2("");
3133 fschmid 425
                for (int kl3 = 0; kl3 < 32; ++kl3)
426
                        pr2 += QChar(KeyGen[kl3]);
427
                for (uint a4 = 0; a4 < 16; ++a4)
428
                        pr2 += QChar(FileID[a4]);
429
                step1 = ComputeMD5(pr2);
430
                QByteArray enk(16);
431
                for (uint a3 = 0; a3 < 16; ++a3)
432
                        UserKey[a3] = step1[a3];
433
                for (int rl = 0; rl < 20; rl++)
434
                {
4229 craig 435
                        for (int j = 0; j < 16; j ++)
436
                                enk[j] = EncryKey[j] ^ rl;
3133 fschmid 437
                        rc4_init(&rc4, reinterpret_cast<uchar*>(enk.data()), 16);
4229 craig 438
                        rc4_encrypt(&rc4, reinterpret_cast<uchar*>(UserKey.data()), reinterpret_cast<uchar*>(UserKey.data()), 16);
3133 fschmid 439
                }
440
        }
441
        else
442
        {
443
                rc4_init(&rc4, reinterpret_cast<uchar*>(step1.data()), 5);
4229 craig 444
                rc4_encrypt(&rc4, reinterpret_cast<uchar*>(KeyGen.data()), reinterpret_cast<uchar*>(UserKey.data()), 32);
3133 fschmid 445
        }
446
}
447
 
3829 cbradney 448
QByteArray PDFlib::ComputeMD5(const QString& in)
3133 fschmid 449
{
3829 cbradney 450
        uint inlen=in.length();
451
        QByteArray TBytes(inlen);
452
        for (uint a = 0; a < inlen; ++a)
3133 fschmid 453
                TBytes[a] = static_cast<uchar>(QChar(in.at(a)));
454
        return ComputeMD5Sum(&TBytes);
455
}
456
 
5387 avox 457
bool PDFlib::PDF_Begin_Doc(const QString& fn, SCFonts &AllFonts, QMap<QString, QMap<uint, FPointArray> > DocFonts, BookMView* vi)
3133 fschmid 458
{
4229 craig 459
        Spool.setName(fn);
3133 fschmid 460
        if (!Spool.open(IO_WriteOnly))
461
                return false;
4229 craig 462
        outStream.setDevice(&Spool);
3133 fschmid 463
        QString tmp;
464
        QString ok = "";
465
        QString uk = "";
466
        QFileInfo fd;
467
        QString fext;
468
        int a;
6407 fschmid 469
        inPattern = 0;
3133 fschmid 470
        Bvie = vi;
471
        BookMinUse = false;
472
        UsedFontsP.clear();
4264 craig 473
        if ((Options.Version == 15) && (Options.useLayers))
3133 fschmid 474
                ObjCounter = 10;
475
        else
476
                ObjCounter = 9;
4264 craig 477
        switch (Options.Version)
3133 fschmid 478
        {
479
                case 12:
480
                case 13:
4229 craig 481
                        PutDoc("%PDF-1.3\n");
3133 fschmid 482
                        break;
483
                case 14:
484
                        PutDoc("%PDF-1.4\n");
485
                        break;
486
                case 15:
487
                        PutDoc("%PDF-1.5\n");
488
                        break;
489
        }
4264 craig 490
        if (Options.Version == 12)
3133 fschmid 491
                ObjCounter++;
4229 craig 492
        PutDoc("%\xc7\xec\x8f\xa2\n");
3133 fschmid 493
        StartObj(1);
494
        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");
4264 craig 495
        if ((Options.Version == 15) && (Options.useLayers))
3133 fschmid 496
                PutDoc("/OCProperties 9 0 R\n");
4264 craig 497
        if (Options.Version == 12)
4229 craig 498
                PutDoc("/OutputIntents [ "+QString::number(ObjCounter-1)+" 0 R ]\n");
4197 fschmid 499
        PutDoc("/PageLayout ");
4264 craig 500
        switch (Options.PageLayout)
3133 fschmid 501
        {
4197 fschmid 502
                case PDFOptions::SinglePage:
503
                        PutDoc("/SinglePage\n");
504
                        break;
505
                case PDFOptions::OneColumn:
506
                        PutDoc("/OneColumn\n");
507
                        break;
508
                case PDFOptions::TwoColumnLeft:
509
                        PutDoc("/TwoColumnLeft\n");
510
                        break;
511
                case PDFOptions::TwoColumnRight:
512
                        PutDoc("/TwoColumnRight\n");
513
                        break;
514
        }
4264 craig 515
        if (Options.displayBookmarks)
4197 fschmid 516
                PutDoc("/PageMode /UseOutlines\n");
4264 craig 517
        else if (Options.displayFullscreen)
4197 fschmid 518
                PutDoc("/PageMode /FullScreen\n");
4264 craig 519
        else if (Options.displayThumbs)
4197 fschmid 520
                PutDoc("/PageMode /UseThumbs\n");
4264 craig 521
        else if ((Options.Version == 15) && (Options.displayLayers))
4197 fschmid 522
                        PutDoc("/PageMode /UseOC\n");
4264 craig 523
        if (!Options.openAction.isEmpty())
4197 fschmid 524
        {
4264 craig 525
                PutDoc("/OpenAction << /S /JavaScript /JS (this."+Options.openAction+"\\(\\)) >>\n");
3133 fschmid 526
        }
527
        PutDoc("/ViewerPreferences\n<<\n/PageDirection ");
4264 craig 528
        PutDoc( Options.Binding == 0 ? "/L2R\n" : "/R2L\n");
529
        if (Options.hideToolBar)
4201 fschmid 530
                PutDoc("/HideToolbar true\n");
4264 craig 531
        if (Options.hideMenuBar)
4201 fschmid 532
                PutDoc("/HideMenubar true\n");
4264 craig 533
        if (Options.fitWindow)
4201 fschmid 534
                PutDoc("/FitWindow true\n");
3133 fschmid 535
        PutDoc(" >>\n>>\nendobj\n");
3829 cbradney 536
        QString IDg(Datum);
4264 craig 537
        IDg += Options.Datei;
3133 fschmid 538
        IDg += "Scribus "+QString(VERSION);
6878 fschmid 539
        IDg += "Scribus PDF Library "+QString(VERSION);
4264 craig 540
        IDg += doc.documentInfo.getTitle();
541
        IDg += doc.documentInfo.getAuthor();
3133 fschmid 542
        IDg += "/False";
543
        FileID = ComputeMD5(IDg);
4264 craig 544
        if (Options.Encrypt)
3133 fschmid 545
        {
6166 fschmid 546
                if ((Options.Version == 14) || (Options.Version == 15))
547
                        KeyLen = 16;
548
                else
549
                        KeyLen = 5;
4264 craig 550
                CalcOwnerKey(Options.PassOwner, Options.PassUser);
551
                CalcUserKey(Options.PassUser, Options.Permissions);
3133 fschmid 552
                for (uint cl2 = 0; cl2 < 32; ++cl2)
553
                        ok += QChar(OwnerKey[cl2]);
554
                if (KeyLen > 5)
555
                {
556
                        for (uint cl3 = 0; cl3 < 16; ++cl3)
557
                                uk += QChar(UserKey[cl3]);
558
                        for (uint cl3r = 0; cl3r < 16; ++cl3r)
559
                                uk += QChar(KeyGen[cl3r]);
560
                }
561
                else
562
                {
563
                        for (uint cl = 0; cl < 32; ++cl)
564
                                uk += QChar(UserKey[cl]);
565
                }
566
        }
567
        QDate d = QDate::currentDate();
568
        Datum = "D:";
569
        tmp.sprintf("%4d", d.year());
570
        tmp.replace(QRegExp(" "), "0");
571
        Datum += tmp;
572
        tmp.sprintf("%2d", d.month());
573
        tmp.replace(QRegExp(" "), "0");
574
        Datum += tmp;
575
        tmp.sprintf("%2d", d.day());
576
        tmp.replace(QRegExp(" "), "0");
577
        Datum += tmp;
4229 craig 578
        tmp = QTime::currentTime().toString();
3133 fschmid 579
        tmp.replace(QRegExp(":"), "");
580
        Datum += tmp;
581
        StartObj(2);
582
        PutDoc("<<\n/Creator "+EncString("(Scribus "+QString(VERSION)+")",2)+"\n");
6890 fschmid 583
        PutDoc("/Producer "+EncString("(Scribus PDF Library "+QString(VERSION)+")",2)+"\n");
4718 fschmid 584
        QString docTitle = doc.documentInfo.getTitle();
585
        if ((Options.Version == 12) && (docTitle.isEmpty()))
586
                PutDoc("/Title "+EncString("("+doc.DocName+")",2)+"\n");
587
        else
588
                PutDoc("/Title "+EncString("("+doc.documentInfo.getTitle()+")",2)+"\n");
4264 craig 589
        PutDoc("/Author "+EncString("("+doc.documentInfo.getAuthor()+")",2)+"\n");
590
        PutDoc("/Keywords "+EncString("("+doc.documentInfo.getKeywords()+")",2)+"\n");
3133 fschmid 591
        PutDoc("/CreationDate "+EncString("("+Datum+")",2)+"\n");
592
        PutDoc("/ModDate "+EncString("("+Datum+")",2)+"\n");
4264 craig 593
        if (Options.Version == 12)
3133 fschmid 594
                PutDoc("/GTS_PDFXVersion (PDF/X-3:2002)\n");
595
        PutDoc("/Trapped /False\n>>\nendobj\n");
4229 craig 596
        for (int t = 0; t < 6; ++t)
597
                XRef.append(bytesWritten());
4264 craig 598
        if ((Options.Version == 15) && (Options.useLayers))
4229 craig 599
                XRef.append(bytesWritten());
4264 craig 600
        if (Options.Version == 12)
4229 craig 601
                XRef.append(bytesWritten());
4264 craig 602
        if (Options.Encrypt)
3133 fschmid 603
        {
604
                StartObj(ObjCounter);
605
                Encrypt = ObjCounter;
606
                ObjCounter++;
607
                PutDoc("<<\n/Filter /Standard\n");
608
                PutDoc( KeyLen > 5 ? "/R 3\n/V 2\n/Length 128\n" : "/R 2\n/V 1\n");
609
                PutDoc("/O <"+String2Hex(&ok)+">\n");
610
                PutDoc("/U <"+String2Hex(&uk)+">\n");
4264 craig 611
                PutDoc("/P "+QString::number(Options.Permissions)+"\n>>\nendobj\n");
3133 fschmid 612
        }
5387 avox 613
        QMap<QString, QMap<uint, FPointArray> > ReallyUsed;
3133 fschmid 614
        ReallyUsed.clear();
615
        PageItem* pgit;
4017 fschmid 616
        QMap<int, QString> ind2PDFabr;
4546 subik 617
        const QString tmpf[] = {"/Courier", "/Courier-Bold", "/Courier-Oblique", "/Courier-BoldOblique",
4017 fschmid 618
                                                                                                "/Helvetica", "/Helvetica-Bold", "/Helvetica-Oblique", "/Helvetica-BoldOblique",
4546 subik 619
                                                                                                "/Times-Roman", "/Times-Bold", "/Times-Italic", "/Times-BoldItalic",
4017 fschmid 620
                                                                                                "/ZapfDingbats", "/Symbol"};
621
        size_t ar = sizeof(tmpf) / sizeof(*tmpf);
622
        for (uint ax = 0; ax < ar; ++ax)
623
                ind2PDFabr[ax] = tmpf[ax];
4264 craig 624
        for (uint c = 0; c < doc.FrameItems.count(); ++c)
3133 fschmid 625
        {
4264 craig 626
                pgit = doc.FrameItems.at(c);
3133 fschmid 627
                if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
628
                {
4084 cbradney 629
                        if (pgit->isAnnotation())
630
                                StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
5292 fschmid 631
                        for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
3133 fschmid 632
                        {
5980 avox 633
                                ReallyUsed.insert(pgit->itemText.charStyle(e).font().scName(), DocFonts[pgit->itemText.charStyle(e).font().scName()]);
3133 fschmid 634
                        }
635
                }
636
        }
4264 craig 637
        for (uint c = 0; c < doc.MasterItems.count(); ++c)
3133 fschmid 638
        {
4264 craig 639
                pgit = doc.MasterItems.at(c);
3133 fschmid 640
                if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
641
                {
4084 cbradney 642
                        if (pgit->isAnnotation())
643
                                StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
5292 fschmid 644
                        for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
3133 fschmid 645
                        {
5980 avox 646
                                ReallyUsed.insert(pgit->itemText.charStyle(e).font().scName(), DocFonts[pgit->itemText.charStyle(e).font().scName()]);
3133 fschmid 647
                        }
648
                }
649
        }
4264 craig 650
        for (uint d = 0; d < doc.Items->count(); ++d)
3133 fschmid 651
        {
4264 craig 652
                pgit = doc.Items->at(d);
3133 fschmid 653
                if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
654
                {
4084 cbradney 655
                        if (pgit->isAnnotation())
656
                                StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
5292 fschmid 657
                        for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
3133 fschmid 658
                        {
5980 avox 659
                                ReallyUsed.insert(pgit->itemText.charStyle(e).font().scName(), DocFonts[pgit->itemText.charStyle(e).font().scName()]);
3133 fschmid 660
                        }
661
                }
662
        }
6407 fschmid 663
        QStringList patterns = doc.getUsedPatterns();
664
        for (uint c = 0; c < patterns.count(); ++c)
665
        {
666
                ScPattern pa = doc.docPatterns[patterns[c]];
667
                for (uint o = 0; o < pa.items.count(); o++)
668
                {
669
                        pgit = pa.items.at(o);
670
                        if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
671
                        {
672
                                if (pgit->isAnnotation())
673
                                        StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
674
                                for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
675
                                {
676
                                        ReallyUsed.insert(pgit->itemText.charStyle(e).font().scName(), DocFonts[pgit->itemText.charStyle(e).font().scName()]);
677
                                }
678
                        }
679
                }
680
        }
4017 fschmid 681
        a = 0;
682
        QMap<QString, QString>::Iterator itStd;
683
        for (itStd = StdFonts.begin(); itStd != StdFonts.end(); ++itStd)
684
        {
685
                StartObj(ObjCounter);
686
                PutDoc("<<\n/Type /Font\n/Subtype /Type1\n");
687
                PutDoc("/BaseFont "+itStd.key()+"\n");
688
                PutDoc(">>\nendobj\n");
4229 craig 689
                Seite.FObjects["FoStd"+QString::number(a)] = ObjCounter;
690
                itStd.data() = "FoStd"+QString::number(a);
4017 fschmid 691
                ObjCounter++;
692
                a++;
693
        }
5387 avox 694
        QMap<QString,QMap<uint, FPointArray> >::Iterator it;
3133 fschmid 695
        a = 0;
696
        for (it = ReallyUsed.begin(); it != ReallyUsed.end(); ++it)
697
        {
5980 avox 698
                ScFace::FontFormat fformat = AllFonts[it.key()].format();
699
                if ((AllFonts[it.key()].isOTF()) || (!AllFonts[it.key()].hasNames()) || (AllFonts[it.key()].subset()) || (Options.SubsetList.contains(it.key())))
3133 fschmid 700
                {
3829 cbradney 701
                        QString fon("");
5387 avox 702
                        QMap<uint,FPointArray>& RealGlyphs(it.data());
3133 fschmid 703
                        QMap<uint,FPointArray>::Iterator ig;
5387 avox 704
                        for (ig = RealGlyphs.begin(); ig != RealGlyphs.end(); ++ig)
3133 fschmid 705
                        {
706
                                FPoint np, np1, np2;
707
                                bool nPath = true;
5606 fschmid 708
                                fon = "";
3133 fschmid 709
                                if (ig.data().size() > 3)
710
                                {
5387 avox 711
                                        FPointArray gly = ig.data();
3133 fschmid 712
                                        QWMatrix mat;
713
                                        mat.scale(0.1, 0.1);
714
                                        gly.map(mat);
715
                                        for (uint poi = 0; poi < gly.size()-3; poi += 4)
716
                                        {
717
                                                if (gly.point(poi).x() > 900000)
718
                                                {
719
                                                        fon += "h\n";
720
                                                        nPath = true;
721
                                                        continue;
722
                                                }
723
                                                if (nPath)
724
                                                {
725
                                                        np = gly.point(poi);
726
                                                        fon += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
727
                                                        nPath = false;
728
                                                }
729
                                                np = gly.point(poi+1);
730
                                                np1 = gly.point(poi+3);
731
                                                np2 = gly.point(poi+2);
732
                                                fon += FToStr(np.x()) + " " + FToStr(-np.y()) + " " +
733
                                                         FToStr(np1.x()) + " " + FToStr(-np1.y()) + " " +
734
                                                         FToStr(np2.x()) + " " + FToStr(-np2.y()) + " c\n";
735
                                        }
736
                                        fon += "h f*\n";
737
                                        np = getMinClipF(&gly);
738
                                        np1 = getMaxClipF(&gly);
739
                                }
5606 fschmid 740
                                else
741
                                {
742
                                        fon = "h";
743
                                        np = FPoint(0, 0);
744
                                        np1 = FPoint(0, 0);
745
                                }
746
                                StartObj(ObjCounter);
747
                                ObjCounter++;
748
                                PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1\n");
749
                                PutDoc("/BBox [ "+FToStr(np.x())+" "+FToStr(-np.y())+" "+FToStr(np1.x())+ " "+FToStr(-np1.y())+" ]\n");
750
                                PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
751
                                PutDoc(">>\n");
752
                                if ((Options.Compress) && (CompAvail))
753
                                        fon = CompressStr(&fon);
754
                                PutDoc("/Length "+QString::number(fon.length()+1));
755
                                if ((Options.Compress) && (CompAvail))
756
                                        PutDoc("\n/Filter /FlateDecode");
757
                                PutDoc(" >>\nstream\n"+EncStream(fon, ObjCounter-1)+"\nendstream\nendobj\n");
5980 avox 758
                                Seite.XObjects[AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+QString::number(ig.key())] = ObjCounter-1;
3133 fschmid 759
                        }
760
                }
761
                else
762
                {
4229 craig 763
                        UsedFontsP.insert(it.key(), "/Fo"+QString::number(a));
5980 avox 764
                        if ((fformat == ScFace::PFB) && (Options.EmbedList.contains(it.key())))
3133 fschmid 765
                        {
3829 cbradney 766
                                QString fon("");
3133 fschmid 767
                                StartObj(ObjCounter);
768
                                QByteArray bb;
5980 avox 769
                                AllFonts[it.key()].RawData(bb);
3133 fschmid 770
                                uint posi;
771
                                for (posi = 6; posi < bb.size(); ++posi)
772
                                {
773
                                        if ((bb[posi] == static_cast<char>(0x80)) && (static_cast<int>(bb[posi+1]) == 2))
774
                                                break;
775
                                        fon += QChar(bb[posi]);
776
                                }
777
                                int len1 = fon.length();
778
                                uint ulen;
779
                                ulen = bb[posi+2] & 0xff;
780
                                ulen |= (bb[posi+3] << 8) & 0xff00;
781
                                ulen |= (bb[posi+4] << 16) & 0xff0000;
782
                                ulen |= (bb[posi+5] << 24) & 0xff000000;
783
                                if (ulen > bb.size())
784
                                        ulen = bb.size()-7;
785
                                posi += 6;
786
                                for (uint j = 0; j < ulen; ++j)
787
                                        fon += QChar(bb[posi++]);
788
                                posi += 6;
789
                                int len2 = fon.length()-len1;
790
                                for (uint j = posi; j < bb.size(); ++j)
791
                                {
792
                                        if ((bb[j] == static_cast<char>(0x80)) && (static_cast<int>(bb[j+1]) == 3))
793
                                                break;
794
                                        if (bb[j] == '\r')
795
                                                fon += "\n";
796
                                        else
797
                                                fon += QChar(bb[j]);
798
                                }
799
                                int len3 = fon.length()-len2-len1;
4264 craig 800
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 801
                                        fon = CompressStr(&fon);
4229 craig 802
                                PutDoc("<<\n/Length "+QString::number(fon.length()+1)+"\n");
803
                                PutDoc("/Length1 "+QString::number(len1)+"\n");
804
                                PutDoc("/Length2 "+QString::number(len2)+"\n");
805
                                PutDoc("/Length3 "+QString::number(len3)+"\n");
4264 craig 806
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 807
                                        PutDoc("/Filter /FlateDecode\n");
4229 craig 808
                                PutDoc(">>\nstream\n"+EncStream(fon,ObjCounter)+"\nendstream\nendobj\n");
3133 fschmid 809
                                ObjCounter++;
810
                        }
5980 avox 811
                        if ((fformat == ScFace::PFA) && (Options.EmbedList.contains(it.key())))
3133 fschmid 812
                        {
3829 cbradney 813
                                QString fon("");
814
                                QString fon2("");
815
                                QString tm("");
3133 fschmid 816
                                uint value;
817
                                bool ok = true;
818
                                StartObj(ObjCounter);
5980 avox 819
                                AllFonts[it.key()].EmbedFont(fon);
3133 fschmid 820
                                int len1 = fon.find("eexec")+5;
821
                                fon2 = fon.left(len1)+"\n";
822
                                int len2 = fon.find("0000000000000000000000000");
823
                                if (len2 == -1)
824
                                        len2 = fon.length()+1;
825
                                int count = 0;
826
                                for (int xx = len1; xx < len2-1; ++xx)
827
                                {
828
                                        tm = fon.at(xx);
829
                                        if ((tm == QChar(13)) || (tm == QChar(10)))
830
                                                continue;
831
                                        xx++;
832
                                        count++;
833
                                        tm += fon.at(xx);
834
                                        value = tm.toUInt(&ok, 16);
835
                                        fon2 += QChar(value);
836
                                }
837
                                fon2 += fon.mid(len2);
4264 craig 838
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 839
                                        fon2 = CompressStr(&fon2);
4229 craig 840
                                PutDoc("<<\n/Length "+QString::number(fon2.length()+1)+"\n");
841
                                PutDoc("/Length1 "+QString::number(len1+1)+"\n");
842
                                PutDoc("/Length2 "+QString::number(count)+"\n");
843
                                PutDoc(static_cast<int>(fon.length()-len2) == -1 ? QString("/Length3 0\n") : "/Length3 "+QString::number(fon.length()-len2)+"\n");
4264 craig 844
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 845
                                        PutDoc("/Filter /FlateDecode\n");
4229 craig 846
                                PutDoc(">>\nstream\n"+EncStream(fon2, ObjCounter)+"\nendstream\nendobj\n");
3133 fschmid 847
                                ObjCounter++;
848
                        }
5980 avox 849
                        if ((fformat == ScFace::SFNT || fformat == ScFace::TTCF) && (Options.EmbedList.contains(it.key())))
3133 fschmid 850
                        {
3829 cbradney 851
                                QString fon("");
3133 fschmid 852
                                StartObj(ObjCounter);
853
                                QByteArray bb;
5980 avox 854
                                AllFonts[it.key()].RawData(bb);
3133 fschmid 855
                                //AV: += and append() dont't work because they stop at '\0' :-(
856
                                for (unsigned int i=0; i < bb.size(); i++)
857
                                        fon += QChar(bb[i]);
858
                                int len = fon.length();
4264 craig 859
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 860
                                        fon = CompressStr(&fon);
861
                                //qDebug(QString("sfnt data: size=%1 before=%2 compressed=%3").arg(bb.size()).arg(len).arg(fon.length()));
4229 craig 862
                                PutDoc("<<\n/Length "+QString::number(fon.length()+1)+"\n");
863
                                PutDoc("/Length1 "+QString::number(len)+"\n");
4264 craig 864
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 865
                                        PutDoc("/Filter /FlateDecode\n");
4229 craig 866
                                PutDoc(">>\nstream\n"+EncStream(fon, ObjCounter)+"\nendstream\nendobj\n");
3133 fschmid 867
                                ObjCounter++;
868
                        }
869
                        StartObj(ObjCounter);
5387 avox 870
                        // TODO: think about QByteArray ScFace::getFontDescriptor() -- AV
3133 fschmid 871
                        PutDoc("<<\n/Type /FontDescriptor\n");
5980 avox 872
                        PutDoc("/FontName /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
6213 fschmid 873
                        PutDoc("/FontBBox [ "+AllFonts[it.key()].FontBBoxAsString()+" ]\n");
3133 fschmid 874
                        PutDoc("/Flags ");
5980 avox 875
                        //FIXME: isItalic() should be queried from ScFace, not from Qt -- AV
3544 avox 876
                        //QFontInfo fo = QFontInfo(it.data());
3133 fschmid 877
                        int pfl = 0;
5980 avox 878
                        if (AllFonts[it.key()].isFixedPitch())
3133 fschmid 879
                                pfl = pfl ^ 1;
3544 avox 880
                        //if (fo.italic())
6213 fschmid 881
                        if (AllFonts[it.key()].ItalicAngleAsString() != "0")
3133 fschmid 882
                                pfl = pfl ^ 64;
883
//                      pfl = pfl ^ 4;
884
                        pfl = pfl ^ 32;
4229 craig 885
                        PutDoc(QString::number(pfl)+"\n");
6213 fschmid 886
                        PutDoc("/Ascent "+AllFonts[it.key()].ascentAsString()+"\n");
887
                        PutDoc("/Descent "+AllFonts[it.key()].descentAsString()+"\n");
888
                        PutDoc("/CapHeight "+AllFonts[it.key()].capHeightAsString()+"\n");
889
                        PutDoc("/ItalicAngle "+AllFonts[it.key()].ItalicAngleAsString()+"\n");
890
//                      PutDoc("/Ascent "+QString::number(static_cast<int>(AllFonts[it.key()].ascent()))+"\n");
891
//                      PutDoc("/Descent "+QString::number(static_cast<int>(AllFonts[it.key()].descent()))+"\n");
892
//                      PutDoc("/CapHeight "+QString::number(static_cast<int>(AllFonts[it.key()].capHeight()))+"\n");
893
//                      PutDoc("/ItalicAngle "+AllFonts[it.key()].italicAngle()+"\n");
894
//                      PutDoc("/StemV "+ AllFonts[it.key()].stemV() + "\n");
895
                        PutDoc("/StemV 1\n");
5980 avox 896
                        if ((fformat == ScFace::SFNT || fformat == ScFace::TTCF) && (Options.EmbedList.contains(it.key())))
4229 craig 897
                                PutDoc("/FontFile2 "+QString::number(ObjCounter-1)+" 0 R\n");
5980 avox 898
                        if ((fformat == ScFace::PFB) && (Options.EmbedList.contains(it.key())))
4229 craig 899
                                PutDoc("/FontFile "+QString::number(ObjCounter-1)+" 0 R\n");
5980 avox 900
                        if ((fformat == ScFace::PFA) && (Options.EmbedList.contains(it.key())))
4229 craig 901
                                PutDoc("/FontFile "+QString::number(ObjCounter-1)+" 0 R\n");
3133 fschmid 902
                        PutDoc(">>\nendobj\n");
903
                        ObjCounter++;
4546 subik 904
/*                      if (!FT_Has_PS_Glyph_Names(AllFonts[it.key()])
3133 fschmid 905
                        {
906
                                StartObj(ObjCounter);
907
                                int chCount = 31;
908
                                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 ");
909
                                for (int ww = 31; ww < 256; ++ww)
910
                                {
4229 craig 911
                                        PutDoc(QString::number(static_cast<int>(AllFonts[it.key()]->CharWidth[itg.key()]*
3133 fschmid 912
                                                        1000))+" ");
913
                                        if (itg == gl.end())
914
                                                break;
915
                                        ++itg;
916
                                        chCount++;
917
                                }
918
                                PutDoc("]\nendobj\n");
919
                                ObjCounter++;
920
                                // put widths object
921
                                // encoding dictionary w/ base encoding w/o differences
922
                                StartObj(ObjCounter);
923
                                PutDoc("<<\n/Type /Font\n/Subtype ");
5980 avox 924
                                PutDoc((fformat == ScFace::SFNT || fformat == ScFace::TTCF) ? "/TrueType\n" : "/Type1\n");
4229 craig 925
                                PutDoc("/Name /Fo"+QString::number(a)+"\n");
5980 avox 926
                                PutDoc("/BaseFont /"+AllFonts[it.key()]->psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "" )+"\n");
3133 fschmid 927
                                //cf. widths:
928
                                PutDoc("/FirstChar 0\n");
4229 craig 929
                                PutDoc("/LastChar "+QString::number(chCount-1)+"\n");
930
                                PutDoc("/Widths "+QString::number(ObjCounter-1)+" 0 R\n");
931
                                PutDoc("/FontDescriptor "+QString::number(ObjCounter-2)+" 0 R\n");
3133 fschmid 932
                                PutDoc(">>\nendobj\n");
4229 craig 933
                                Seite.FObjects["Fo"+QString::number(a)] = ObjCounter;
3133 fschmid 934
                                ObjCounter++;
935
                        }
936
                        else */
937
//                      {
6301 avox 938
                                QMap<uint,std::pair<QChar,QString> > gl;
939
                                AllFonts[it.key()].glyphNames(gl);
940
                                int nglyphs = 0;
941
                                QMap<uint,std::pair<QChar,QString> >::Iterator gli;
942
                                for (gli = gl.begin(); gli != gl.end(); ++gli) {
943
                                        if (gli.key() > nglyphs)
944
                                                nglyphs = gli.key();
945
                                }
946
                                ++nglyphs;
6302 avox 947
//                              qDebug(QString("pdflib: nglyphs %1 max %2").arg(nglyphs).arg(AllFonts[it.key()].maxGlyph()));
3133 fschmid 948
                                uint FontDes = ObjCounter - 1;
6301 avox 949
                                uint Fcc = nglyphs / 224;
950
                                if ((nglyphs % 224) != 0)
3133 fschmid 951
                                        Fcc += 1;
952
                                for (uint Fc = 0; Fc < Fcc; ++Fc)
953
                                {
954
                                        StartObj(ObjCounter);
6301 avox 955
                                        int chCount = 32;
956
                                        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 ");
957
                                        for (int ww = 32; ww < 256; ++ww)
3133 fschmid 958
                                        {
6301 avox 959
                                                uint glyph = 224 * Fc + ww - 32;
960
                                                if (gl.contains(glyph))
961
                                                        PutDoc(QString::number(static_cast<int>(AllFonts[it.key()].glyphWidth(glyph)* 1000))+" ");
962
                                                else
963
                                                        PutDoc("0 ");
964
 
6302 avox 965
                                                chCount++;
6301 avox 966
                                                if (signed(glyph) == nglyphs-1)
3133 fschmid 967
                                                        break;
968
                                        }
969
                                        PutDoc("]\nendobj\n");
970
                                        ObjCounter++;
971
                                        StartObj(ObjCounter);
972
                                        ObjCounter++;
973
                                        PutDoc("<< /Type /Encoding\n");
974
//                                      PutDoc("/BaseEncoding /" + AllFonts[it.key()]->FontEnc + "\n");
6301 avox 975
                                        PutDoc("/Differences [ \n");
3133 fschmid 976
                                        int crc = 0;
6301 avox 977
                                        bool startOfSeq = true;
3133 fschmid 978
                                        for (int ww2 = 32; ww2 < 256; ++ww2)
979
                                        {
6301 avox 980
                                                uint glyph = 224 * Fc + ww2 - 32;
981
                                                if (gl[glyph].second != "")
6213 fschmid 982
                                                {
6301 avox 983
                                                        if (startOfSeq) {
984
                                                                PutDoc(QString::number(ww2)+" ");
985
                                                                startOfSeq = false;
986
                                                        }
987
                                                        PutDoc("/"+gl[glyph].second+" ");
988
                                                        crc++;
6213 fschmid 989
                                                }
6301 avox 990
                                                else {
991
                                                        startOfSeq = true;
992
                                                }
993
                                                if (signed(glyph) == nglyphs-1)
3133 fschmid 994
                                                        break;
995
                                                if (crc > 8)
996
                                                {
997
                                                        PutDoc("\n");
998
                                                        crc = 0;
999
                                                }
1000
                                        }
1001
                                        PutDoc("]\n");
4546 subik 1002
 
3133 fschmid 1003
                                        PutDoc(">>\nendobj\n");
1004
                                        StartObj(ObjCounter);
1005
                                        PutDoc("<<\n/Type /Font\n/Subtype ");
5980 avox 1006
                                        PutDoc((fformat == ScFace::SFNT || fformat == ScFace::TTCF) ? "/TrueType\n" : "/Type1\n");
4229 craig 1007
                                        PutDoc("/Name /Fo"+QString::number(a)+"S"+QString::number(Fc)+"\n");
5980 avox 1008
                                        PutDoc("/BaseFont /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
3133 fschmid 1009
                                        PutDoc("/FirstChar 0\n");
4229 craig 1010
                                        PutDoc("/LastChar "+QString::number(chCount-1)+"\n");
1011
                                        PutDoc("/Widths "+QString::number(ObjCounter-2)+" 0 R\n");
1012
                                        PutDoc("/Encoding "+QString::number(ObjCounter-1)+" 0 R\n");
1013
                                        PutDoc("/FontDescriptor "+QString::number(FontDes)+" 0 R\n");
3133 fschmid 1014
                                        PutDoc(">>\nendobj\n");
4229 craig 1015
                                        Seite.FObjects["Fo"+QString::number(a)+"S"+QString::number(Fc)] = ObjCounter;
3133 fschmid 1016
                                        ObjCounter++;
1017
                                } // for(Fc)
1018
//                      } // FT_Has_PS_Glyph_Names
1019
                }
1020
                a++;
1021
        }
4264 craig 1022
        if (Options.UseLPI)
3133 fschmid 1023
        {
1024
                StartObj(ObjCounter);
1025
                PutDoc("<<\n/Type /Halftone\n/HalftoneType 5\n");
4264 craig 1026
                QMap<QString,LPIData>::const_iterator itlp;
1027
                for (itlp = Options.LPISettings.constBegin(); itlp != Options.LPISettings.constEnd(); ++itlp)
3133 fschmid 1028
                {
1029
                        PutDoc("/"+itlp.key()+"\n<<\n/Type /Halftone\n/HalftoneType 1\n/Frequency ");
4229 craig 1030
                        PutDoc(QString::number(itlp.data().Frequency)+"\n/Angle "+QString::number(itlp.data().Angle)+"\n/SpotFunction ");
3829 cbradney 1031
                        QString func ("");
3133 fschmid 1032
                        switch (itlp.data().SpotFunc)
1033
                        {
1034
                                case 0:
1035
                                        func = "/SimpleDot";
1036
                                        break;
1037
                                case 1:
1038
                                        func = "/Line";
1039
                                        break;
1040
                                case 2:
1041
                                        func = "/Round";
1042
                                        break;
1043
                                case 3:
1044
                                        func = "/Ellipse";
1045
                                        break;
1046
                                default:
1047
                                        func = "/SimpleDot";
1048
                                        break;
1049
                        }
1050
                        PutDoc(func+"\n>>\n");
1051
                }
1052
                PutDoc("/Default\n<<\n/Type /Halftone\n/HalftoneType 1\n/Frequency 50\n/Angle 45\n/SpotFunction /Round\n>>\n");
1053
                PutDoc(">>\nendobj\n");
1054
                ObjCounter++;
1055
                StartObj(ObjCounter);
4229 craig 1056
                HTName = ResNam+QString::number(ResCount);
3133 fschmid 1057
                Transpar[HTName] = ObjCounter;
4229 craig 1058
                PutDoc("<< /Type /ExtGState\n/HT "+QString::number(ObjCounter-1)+" 0 R\n>>\nendobj\n");
3133 fschmid 1059
                ResCount++;
1060
                ObjCounter++;
1061
        }
5880 jghali 1062
        if ((doc.HasCMS) && (Options.UseProfiles))
3133 fschmid 1063
        {
1064
                StartObj(ObjCounter);
1065
                ObjCounter++;
1066
                QString dataP;
1067
                struct ICCD dataD;
5243 cbradney 1068
                loadText(ScCore->InputProfiles[Options.SolidProf], &dataP);
3133 fschmid 1069
                PutDoc("<<\n");
4264 craig 1070
                if ((Options.Compress) && (CompAvail))
3133 fschmid 1071
                {
1072
                        PutDoc("/Filter /FlateDecode\n");
1073
                        dataP = CompressStr(&dataP);
1074
                }
4229 craig 1075
                PutDoc("/Length "+QString::number(dataP.length()+1)+"\n");
4264 craig 1076
                PutDoc("/N "+QString::number(Options.SComp)+"\n");
4229 craig 1077
                PutDoc(">>\nstream\n"+EncStream(dataP, ObjCounter-1)+"\nendstream\nendobj\n");
3133 fschmid 1078
                StartObj(ObjCounter);
4229 craig 1079
                dataD.ResName = ResNam+QString::number(ResCount);
1080
                dataD.ICCArray = "[ /ICCBased "+QString::number(ObjCounter-1)+" 0 R ]";
3133 fschmid 1081
                dataD.ResNum = ObjCounter;
4264 craig 1082
                ICCProfiles[Options.SolidProf] = dataD;
4229 craig 1083
                PutDoc("[ /ICCBased "+QString::number(ObjCounter-1)+" 0 R ]\n");
3133 fschmid 1084
                PutDoc("endobj\n");
1085
                ResCount++;
1086
                ObjCounter++;
1087
        }
4264 craig 1088
        if (((Options.isGrayscale == false) && (Options.UseRGB == false)) && (Options.UseSpotColors))
3133 fschmid 1089
        {
4264 craig 1090
                doc.getUsedColors(colorsToUse);
3133 fschmid 1091
                ColorList::Iterator itf;
1092
                for (itf = colorsToUse.begin(); itf != colorsToUse.end(); ++itf)
1093
                {
1094
                        if ((colorsToUse[itf.key()].isSpotColor()) || (colorsToUse[itf.key()].isRegistrationColor()))
1095
                        {
1096
                                int cc, cm, cy, ck;
1097
                                struct SpotC spotD;
1098
                                colorsToUse[itf.key()].getCMYK(&cc, &cm, &cy, &ck);
1099
                                QString colorDesc = "{\ndup "+FToStr(static_cast<double>(cc) / 255)+"\nmul exch dup ";
1100
                                colorDesc += FToStr(static_cast<double>(cm) / 255)+"\nmul exch dup ";
1101
                                colorDesc += FToStr(static_cast<double>(cy) / 255)+"\nmul exch ";
1102
                                colorDesc += FToStr(static_cast<double>(ck) / 255)+" mul }";
1103
                                StartObj(ObjCounter);
1104
                                ObjCounter++;
1105
                                PutDoc("<<\n/FunctionType 4\n");
1106
                                PutDoc("/Domain [0.0 1.0]\n");
1107
                                PutDoc("/Range [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]\n");
4229 craig 1108
                                PutDoc("/Length "+QString::number(colorDesc.length()+1)+"\n");
1109
                                PutDoc(">>\nstream\n"+EncStream(colorDesc, ObjCounter-1)+"\nendstream\nendobj\n");
3133 fschmid 1110
                                StartObj(ObjCounter);
1111
                                PutDoc("[ /Separation /");
1112
                                if (colorsToUse[itf.key()].isRegistrationColor())
1113
                                        PutDoc("All");
1114
                                else
6471 fschmid 1115
                                        PutDoc(itf.key().simplifyWhiteSpace().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "#20" ));
4229 craig 1116
                                PutDoc(" /DeviceCMYK "+QString::number(ObjCounter-1)+" 0 R ]\nendobj\n");
1117
                                spotD.ResName = spotNam+QString::number(spotCount);
3133 fschmid 1118
                                spotD.ResNum = ObjCounter;
1119
                                spotMap.insert(itf.key(), spotD);
1120
                                spotCount++;
1121
                                ObjCounter++;
1122
                        }
1123
                }
1124
        }
6925 fschmid 1125
        if ((Options.cropMarks) || (Options.bleedMarks) || (Options.registrationMarks) || (Options.colorMarks) || (Options.docInfoMarks))
1126
        {
1127
                struct SpotC spotD;
1128
                StartObj(ObjCounter);
1129
                PutDoc("[ /Separation /All /DeviceCMYK\n");
1130
                PutDoc("<<\n/FunctionType 2\n");
1131
                PutDoc("/Domain [0.0 1.0]\n");
1132
                PutDoc("/Range [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]\n");
1133
                PutDoc("/C0 [0 0 0 0] \n");
1134
                PutDoc("/C1 [1 1 1 1] \n");
1135
                PutDoc("/N 1\n");
1136
                PutDoc(">>\n]\nendobj\n");
1137
                spotD.ResName = spotNam+QString::number(spotCount);
1138
                spotD.ResNum = ObjCounter;
1139
                spotMapReg.insert("Register", spotD);
1140
                spotCount++;
1141
                ObjCounter++;
1142
        }
4264 craig 1143
        if ((Options.Version == 15) && (Options.useLayers))
3133 fschmid 1144
        {
1145
                struct Layer ll;
1146
                struct OCGInfo ocg;
1147
                ll.isPrintable = false;
1148
                ll.LNr = 0;
1149
                int Lnr = 0;
3829 cbradney 1150
                QString ocgNam("oc");
4264 craig 1151
                uint docLayersCount=doc.Layers.count();
3829 cbradney 1152
                for (uint la = 0; la < docLayersCount; ++la)
3133 fschmid 1153
                {
3829 cbradney 1154
                        QString tmp("");
4264 craig 1155
                        Level2Layer(&doc, &ll, Lnr);
3133 fschmid 1156
                        ocg.Name = ocgNam+tmp.setNum(ll.LNr);
1157
                        ocg.ObjNum = ObjCounter;
1158
                        ocg.visible = ll.isViewable;
1159
                        OCGEntries.insert(ll.Name, ocg);
1160
                        StartObj(ObjCounter);
1161
                        ObjCounter++;
1162
                        PutDoc("<<\n");
1163
                        PutDoc("/Type /OCG\n");
1164
                        PutDoc("/Name ("+ll.Name+")\n");
1165
                        PutDoc(">>\nendobj\n");
1166
                        Lnr++;
1167
                }
1168
        }
1169
        return true;
1170
}
1171
 
4241 craig 1172
void PDFlib::PDF_TemplatePage(const Page* pag, bool )
3133 fschmid 1173
{
1174
        QString tmp;
1175
        ActPageP = pag;
1176
        PageItem* ite;
1177
        QPtrList<PageItem> PItems;
1178
        int Lnr = 0;
1179
        struct Layer ll;
1180
        ll.isPrintable = false;
1181
        ll.LNr = 0;
1182
        Inhalt = "";
1183
        Seite.AObjects.clear();
4264 craig 1184
        for (uint la = 0; la < doc.Layers.count(); ++la)
3133 fschmid 1185
        {
4264 craig 1186
                Level2Layer(&doc, &ll, Lnr);
1187
                PItems = doc.MasterItems;
3133 fschmid 1188
                if (ll.isPrintable)
1189
                {
4264 craig 1190
                        if ((Options.Version == 15) && (Options.useLayers))
3133 fschmid 1191
                                PutPage("/OC /"+OCGEntries[ll.Name].Name+" BDC\n");
1192
                        for (uint a = 0; a < PItems.count(); ++a)
1193
                        {
1194
                                Inhalt = "";
1195
                                ite =PItems.at(a);
1196
                                if (ite->LayerNr != ll.LNr)
1197
                                        continue;
4726 fschmid 1198
                                double x = pag->xOffset();
1199
                                double y = pag->yOffset();
1200
                                double w = pag->width();
1201
                                double h1 = pag->height();
4580 cbradney 1202
                                double ilw=ite->lineWidth();
4726 fschmid 1203
                                double x2 = ite->BoundingX - ilw / 2.0;
1204
                                double y2 = ite->BoundingY - ilw / 2.0;
1205
                                double w2 = ite->BoundingW + ilw;
1206
                                double h2 = ite->BoundingH + ilw;
1207
                                if (!( QMAX( x, x2 ) <= QMIN( x+w, x2+w2 ) && QMAX( y, y2 ) <= QMIN( y+h1, y2+h2 )))
3133 fschmid 1208
                                        continue;
1209
                                if (ite->ChangedMasterItem)
1210
                                        continue;
5685 cbradney 1211
                                if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
3133 fschmid 1212
                                        continue;
1213
                                PutPage("q\n");
5320 fschmid 1214
                                if ((ite->doOverprint) && (!Options.doOverprint) && (!Options.UseRGB))
1215
                                {
1216
                                        StartObj(ObjCounter);
1217
                                        QString ShName = ResNam+QString::number(ResCount);
1218
                                        Transpar[ShName] = ObjCounter;
1219
                                        ResCount++;
1220
                                        ObjCounter++;
1221
                                        PutDoc("<< /Type /ExtGState\n");
1222
                                        PutDoc("/OP true\n");
1223
                                        PutDoc("/op true\n");
1224
                                        PutDoc("/OPM 1\n");
1225
                                        PutDoc(">>\nendobj\n");
1226
                                        PutPage("/"+ShName+" gs\n");
1227
                                }
4679 fschmid 1228
/* Bookmarks on Master Pages do not make any sense */
1229
//                              if ((ite->isBookmark) && (Options.Bookmarks))
1230
//                                      PDF_Bookmark(ite, pag->height() - (ite->yPos() - pag->yOffset()));
5685 cbradney 1231
                                if (!ite->printEnabled() || ((ite->itemType() == PageItem::TextFrame) && (!pag->pageName().isEmpty())))
3133 fschmid 1232
                                {
1233
                                        PutPage("Q\n");
1234
                                        continue;
1235
                                }
4546 subik 1236
                                if (ite->fillColor() != CommonStrings::None)
3133 fschmid 1237
                                        PutPage(putColor(ite->fillColor(), ite->fillShade(), true));
4546 subik 1238
                                if (ite->lineColor() != CommonStrings::None)
3133 fschmid 1239
                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), false));
4580 cbradney 1240
                                Inhalt += FToStr(fabs(ite->lineWidth()))+" w\n";
3133 fschmid 1241
                                if (ite->DashValues.count() != 0)
1242
                                {
1243
                                        PutPage("[ ");
1244
                                        QValueList<double>::iterator it;
1245
                                        for ( it = ite->DashValues.begin(); it != ite->DashValues.end(); ++it )
1246
                                        {
1247
                                                int da = static_cast<int>(*it);
1248
                                                if (da != 0)
4229 craig 1249
                                                        PutPage(QString::number(da)+" ");
3133 fschmid 1250
                                        }
4229 craig 1251
                                        PutPage("] "+QString::number(static_cast<int>(ite->DashOffset))+" d\n");
3133 fschmid 1252
                                }
1253
                                else
1254
                                {
4580 cbradney 1255
                                        QString Dt = FToStr(QMAX(2*fabs(ite->lineWidth()), 1));
1256
                                        QString Da = FToStr(QMAX(6*fabs(ite->lineWidth()), 1));
3133 fschmid 1257
                                        switch (ite->PLineArt)
1258
                                        {
1259
                                                case Qt::SolidLine:
1260
                                                        PutPage("[] 0 d\n");
1261
                                                        break;
1262
                                                case Qt::DashLine:
1263
                                                        PutPage("["+Da+" "+Dt+"] 0 d\n");
1264
                                                        break;
1265
                                                case Qt::DotLine:
1266
                                                        PutPage("["+Dt+"] 0 d\n");
1267
                                                        break;
1268
                                                case Qt::DashDotLine:
1269
                                                        PutPage("["+Da+" "+Dt+" "+Dt+" "+Dt+"] 0 d\n");
1270
                                                        break;
1271
                                                case Qt::DashDotDotLine:
1272
                                                        PutPage("["+Da+" "+Dt+" "+Dt+" "+Dt+" "+Dt+" "+Dt+"] 0 d\n");
1273
                                                        break;
1274
                                                default:
1275
                                                        PutPage("[] 0 d\n");
1276
                                                        break;
1277
                                        }
1278
                                }
1279
                                switch (ite->PLineEnd)
1280
                                {
1281
                                        case Qt::FlatCap:
1282
                                                PutPage("0 J\n");
1283
                                                break;
1284
                                        case Qt::SquareCap:
1285
                                                PutPage("2 J\n");
1286
                                                break;
1287
                                        case Qt::RoundCap:
1288
                                                PutPage("1 J\n");
1289
                                                break;
1290
                                        default:
1291
                                                PutPage("0 J\n");
1292
                                                break;
1293
                                }
1294
                                switch (ite->PLineJoin)
1295
                                {
1296
                                        case Qt::MiterJoin:
1297
                                                PutPage("0 j\n");
1298
                                                break;
1299
                                        case Qt::BevelJoin:
1300
                                                PutPage("2 j\n");
1301
                                                break;
1302
                                        case Qt::RoundJoin:
1303
                                                PutPage("1 j\n");
1304
                                                break;
1305
                                        default:
1306
                                                PutPage("0 j\n");
1307
                                                break;
1308
                                }
3903 cbradney 1309
                                PutPage("1 0 0 1 "+FToStr(ite->xPos() - pag->xOffset())+" "+FToStr(pag->height() - (ite->yPos()  - pag->yOffset()))+" cm\n");
3934 cbradney 1310
                                if (ite->rotation() != 0)
3133 fschmid 1311
                                {
3934 cbradney 1312
                                        double sr = sin(-ite->rotation()* M_PI / 180.0);
1313
                                        double cr = cos(-ite->rotation()* M_PI / 180.0);
3133 fschmid 1314
                                        if ((cr * cr) < 0.000001)
1315
                                                cr = 0;
1316
                                        if ((sr * sr) < 0.000001)
1317
                                                sr = 0;
1318
                                        PutPage(FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+" 0 0 cm\n");
1319
                                }
1320
                                switch (ite->itemType())
1321
                                {
1322
                                        case PageItem::ImageFrame:
5748 fschmid 1323
                                                if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= 14))
1324
                                                        PutPage(PDF_TransparenzFill(ite));
4546 subik 1325
                                                if ((ite->fillColor() != CommonStrings::None) || (ite->GrType != 0))
3133 fschmid 1326
                                                {
1327
                                                        if (ite->GrType != 0)
1328
                                                                PutPage(PDF_Gradient(ite));
1329
                                                        else
1330
                                                        {
1331
                                                                PutPage(SetClipPath(ite));
1332
                                                                PutPage("h\nf*\n");
1333
                                                        }
1334
                                                }
1335
                                                PutPage("q\n");
1336
                                                if (ite->imageClip.size() != 0)
4744 fschmid 1337
                                                {
3133 fschmid 1338
                                                        PutPage(SetClipPathImage(ite));
4744 fschmid 1339
                                                        PutPage("h\nW*\nn\n");
1340
                                                }
1341
                                                PutPage(SetClipPath(ite));
3133 fschmid 1342
                                                PutPage("h\nW*\nn\n");
1343
                                                if (ite->imageFlippedH())
3934 cbradney 1344
                                                        PutPage("-1 0 0 1 "+FToStr(ite->width())+" 0 cm\n");
3133 fschmid 1345
                                                if (ite->imageFlippedV())
3934 cbradney 1346
                                                        PutPage("1 0 0 -1 0 "+FToStr(-ite->height())+" cm\n");
3133 fschmid 1347
                                                if ((ite->PicAvail) && (!ite->Pfile.isEmpty()))
3985 cbradney 1348
                                                        PutPage(PDF_Image(ite, ite->Pfile, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), false, ite->IProfile, ite->UseEmbedded, ite->IRender));
3133 fschmid 1349
                                                PutPage("Q\n");
4546 subik 1350
                                                if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
3133 fschmid 1351
                                                {
5748 fschmid 1352
                                                        if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= 14))
1353
                                                                PutPage(PDF_TransparenzStroke(ite));
4580 cbradney 1354
                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1355
                                                        {
1356
                                                                PutPage(SetClipPath(ite));
1357
                                                                PutPage("h\nS\n");
1358
                                                        }
1359
                                                        else
1360
                                                        {
4264 craig 1361
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1362
                                                                for (int it = ml.size()-1; it > -1; it--)
1363
                                                                {
6568 fschmid 1364
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1365
                                                                        {
1366
                                                                                PutPage(setStrokeMulti(&ml[it]));
1367
                                                                                PutPage(SetClipPath(ite));
1368
                                                                                PutPage("h\nS\n");
1369
                                                                        }
3133 fschmid 1370
                                                                }
1371
                                                        }
1372
                                                }
1373
                                                break;
1374
                                        case PageItem::TextFrame:
1375
                                                break;
1376
                                        case PageItem::Line:
5748 fschmid 1377
                                                if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= 14))
1378
                                                        PutPage(PDF_TransparenzStroke(ite));
3133 fschmid 1379
                                                if (ite->NamedLStyle.isEmpty())
1380
                                                {
1381
                                                        PutPage("0 0 m\n");
3934 cbradney 1382
                                                        PutPage(FToStr(ite->width())+" 0 l\n");
3133 fschmid 1383
                                                        PutPage("S\n");
1384
                                                }
1385
                                                else
1386
                                                {
4264 craig 1387
                                                        multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1388
                                                        for (int it = ml.size()-1; it > -1; it--)
1389
                                                        {
6568 fschmid 1390
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1391
                                                                        {
1392
                                                                                PutPage(setStrokeMulti(&ml[it]));
1393
                                                                                PutPage("0 0 m\n");
1394
                                                                                PutPage(FToStr(ite->width())+" 0 l\n");
1395
                                                                                PutPage("S\n");
1396
                                                                        }
3133 fschmid 1397
                                                        }
1398
                                                }
4061 craig 1399
                                                if (ite->startArrowIndex() != 0)
3133 fschmid 1400
                                                {
1401
                                                        QWMatrix arrowTrans;
4264 craig 1402
                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->startArrowIndex()-1)).points.copy();
3133 fschmid 1403
                                                        arrowTrans.translate(0, 0);
4580 cbradney 1404
                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1405
                                                        arrowTrans.scale(-1,1);
1406
                                                        arrow.map(arrowTrans);
4264 craig 1407
                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1408
                                                        {
1409
                                                                StartObj(ObjCounter);
4229 craig 1410
                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1411
                                                                Transpar[ShName] = ObjCounter;
1412
                                                                ResCount++;
1413
                                                                ObjCounter++;
1414
                                                                PutDoc("<< /Type /ExtGState\n");
1415
                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1416
                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1417
                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1418
                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1419
                                                                PutPage("/"+ShName+" gs\n");
1420
                                                        }
4016 fschmid 1421
                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1422
                                                        PutPage(SetClipPathArray(&arrow));
1423
                                                        PutPage("h\nf*\n");
1424
                                                }
4061 craig 1425
                                                if (ite->endArrowIndex() != 0)
3133 fschmid 1426
                                                {
1427
                                                        QWMatrix arrowTrans;
4264 craig 1428
                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->endArrowIndex()-1)).points.copy();
3934 cbradney 1429
                                                        arrowTrans.translate(ite->width(), 0);
4580 cbradney 1430
                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1431
                                                        arrow.map(arrowTrans);
4264 craig 1432
                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1433
                                                        {
1434
                                                                StartObj(ObjCounter);
4229 craig 1435
                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1436
                                                                Transpar[ShName] = ObjCounter;
1437
                                                                ResCount++;
1438
                                                                ObjCounter++;
1439
                                                                PutDoc("<< /Type /ExtGState\n");
1440
                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1441
                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1442
                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1443
                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1444
                                                                PutPage("/"+ShName+" gs\n");
1445
                                                        }
4016 fschmid 1446
                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1447
                                                        PutPage(SetClipPathArray(&arrow));
1448
                                                        PutPage("h\nf*\n");
1449
                                                }
1450
                                                break;
3232 cbradney 1451
                                        case PageItem::ItemType1:
1452
                                        case PageItem::ItemType3:
3133 fschmid 1453
                                        case PageItem::Polygon:
5748 fschmid 1454
                                                if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= 14))
1455
                                                        PutPage(PDF_TransparenzFill(ite));
3133 fschmid 1456
                                                if (ite->GrType != 0)
1457
                                                        PutPage(PDF_Gradient(ite));
1458
                                                else
1459
                                                {
4546 subik 1460
                                                        if (ite->fillColor() != CommonStrings::None)
3133 fschmid 1461
                                                        {
1462
                                                                PutPage(SetClipPath(ite));
1463
                                                                PutPage("h\nf*\n");
1464
                                                        }
1465
                                                }
4546 subik 1466
                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3133 fschmid 1467
                                                {
5748 fschmid 1468
                                                        if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= 14))
1469
                                                                PutPage(PDF_TransparenzStroke(ite));
4580 cbradney 1470
                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1471
                                                        {
1472
                                                                PutPage(SetClipPath(ite));
1473
                                                                PutPage("h\nS\n");
1474
                                                        }
1475
                                                        else
1476
                                                        {
4264 craig 1477
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1478
                                                                for (int it = ml.size()-1; it > -1; it--)
1479
                                                                {
6568 fschmid 1480
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1481
                                                                        {
1482
                                                                                PutPage(setStrokeMulti(&ml[it]));
1483
                                                                                PutPage(SetClipPath(ite));
1484
                                                                                PutPage("h\nS\n");
1485
                                                                        }
3133 fschmid 1486
                                                                }
1487
                                                        }
1488
                                                }
1489
                                                break;
1490
                                        case PageItem::PolyLine:
4658 fschmid 1491
                                                if (ite->PoLine.size() > 4) // && ((ite->PoLine.point(0) != ite->PoLine.point(1)) || (ite->PoLine.point(2) != ite->PoLine.point(3))))
3133 fschmid 1492
                                                {
5748 fschmid 1493
                                                        if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= 14))
1494
                                                                PutPage(PDF_TransparenzFill(ite));
3133 fschmid 1495
                                                        if (ite->GrType != 0)
1496
                                                                PutPage(PDF_Gradient(ite));
1497
                                                        else
1498
                                                        {
4546 subik 1499
                                                                if (ite->fillColor() != CommonStrings::None)
3133 fschmid 1500
                                                                {
1501
                                                                        PutPage(SetClipPath(ite));
1502
                                                                        PutPage("h\nf*\n");
1503
                                                                }
1504
                                                        }
1505
                                                }
4546 subik 1506
                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3133 fschmid 1507
                                                {
5748 fschmid 1508
                                                        if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= 14))
1509
                                                                PutPage(PDF_TransparenzStroke(ite));
4580 cbradney 1510
                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1511
                                                        {
1512
                                                                PutPage(SetClipPath(ite, false));
1513
                                                                PutPage("S\n");
1514
                                                        }
1515
                                                        else
1516
                                                        {
4264 craig 1517
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1518
                                                                for (int it = ml.size()-1; it > -1; it--)
1519
                                                                {
6568 fschmid 1520
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1521
                                                                        {
1522
                                                                                PutPage(setStrokeMulti(&ml[it]));
1523
                                                                                PutPage(SetClipPath(ite, false));
1524
                                                                                PutPage("S\n");
1525
                                                                        }
3133 fschmid 1526
                                                                }
1527
                                                        }
1528
                                                }
4061 craig 1529
                                                if (ite->startArrowIndex() != 0)
3133 fschmid 1530
                                                {
1531
                                                        FPoint Start = ite->PoLine.point(0);
1532
                                                        for (uint xx = 1; xx < ite->PoLine.size(); xx += 2)
1533
                                                        {
1534
                                                                FPoint Vector = ite->PoLine.point(xx);
1535
                                                                if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
1536
                                                                {
1537
                                                                        double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
1538
                                                                        QWMatrix arrowTrans;
4264 craig 1539
                                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->startArrowIndex()-1)).points.copy();
3133 fschmid 1540
                                                                        arrowTrans.translate(Start.x(), Start.y());
1541
                                                                        arrowTrans.rotate(r);
4580 cbradney 1542
                                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1543
                                                                        arrow.map(arrowTrans);
4264 craig 1544
                                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1545
                                                                        {
1546
                                                                                StartObj(ObjCounter);
4229 craig 1547
                                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1548
                                                                                Transpar[ShName] = ObjCounter;
1549
                                                                                ResCount++;
1550
                                                                                ObjCounter++;
1551
                                                                                PutDoc("<< /Type /ExtGState\n");
1552
                                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1553
                                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1554
                                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1555
                                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1556
                                                                                PutPage("/"+ShName+" gs\n");
1557
                                                                        }
4016 fschmid 1558
                                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1559
                                                                        PutPage(SetClipPathArray(&arrow));
1560
                                                                        PutPage("h\nf*\n");
1561
                                                                        break;
1562
                                                                }
1563
                                                        }
1564
                                                }
4061 craig 1565
                                                if (ite->endArrowIndex() != 0)
3133 fschmid 1566
                                                {
1567
                                                        FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
1568
                                                        for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
1569
                                                        {
1570
                                                                FPoint Vector = ite->PoLine.point(xx);
1571
                                                                if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
1572
                                                                {
1573
                                                                        double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
1574
                                                                        QWMatrix arrowTrans;
4264 craig 1575
                                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->endArrowIndex()-1)).points.copy();
3133 fschmid 1576
                                                                        arrowTrans.translate(End.x(), End.y());
1577
                                                                        arrowTrans.rotate(r);
4580 cbradney 1578
                                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1579
                                                                        arrow.map(arrowTrans);
4264 craig 1580
                                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1581
                                                                        {
1582
                                                                                StartObj(ObjCounter);
4229 craig 1583
                                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1584
                                                                                Transpar[ShName] = ObjCounter;
1585
                                                                                ResCount++;
1586
                                                                                ObjCounter++;
1587
                                                                                PutDoc("<< /Type /ExtGState\n");
1588
                                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1589
                                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1590
                                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1591
                                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1592
                                                                                PutPage("/"+ShName+" gs\n");
1593
                                                                        }
4016 fschmid 1594
                                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1595
                                                                        PutPage(SetClipPathArray(&arrow));
1596
                                                                        PutPage("h\nf*\n");
1597
                                                                        break;
1598
                                                                }
1599
                                                        }
1600
                                                }
1601
                                                break;
1602
                                        case PageItem::PathText:
1603
                                                if (ite->PoShow)
1604
                                                {
1605
                                                        if (ite->PoLine.size() > 3)
1606
                                                        {
1607
                                                                PutPage("q\n");
4546 subik 1608
                                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3133 fschmid 1609
                                                                {
5748 fschmid 1610
                                                                        if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= 14))
1611
                                                                                PutPage(PDF_TransparenzStroke(ite));
4580 cbradney 1612
                                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1613
                                                                        {
1614
                                                                                PutPage(SetClipPath(ite, false));
1615
                                                                                PutPage("S\n");
1616
                                                                        }
1617
                                                                        else
1618
                                                                        {
4264 craig 1619
                                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
6568 fschmid 1620
                                                                                for (int it = ml.size()-1; it > -1; it--)
1621
                                                                                {
1622
                                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
3133 fschmid 1623
                                                                                        {
6568 fschmid 1624
                                                                                                PutPage(setStrokeMulti(&ml[it]));
1625
                                                                                                PutPage(SetClipPath(ite, false));
1626
                                                                                                PutPage("S\n");
3133 fschmid 1627
                                                                                        }
6568 fschmid 1628
                                                                                }
3133 fschmid 1629
                                                                        }
1630
                                                                }
1631
                                                                PutPage("Q\n");
1632
                                                        }
1633
                                                }
5748 fschmid 1634
                                                if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= 14))
1635
                                                        PutPage(PDF_TransparenzFill(ite));
3200 cbradney 1636
                                                PutPage(setTextSt(ite, pag->pageNr(), pag));
3133 fschmid 1637
                                                break;
1638
                                        }
1639
                                PutPage("Q\n");
1640
                                StartObj(ObjCounter);
1641
                                ObjCounter++;
1642
                                PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1\n");
3200 cbradney 1643
                                PutDoc("/BBox [ 0 0 "+FToStr(ActPageP->width())+" "+FToStr(ActPageP->height())+" ]\n");
3133 fschmid 1644
                                PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
1645
                                if (Seite.ImgObjects.count() != 0)
1646
                                {
1647
                                        PutDoc("/XObject <<\n");
1648
                                        QMap<QString,int>::Iterator it;
1649
                                        for (it = Seite.ImgObjects.begin(); it != Seite.ImgObjects.end(); ++it)
4229 craig 1650
                                                PutDoc("/"+it.key()+" "+QString::number(it.data())+" 0 R\n");
3133 fschmid 1651
                                        PutDoc(">>\n");
1652
                                }
1653
                                if (Seite.FObjects.count() != 0)
1654
                                {
1655
                                        PutDoc("/Font << \n");
1656
                                        QMap<QString,int>::Iterator it2;
1657
                                        for (it2 = Seite.FObjects.begin(); it2 != Seite.FObjects.end(); ++it2)
4229 craig 1658
                                                PutDoc("/"+it2.key()+" "+QString::number(it2.data())+" 0 R\n");
3133 fschmid 1659
                                        PutDoc(">>\n");
1660
                                }
1661
                                if (Shadings.count() != 0)
1662
                                {
1663
                                        PutDoc("/Shading << \n");
1664
                                        QMap<QString,int>::Iterator it3;
1665
                                        for (it3 = Shadings.begin(); it3 != Shadings.end(); ++it3)
4229 craig 1666
                                                PutDoc("/"+it3.key()+" "+QString::number(it3.data())+" 0 R\n");
3133 fschmid 1667
                                        PutDoc(">>\n");
1668
                                }
6378 fschmid 1669
                                if (Patterns.count() != 0)
1670
                                {
1671
                                        PutDoc("/Pattern << \n");
1672
                                        QMap<QString,int>::Iterator it3p;
1673
                                        for (it3p = Patterns.begin(); it3p != Patterns.end(); ++it3p)
1674
                                                PutDoc("/"+it3p.key()+" "+QString::number(it3p.data())+" 0 R\n");
1675
                                        PutDoc(">>\n");
1676
                                }
3133 fschmid 1677
                                if (Transpar.count() != 0)
1678
                                {
1679
                                        PutDoc("/ExtGState << \n");
1680
                                        QMap<QString,int>::Iterator it3t;
1681
                                        for (it3t = Transpar.begin(); it3t != Transpar.end(); ++it3t)
4229 craig 1682
                                                PutDoc("/"+it3t.key()+" "+QString::number(it3t.data())+" 0 R\n");
3133 fschmid 1683
                                        PutDoc(">>\n");
1684
                                }
1685
                                if ((ICCProfiles.count() != 0) || (spotMap.count() != 0))
1686
                                {
1687
                                        PutDoc("/ColorSpace << \n");
1688
                                        QMap<QString,ICCD>::Iterator it3c;
1689
                                        if (ICCProfiles.count() != 0)
1690
                                        {
1691
                                                for (it3c = ICCProfiles.begin(); it3c != ICCProfiles.end(); ++it3c)
4229 craig 1692
                                                        PutDoc("/"+it3c.data().ResName+" "+QString::number(it3c.data().ResNum)+" 0 R\n");
3133 fschmid 1693
                                        }
1694
                                        QMap<QString,SpotC>::Iterator it3sc;
1695
                                        if (spotMap.count() != 0)
1696
                                        {
1697
                                        for (it3sc = spotMap.begin(); it3sc != spotMap.end(); ++it3sc)
4229 craig 1698
                                                PutDoc("/"+it3sc.data().ResName+" "+QString::number(it3sc.data().ResNum)+" 0 R\n");
3133 fschmid 1699
                                        }
1700
                                        PutDoc(">>\n");
1701
                                }
1702
                                PutDoc(">>\n");
4264 craig 1703
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 1704
                                        Inhalt = CompressStr(&Inhalt);
4229 craig 1705
                                PutDoc("/Length "+QString::number(Inhalt.length()+1));
4264 craig 1706
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 1707
                                        PutDoc("\n/Filter /FlateDecode");
4229 craig 1708
                                PutDoc(" >>\nstream\n"+EncStream(Inhalt, ObjCounter-1)+"\nendstream\nendobj\n");
5685 cbradney 1709
                                QString name = pag->pageName().simplifyWhiteSpace().replace( QRegExp("[\\s\\/\\{\\[\\]