Subversion Repositories Scribus

Rev

Rev 7069 | Rev 7103 | 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
        }
6943 fschmid 663
        if (Options.docInfoMarks)
664
        {
665
                StdFonts.insert("/Helvetica", "");
666
        }
6407 fschmid 667
        QStringList patterns = doc.getUsedPatterns();
668
        for (uint c = 0; c < patterns.count(); ++c)
669
        {
670
                ScPattern pa = doc.docPatterns[patterns[c]];
671
                for (uint o = 0; o < pa.items.count(); o++)
672
                {
673
                        pgit = pa.items.at(o);
674
                        if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
675
                        {
676
                                if (pgit->isAnnotation())
677
                                        StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
678
                                for (uint e = 0; e < static_cast<uint>(pgit->itemText.length()); ++e)
679
                                {
680
                                        ReallyUsed.insert(pgit->itemText.charStyle(e).font().scName(), DocFonts[pgit->itemText.charStyle(e).font().scName()]);
681
                                }
682
                        }
683
                }
684
        }
4017 fschmid 685
        a = 0;
686
        QMap<QString, QString>::Iterator itStd;
687
        for (itStd = StdFonts.begin(); itStd != StdFonts.end(); ++itStd)
688
        {
689
                StartObj(ObjCounter);
690
                PutDoc("<<\n/Type /Font\n/Subtype /Type1\n");
691
                PutDoc("/BaseFont "+itStd.key()+"\n");
692
                PutDoc(">>\nendobj\n");
4229 craig 693
                Seite.FObjects["FoStd"+QString::number(a)] = ObjCounter;
694
                itStd.data() = "FoStd"+QString::number(a);
4017 fschmid 695
                ObjCounter++;
696
                a++;
697
        }
5387 avox 698
        QMap<QString,QMap<uint, FPointArray> >::Iterator it;
3133 fschmid 699
        a = 0;
700
        for (it = ReallyUsed.begin(); it != ReallyUsed.end(); ++it)
701
        {
5980 avox 702
                ScFace::FontFormat fformat = AllFonts[it.key()].format();
7089 fschmid 703
                if ((!AllFonts[it.key()].hasNames()) || (Options.SubsetList.contains(it.key())))
3133 fschmid 704
                {
3829 cbradney 705
                        QString fon("");
5387 avox 706
                        QMap<uint,FPointArray>& RealGlyphs(it.data());
3133 fschmid 707
                        QMap<uint,FPointArray>::Iterator ig;
5387 avox 708
                        for (ig = RealGlyphs.begin(); ig != RealGlyphs.end(); ++ig)
3133 fschmid 709
                        {
710
                                FPoint np, np1, np2;
711
                                bool nPath = true;
5606 fschmid 712
                                fon = "";
3133 fschmid 713
                                if (ig.data().size() > 3)
714
                                {
5387 avox 715
                                        FPointArray gly = ig.data();
3133 fschmid 716
                                        QWMatrix mat;
717
                                        mat.scale(0.1, 0.1);
718
                                        gly.map(mat);
719
                                        for (uint poi = 0; poi < gly.size()-3; poi += 4)
720
                                        {
721
                                                if (gly.point(poi).x() > 900000)
722
                                                {
723
                                                        fon += "h\n";
724
                                                        nPath = true;
725
                                                        continue;
726
                                                }
727
                                                if (nPath)
728
                                                {
729
                                                        np = gly.point(poi);
730
                                                        fon += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
731
                                                        nPath = false;
732
                                                }
733
                                                np = gly.point(poi+1);
734
                                                np1 = gly.point(poi+3);
735
                                                np2 = gly.point(poi+2);
736
                                                fon += FToStr(np.x()) + " " + FToStr(-np.y()) + " " +
737
                                                         FToStr(np1.x()) + " " + FToStr(-np1.y()) + " " +
738
                                                         FToStr(np2.x()) + " " + FToStr(-np2.y()) + " c\n";
739
                                        }
740
                                        fon += "h f*\n";
741
                                        np = getMinClipF(&gly);
742
                                        np1 = getMaxClipF(&gly);
743
                                }
5606 fschmid 744
                                else
745
                                {
746
                                        fon = "h";
747
                                        np = FPoint(0, 0);
748
                                        np1 = FPoint(0, 0);
749
                                }
750
                                StartObj(ObjCounter);
751
                                ObjCounter++;
752
                                PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1\n");
753
                                PutDoc("/BBox [ "+FToStr(np.x())+" "+FToStr(-np.y())+" "+FToStr(np1.x())+ " "+FToStr(-np1.y())+" ]\n");
754
                                PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
755
                                PutDoc(">>\n");
756
                                if ((Options.Compress) && (CompAvail))
757
                                        fon = CompressStr(&fon);
758
                                PutDoc("/Length "+QString::number(fon.length()+1));
759
                                if ((Options.Compress) && (CompAvail))
760
                                        PutDoc("\n/Filter /FlateDecode");
761
                                PutDoc(" >>\nstream\n"+EncStream(fon, ObjCounter-1)+"\nendstream\nendobj\n");
5980 avox 762
                                Seite.XObjects[AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+QString::number(ig.key())] = ObjCounter-1;
3133 fschmid 763
                        }
764
                }
765
                else
766
                {
4229 craig 767
                        UsedFontsP.insert(it.key(), "/Fo"+QString::number(a));
5980 avox 768
                        if ((fformat == ScFace::PFB) && (Options.EmbedList.contains(it.key())))
3133 fschmid 769
                        {
3829 cbradney 770
                                QString fon("");
3133 fschmid 771
                                StartObj(ObjCounter);
772
                                QByteArray bb;
5980 avox 773
                                AllFonts[it.key()].RawData(bb);
3133 fschmid 774
                                uint posi;
775
                                for (posi = 6; posi < bb.size(); ++posi)
776
                                {
777
                                        if ((bb[posi] == static_cast<char>(0x80)) && (static_cast<int>(bb[posi+1]) == 2))
778
                                                break;
779
                                        fon += QChar(bb[posi]);
780
                                }
781
                                int len1 = fon.length();
782
                                uint ulen;
783
                                ulen = bb[posi+2] & 0xff;
784
                                ulen |= (bb[posi+3] << 8) & 0xff00;
785
                                ulen |= (bb[posi+4] << 16) & 0xff0000;
786
                                ulen |= (bb[posi+5] << 24) & 0xff000000;
787
                                if (ulen > bb.size())
788
                                        ulen = bb.size()-7;
789
                                posi += 6;
790
                                for (uint j = 0; j < ulen; ++j)
791
                                        fon += QChar(bb[posi++]);
792
                                posi += 6;
793
                                int len2 = fon.length()-len1;
794
                                for (uint j = posi; j < bb.size(); ++j)
795
                                {
796
                                        if ((bb[j] == static_cast<char>(0x80)) && (static_cast<int>(bb[j+1]) == 3))
797
                                                break;
798
                                        if (bb[j] == '\r')
799
                                                fon += "\n";
800
                                        else
801
                                                fon += QChar(bb[j]);
802
                                }
803
                                int len3 = fon.length()-len2-len1;
4264 craig 804
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 805
                                        fon = CompressStr(&fon);
4229 craig 806
                                PutDoc("<<\n/Length "+QString::number(fon.length()+1)+"\n");
807
                                PutDoc("/Length1 "+QString::number(len1)+"\n");
808
                                PutDoc("/Length2 "+QString::number(len2)+"\n");
809
                                PutDoc("/Length3 "+QString::number(len3)+"\n");
4264 craig 810
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 811
                                        PutDoc("/Filter /FlateDecode\n");
4229 craig 812
                                PutDoc(">>\nstream\n"+EncStream(fon,ObjCounter)+"\nendstream\nendobj\n");
3133 fschmid 813
                                ObjCounter++;
814
                        }
5980 avox 815
                        if ((fformat == ScFace::PFA) && (Options.EmbedList.contains(it.key())))
3133 fschmid 816
                        {
3829 cbradney 817
                                QString fon("");
818
                                QString fon2("");
819
                                QString tm("");
3133 fschmid 820
                                uint value;
821
                                bool ok = true;
822
                                StartObj(ObjCounter);
5980 avox 823
                                AllFonts[it.key()].EmbedFont(fon);
3133 fschmid 824
                                int len1 = fon.find("eexec")+5;
825
                                fon2 = fon.left(len1)+"\n";
826
                                int len2 = fon.find("0000000000000000000000000");
827
                                if (len2 == -1)
828
                                        len2 = fon.length()+1;
829
                                int count = 0;
830
                                for (int xx = len1; xx < len2-1; ++xx)
831
                                {
832
                                        tm = fon.at(xx);
833
                                        if ((tm == QChar(13)) || (tm == QChar(10)))
834
                                                continue;
835
                                        xx++;
836
                                        count++;
837
                                        tm += fon.at(xx);
838
                                        value = tm.toUInt(&ok, 16);
839
                                        fon2 += QChar(value);
840
                                }
841
                                fon2 += fon.mid(len2);
4264 craig 842
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 843
                                        fon2 = CompressStr(&fon2);
4229 craig 844
                                PutDoc("<<\n/Length "+QString::number(fon2.length()+1)+"\n");
845
                                PutDoc("/Length1 "+QString::number(len1+1)+"\n");
846
                                PutDoc("/Length2 "+QString::number(count)+"\n");
847
                                PutDoc(static_cast<int>(fon.length()-len2) == -1 ? QString("/Length3 0\n") : "/Length3 "+QString::number(fon.length()-len2)+"\n");
4264 craig 848
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 849
                                        PutDoc("/Filter /FlateDecode\n");
4229 craig 850
                                PutDoc(">>\nstream\n"+EncStream(fon2, ObjCounter)+"\nendstream\nendobj\n");
3133 fschmid 851
                                ObjCounter++;
852
                        }
5980 avox 853
                        if ((fformat == ScFace::SFNT || fformat == ScFace::TTCF) && (Options.EmbedList.contains(it.key())))
3133 fschmid 854
                        {
3829 cbradney 855
                                QString fon("");
3133 fschmid 856
                                StartObj(ObjCounter);
857
                                QByteArray bb;
5980 avox 858
                                AllFonts[it.key()].RawData(bb);
3133 fschmid 859
                                //AV: += and append() dont't work because they stop at '\0' :-(
860
                                for (unsigned int i=0; i < bb.size(); i++)
861
                                        fon += QChar(bb[i]);
862
                                int len = fon.length();
4264 craig 863
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 864
                                        fon = CompressStr(&fon);
865
                                //qDebug(QString("sfnt data: size=%1 before=%2 compressed=%3").arg(bb.size()).arg(len).arg(fon.length()));
4229 craig 866
                                PutDoc("<<\n/Length "+QString::number(fon.length()+1)+"\n");
867
                                PutDoc("/Length1 "+QString::number(len)+"\n");
4264 craig 868
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 869
                                        PutDoc("/Filter /FlateDecode\n");
4229 craig 870
                                PutDoc(">>\nstream\n"+EncStream(fon, ObjCounter)+"\nendstream\nendobj\n");
3133 fschmid 871
                                ObjCounter++;
872
                        }
873
                        StartObj(ObjCounter);
5387 avox 874
                        // TODO: think about QByteArray ScFace::getFontDescriptor() -- AV
3133 fschmid 875
                        PutDoc("<<\n/Type /FontDescriptor\n");
5980 avox 876
                        PutDoc("/FontName /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
6213 fschmid 877
                        PutDoc("/FontBBox [ "+AllFonts[it.key()].FontBBoxAsString()+" ]\n");
3133 fschmid 878
                        PutDoc("/Flags ");
5980 avox 879
                        //FIXME: isItalic() should be queried from ScFace, not from Qt -- AV
3544 avox 880
                        //QFontInfo fo = QFontInfo(it.data());
3133 fschmid 881
                        int pfl = 0;
5980 avox 882
                        if (AllFonts[it.key()].isFixedPitch())
3133 fschmid 883
                                pfl = pfl ^ 1;
3544 avox 884
                        //if (fo.italic())
6213 fschmid 885
                        if (AllFonts[it.key()].ItalicAngleAsString() != "0")
3133 fschmid 886
                                pfl = pfl ^ 64;
887
//                      pfl = pfl ^ 4;
888
                        pfl = pfl ^ 32;
4229 craig 889
                        PutDoc(QString::number(pfl)+"\n");
6213 fschmid 890
                        PutDoc("/Ascent "+AllFonts[it.key()].ascentAsString()+"\n");
891
                        PutDoc("/Descent "+AllFonts[it.key()].descentAsString()+"\n");
892
                        PutDoc("/CapHeight "+AllFonts[it.key()].capHeightAsString()+"\n");
893
                        PutDoc("/ItalicAngle "+AllFonts[it.key()].ItalicAngleAsString()+"\n");
894
//                      PutDoc("/Ascent "+QString::number(static_cast<int>(AllFonts[it.key()].ascent()))+"\n");
895
//                      PutDoc("/Descent "+QString::number(static_cast<int>(AllFonts[it.key()].descent()))+"\n");
896
//                      PutDoc("/CapHeight "+QString::number(static_cast<int>(AllFonts[it.key()].capHeight()))+"\n");
897
//                      PutDoc("/ItalicAngle "+AllFonts[it.key()].italicAngle()+"\n");
898
//                      PutDoc("/StemV "+ AllFonts[it.key()].stemV() + "\n");
899
                        PutDoc("/StemV 1\n");
5980 avox 900
                        if ((fformat == ScFace::SFNT || fformat == ScFace::TTCF) && (Options.EmbedList.contains(it.key())))
4229 craig 901
                                PutDoc("/FontFile2 "+QString::number(ObjCounter-1)+" 0 R\n");
5980 avox 902
                        if ((fformat == ScFace::PFB) && (Options.EmbedList.contains(it.key())))
4229 craig 903
                                PutDoc("/FontFile "+QString::number(ObjCounter-1)+" 0 R\n");
5980 avox 904
                        if ((fformat == ScFace::PFA) && (Options.EmbedList.contains(it.key())))
4229 craig 905
                                PutDoc("/FontFile "+QString::number(ObjCounter-1)+" 0 R\n");
3133 fschmid 906
                        PutDoc(">>\nendobj\n");
907
                        ObjCounter++;
4546 subik 908
/*                      if (!FT_Has_PS_Glyph_Names(AllFonts[it.key()])
3133 fschmid 909
                        {
910
                                StartObj(ObjCounter);
911
                                int chCount = 31;
912
                                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 ");
913
                                for (int ww = 31; ww < 256; ++ww)
914
                                {
4229 craig 915
                                        PutDoc(QString::number(static_cast<int>(AllFonts[it.key()]->CharWidth[itg.key()]*
3133 fschmid 916
                                                        1000))+" ");
917
                                        if (itg == gl.end())
918
                                                break;
919
                                        ++itg;
920
                                        chCount++;
921
                                }
922
                                PutDoc("]\nendobj\n");
923
                                ObjCounter++;
924
                                // put widths object
925
                                // encoding dictionary w/ base encoding w/o differences
926
                                StartObj(ObjCounter);
927
                                PutDoc("<<\n/Type /Font\n/Subtype ");
5980 avox 928
                                PutDoc((fformat == ScFace::SFNT || fformat == ScFace::TTCF) ? "/TrueType\n" : "/Type1\n");
4229 craig 929
                                PutDoc("/Name /Fo"+QString::number(a)+"\n");
5980 avox 930
                                PutDoc("/BaseFont /"+AllFonts[it.key()]->psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "" )+"\n");
3133 fschmid 931
                                //cf. widths:
932
                                PutDoc("/FirstChar 0\n");
4229 craig 933
                                PutDoc("/LastChar "+QString::number(chCount-1)+"\n");
934
                                PutDoc("/Widths "+QString::number(ObjCounter-1)+" 0 R\n");
935
                                PutDoc("/FontDescriptor "+QString::number(ObjCounter-2)+" 0 R\n");
3133 fschmid 936
                                PutDoc(">>\nendobj\n");
4229 craig 937
                                Seite.FObjects["Fo"+QString::number(a)] = ObjCounter;
3133 fschmid 938
                                ObjCounter++;
939
                        }
940
                        else */
941
//                      {
6301 avox 942
                                QMap<uint,std::pair<QChar,QString> > gl;
943
                                AllFonts[it.key()].glyphNames(gl);
944
                                int nglyphs = 0;
945
                                QMap<uint,std::pair<QChar,QString> >::Iterator gli;
946
                                for (gli = gl.begin(); gli != gl.end(); ++gli) {
947
                                        if (gli.key() > nglyphs)
948
                                                nglyphs = gli.key();
949
                                }
950
                                ++nglyphs;
6302 avox 951
//                              qDebug(QString("pdflib: nglyphs %1 max %2").arg(nglyphs).arg(AllFonts[it.key()].maxGlyph()));
3133 fschmid 952
                                uint FontDes = ObjCounter - 1;
6301 avox 953
                                uint Fcc = nglyphs / 224;
954
                                if ((nglyphs % 224) != 0)
3133 fschmid 955
                                        Fcc += 1;
956
                                for (uint Fc = 0; Fc < Fcc; ++Fc)
957
                                {
958
                                        StartObj(ObjCounter);
6301 avox 959
                                        int chCount = 32;
960
                                        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 ");
961
                                        for (int ww = 32; ww < 256; ++ww)
3133 fschmid 962
                                        {
6301 avox 963
                                                uint glyph = 224 * Fc + ww - 32;
964
                                                if (gl.contains(glyph))
965
                                                        PutDoc(QString::number(static_cast<int>(AllFonts[it.key()].glyphWidth(glyph)* 1000))+" ");
966
                                                else
967
                                                        PutDoc("0 ");
968
 
6302 avox 969
                                                chCount++;
6301 avox 970
                                                if (signed(glyph) == nglyphs-1)
3133 fschmid 971
                                                        break;
972
                                        }
973
                                        PutDoc("]\nendobj\n");
974
                                        ObjCounter++;
975
                                        StartObj(ObjCounter);
976
                                        ObjCounter++;
977
                                        PutDoc("<< /Type /Encoding\n");
978
//                                      PutDoc("/BaseEncoding /" + AllFonts[it.key()]->FontEnc + "\n");
6301 avox 979
                                        PutDoc("/Differences [ \n");
3133 fschmid 980
                                        int crc = 0;
6301 avox 981
                                        bool startOfSeq = true;
3133 fschmid 982
                                        for (int ww2 = 32; ww2 < 256; ++ww2)
983
                                        {
6301 avox 984
                                                uint glyph = 224 * Fc + ww2 - 32;
985
                                                if (gl[glyph].second != "")
6213 fschmid 986
                                                {
6301 avox 987
                                                        if (startOfSeq) {
988
                                                                PutDoc(QString::number(ww2)+" ");
989
                                                                startOfSeq = false;
990
                                                        }
991
                                                        PutDoc("/"+gl[glyph].second+" ");
992
                                                        crc++;
6213 fschmid 993
                                                }
6301 avox 994
                                                else {
995
                                                        startOfSeq = true;
996
                                                }
997
                                                if (signed(glyph) == nglyphs-1)
3133 fschmid 998
                                                        break;
999
                                                if (crc > 8)
1000
                                                {
1001
                                                        PutDoc("\n");
1002
                                                        crc = 0;
1003
                                                }
1004
                                        }
1005
                                        PutDoc("]\n");
4546 subik 1006
 
3133 fschmid 1007
                                        PutDoc(">>\nendobj\n");
1008
                                        StartObj(ObjCounter);
1009
                                        PutDoc("<<\n/Type /Font\n/Subtype ");
5980 avox 1010
                                        PutDoc((fformat == ScFace::SFNT || fformat == ScFace::TTCF) ? "/TrueType\n" : "/Type1\n");
4229 craig 1011
                                        PutDoc("/Name /Fo"+QString::number(a)+"S"+QString::number(Fc)+"\n");
5980 avox 1012
                                        PutDoc("/BaseFont /"+AllFonts[it.key()].psName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
3133 fschmid 1013
                                        PutDoc("/FirstChar 0\n");
4229 craig 1014
                                        PutDoc("/LastChar "+QString::number(chCount-1)+"\n");
1015
                                        PutDoc("/Widths "+QString::number(ObjCounter-2)+" 0 R\n");
1016
                                        PutDoc("/Encoding "+QString::number(ObjCounter-1)+" 0 R\n");
1017
                                        PutDoc("/FontDescriptor "+QString::number(FontDes)+" 0 R\n");
3133 fschmid 1018
                                        PutDoc(">>\nendobj\n");
4229 craig 1019
                                        Seite.FObjects["Fo"+QString::number(a)+"S"+QString::number(Fc)] = ObjCounter;
3133 fschmid 1020
                                        ObjCounter++;
1021
                                } // for(Fc)
1022
//                      } // FT_Has_PS_Glyph_Names
1023
                }
1024
                a++;
1025
        }
4264 craig 1026
        if (Options.UseLPI)
3133 fschmid 1027
        {
1028
                StartObj(ObjCounter);
1029
                PutDoc("<<\n/Type /Halftone\n/HalftoneType 5\n");
4264 craig 1030
                QMap<QString,LPIData>::const_iterator itlp;
1031
                for (itlp = Options.LPISettings.constBegin(); itlp != Options.LPISettings.constEnd(); ++itlp)
3133 fschmid 1032
                {
1033
                        PutDoc("/"+itlp.key()+"\n<<\n/Type /Halftone\n/HalftoneType 1\n/Frequency ");
4229 craig 1034
                        PutDoc(QString::number(itlp.data().Frequency)+"\n/Angle "+QString::number(itlp.data().Angle)+"\n/SpotFunction ");
3829 cbradney 1035
                        QString func ("");
3133 fschmid 1036
                        switch (itlp.data().SpotFunc)
1037
                        {
1038
                                case 0:
1039
                                        func = "/SimpleDot";
1040
                                        break;
1041
                                case 1:
1042
                                        func = "/Line";
1043
                                        break;
1044
                                case 2:
1045
                                        func = "/Round";
1046
                                        break;
1047
                                case 3:
1048
                                        func = "/Ellipse";
1049
                                        break;
1050
                                default:
1051
                                        func = "/SimpleDot";
1052
                                        break;
1053
                        }
1054
                        PutDoc(func+"\n>>\n");
1055
                }
1056
                PutDoc("/Default\n<<\n/Type /Halftone\n/HalftoneType 1\n/Frequency 50\n/Angle 45\n/SpotFunction /Round\n>>\n");
1057
                PutDoc(">>\nendobj\n");
1058
                ObjCounter++;
1059
                StartObj(ObjCounter);
4229 craig 1060
                HTName = ResNam+QString::number(ResCount);
3133 fschmid 1061
                Transpar[HTName] = ObjCounter;
4229 craig 1062
                PutDoc("<< /Type /ExtGState\n/HT "+QString::number(ObjCounter-1)+" 0 R\n>>\nendobj\n");
3133 fschmid 1063
                ResCount++;
1064
                ObjCounter++;
1065
        }
5880 jghali 1066
        if ((doc.HasCMS) && (Options.UseProfiles))
3133 fschmid 1067
        {
1068
                StartObj(ObjCounter);
1069
                ObjCounter++;
1070
                QString dataP;
1071
                struct ICCD dataD;
5243 cbradney 1072
                loadText(ScCore->InputProfiles[Options.SolidProf], &dataP);
3133 fschmid 1073
                PutDoc("<<\n");
4264 craig 1074
                if ((Options.Compress) && (CompAvail))
3133 fschmid 1075
                {
1076
                        PutDoc("/Filter /FlateDecode\n");
1077
                        dataP = CompressStr(&dataP);
1078
                }
4229 craig 1079
                PutDoc("/Length "+QString::number(dataP.length()+1)+"\n");
4264 craig 1080
                PutDoc("/N "+QString::number(Options.SComp)+"\n");
4229 craig 1081
                PutDoc(">>\nstream\n"+EncStream(dataP, ObjCounter-1)+"\nendstream\nendobj\n");
3133 fschmid 1082
                StartObj(ObjCounter);
4229 craig 1083
                dataD.ResName = ResNam+QString::number(ResCount);
1084
                dataD.ICCArray = "[ /ICCBased "+QString::number(ObjCounter-1)+" 0 R ]";
3133 fschmid 1085
                dataD.ResNum = ObjCounter;
4264 craig 1086
                ICCProfiles[Options.SolidProf] = dataD;
4229 craig 1087
                PutDoc("[ /ICCBased "+QString::number(ObjCounter-1)+" 0 R ]\n");
3133 fschmid 1088
                PutDoc("endobj\n");
1089
                ResCount++;
1090
                ObjCounter++;
1091
        }
4264 craig 1092
        if (((Options.isGrayscale == false) && (Options.UseRGB == false)) && (Options.UseSpotColors))
3133 fschmid 1093
        {
4264 craig 1094
                doc.getUsedColors(colorsToUse);
3133 fschmid 1095
                ColorList::Iterator itf;
1096
                for (itf = colorsToUse.begin(); itf != colorsToUse.end(); ++itf)
1097
                {
1098
                        if ((colorsToUse[itf.key()].isSpotColor()) || (colorsToUse[itf.key()].isRegistrationColor()))
1099
                        {
1100
                                int cc, cm, cy, ck;
1101
                                struct SpotC spotD;
1102
                                colorsToUse[itf.key()].getCMYK(&cc, &cm, &cy, &ck);
1103
                                QString colorDesc = "{\ndup "+FToStr(static_cast<double>(cc) / 255)+"\nmul exch dup ";
1104
                                colorDesc += FToStr(static_cast<double>(cm) / 255)+"\nmul exch dup ";
1105
                                colorDesc += FToStr(static_cast<double>(cy) / 255)+"\nmul exch ";
1106
                                colorDesc += FToStr(static_cast<double>(ck) / 255)+" mul }";
1107
                                StartObj(ObjCounter);
1108
                                ObjCounter++;
1109
                                PutDoc("<<\n/FunctionType 4\n");
1110
                                PutDoc("/Domain [0.0 1.0]\n");
1111
                                PutDoc("/Range [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]\n");
4229 craig 1112
                                PutDoc("/Length "+QString::number(colorDesc.length()+1)+"\n");
1113
                                PutDoc(">>\nstream\n"+EncStream(colorDesc, ObjCounter-1)+"\nendstream\nendobj\n");
3133 fschmid 1114
                                StartObj(ObjCounter);
1115
                                PutDoc("[ /Separation /");
1116
                                if (colorsToUse[itf.key()].isRegistrationColor())
1117
                                        PutDoc("All");
1118
                                else
6471 fschmid 1119
                                        PutDoc(itf.key().simplifyWhiteSpace().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "#20" ));
4229 craig 1120
                                PutDoc(" /DeviceCMYK "+QString::number(ObjCounter-1)+" 0 R ]\nendobj\n");
1121
                                spotD.ResName = spotNam+QString::number(spotCount);
3133 fschmid 1122
                                spotD.ResNum = ObjCounter;
1123
                                spotMap.insert(itf.key(), spotD);
1124
                                spotCount++;
1125
                                ObjCounter++;
1126
                        }
1127
                }
1128
        }
6925 fschmid 1129
        if ((Options.cropMarks) || (Options.bleedMarks) || (Options.registrationMarks) || (Options.colorMarks) || (Options.docInfoMarks))
1130
        {
1131
                struct SpotC spotD;
1132
                StartObj(ObjCounter);
1133
                PutDoc("[ /Separation /All /DeviceCMYK\n");
1134
                PutDoc("<<\n/FunctionType 2\n");
1135
                PutDoc("/Domain [0.0 1.0]\n");
1136
                PutDoc("/Range [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]\n");
1137
                PutDoc("/C0 [0 0 0 0] \n");
1138
                PutDoc("/C1 [1 1 1 1] \n");
1139
                PutDoc("/N 1\n");
1140
                PutDoc(">>\n]\nendobj\n");
1141
                spotD.ResName = spotNam+QString::number(spotCount);
1142
                spotD.ResNum = ObjCounter;
1143
                spotMapReg.insert("Register", spotD);
1144
                spotCount++;
1145
                ObjCounter++;
1146
        }
4264 craig 1147
        if ((Options.Version == 15) && (Options.useLayers))
3133 fschmid 1148
        {
1149
                struct Layer ll;
1150
                struct OCGInfo ocg;
1151
                ll.isPrintable = false;
1152
                ll.LNr = 0;
1153
                int Lnr = 0;
3829 cbradney 1154
                QString ocgNam("oc");
4264 craig 1155
                uint docLayersCount=doc.Layers.count();
3829 cbradney 1156
                for (uint la = 0; la < docLayersCount; ++la)
3133 fschmid 1157
                {
3829 cbradney 1158
                        QString tmp("");
4264 craig 1159
                        Level2Layer(&doc, &ll, Lnr);
3133 fschmid 1160
                        ocg.Name = ocgNam+tmp.setNum(ll.LNr);
1161
                        ocg.ObjNum = ObjCounter;
1162
                        ocg.visible = ll.isViewable;
1163
                        OCGEntries.insert(ll.Name, ocg);
1164
                        StartObj(ObjCounter);
1165
                        ObjCounter++;
1166
                        PutDoc("<<\n");
1167
                        PutDoc("/Type /OCG\n");
1168
                        PutDoc("/Name ("+ll.Name+")\n");
1169
                        PutDoc(">>\nendobj\n");
1170
                        Lnr++;
1171
                }
1172
        }
1173
        return true;
1174
}
1175
 
4241 craig 1176
void PDFlib::PDF_TemplatePage(const Page* pag, bool )
3133 fschmid 1177
{
1178
        QString tmp;
1179
        ActPageP = pag;
1180
        PageItem* ite;
1181
        QPtrList<PageItem> PItems;
1182
        int Lnr = 0;
1183
        struct Layer ll;
1184
        ll.isPrintable = false;
1185
        ll.LNr = 0;
1186
        Inhalt = "";
1187
        Seite.AObjects.clear();
4264 craig 1188
        for (uint la = 0; la < doc.Layers.count(); ++la)
3133 fschmid 1189
        {
4264 craig 1190
                Level2Layer(&doc, &ll, Lnr);
1191
                PItems = doc.MasterItems;
3133 fschmid 1192
                if (ll.isPrintable)
1193
                {
4264 craig 1194
                        if ((Options.Version == 15) && (Options.useLayers))
3133 fschmid 1195
                                PutPage("/OC /"+OCGEntries[ll.Name].Name+" BDC\n");
1196
                        for (uint a = 0; a < PItems.count(); ++a)
1197
                        {
1198
                                Inhalt = "";
1199
                                ite =PItems.at(a);
1200
                                if (ite->LayerNr != ll.LNr)
1201
                                        continue;
4726 fschmid 1202
                                double x = pag->xOffset();
1203
                                double y = pag->yOffset();
1204
                                double w = pag->width();
1205
                                double h1 = pag->height();
4580 cbradney 1206
                                double ilw=ite->lineWidth();
4726 fschmid 1207
                                double x2 = ite->BoundingX - ilw / 2.0;
1208
                                double y2 = ite->BoundingY - ilw / 2.0;
1209
                                double w2 = ite->BoundingW + ilw;
1210
                                double h2 = ite->BoundingH + ilw;
1211
                                if (!( QMAX( x, x2 ) <= QMIN( x+w, x2+w2 ) && QMAX( y, y2 ) <= QMIN( y+h1, y2+h2 )))
3133 fschmid 1212
                                        continue;
1213
                                if (ite->ChangedMasterItem)
1214
                                        continue;
5685 cbradney 1215
                                if ((!pag->pageName().isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
3133 fschmid 1216
                                        continue;
1217
                                PutPage("q\n");
5320 fschmid 1218
                                if ((ite->doOverprint) && (!Options.doOverprint) && (!Options.UseRGB))
1219
                                {
1220
                                        StartObj(ObjCounter);
1221
                                        QString ShName = ResNam+QString::number(ResCount);
1222
                                        Transpar[ShName] = ObjCounter;
1223
                                        ResCount++;
1224
                                        ObjCounter++;
1225
                                        PutDoc("<< /Type /ExtGState\n");
1226
                                        PutDoc("/OP true\n");
1227
                                        PutDoc("/op true\n");
1228
                                        PutDoc("/OPM 1\n");
1229
                                        PutDoc(">>\nendobj\n");
1230
                                        PutPage("/"+ShName+" gs\n");
1231
                                }
4679 fschmid 1232
/* Bookmarks on Master Pages do not make any sense */
1233
//                              if ((ite->isBookmark) && (Options.Bookmarks))
1234
//                                      PDF_Bookmark(ite, pag->height() - (ite->yPos() - pag->yOffset()));
5685 cbradney 1235
                                if (!ite->printEnabled() || ((ite->itemType() == PageItem::TextFrame) && (!pag->pageName().isEmpty())))
3133 fschmid 1236
                                {
1237
                                        PutPage("Q\n");
1238
                                        continue;
1239
                                }
4546 subik 1240
                                if (ite->fillColor() != CommonStrings::None)
3133 fschmid 1241
                                        PutPage(putColor(ite->fillColor(), ite->fillShade(), true));
4546 subik 1242
                                if (ite->lineColor() != CommonStrings::None)
3133 fschmid 1243
                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), false));
4580 cbradney 1244
                                Inhalt += FToStr(fabs(ite->lineWidth()))+" w\n";
3133 fschmid 1245
                                if (ite->DashValues.count() != 0)
1246
                                {
1247
                                        PutPage("[ ");
1248
                                        QValueList<double>::iterator it;
1249
                                        for ( it = ite->DashValues.begin(); it != ite->DashValues.end(); ++it )
1250
                                        {
1251
                                                int da = static_cast<int>(*it);
1252
                                                if (da != 0)
4229 craig 1253
                                                        PutPage(QString::number(da)+" ");
3133 fschmid 1254
                                        }
4229 craig 1255
                                        PutPage("] "+QString::number(static_cast<int>(ite->DashOffset))+" d\n");
3133 fschmid 1256
                                }
1257
                                else
1258
                                {
4580 cbradney 1259
                                        QString Dt = FToStr(QMAX(2*fabs(ite->lineWidth()), 1));
1260
                                        QString Da = FToStr(QMAX(6*fabs(ite->lineWidth()), 1));
3133 fschmid 1261
                                        switch (ite->PLineArt)
1262
                                        {
1263
                                                case Qt::SolidLine:
1264
                                                        PutPage("[] 0 d\n");
1265
                                                        break;
1266
                                                case Qt::DashLine:
1267
                                                        PutPage("["+Da+" "+Dt+"] 0 d\n");
1268
                                                        break;
1269
                                                case Qt::DotLine:
1270
                                                        PutPage("["+Dt+"] 0 d\n");
1271
                                                        break;
1272
                                                case Qt::DashDotLine:
1273
                                                        PutPage("["+Da+" "+Dt+" "+Dt+" "+Dt+"] 0 d\n");
1274
                                                        break;
1275
                                                case Qt::DashDotDotLine:
1276
                                                        PutPage("["+Da+" "+Dt+" "+Dt+" "+Dt+" "+Dt+" "+Dt+"] 0 d\n");
1277
                                                        break;
1278
                                                default:
1279
                                                        PutPage("[] 0 d\n");
1280
                                                        break;
1281
                                        }
1282
                                }
1283
                                switch (ite->PLineEnd)
1284
                                {
1285
                                        case Qt::FlatCap:
1286
                                                PutPage("0 J\n");
1287
                                                break;
1288
                                        case Qt::SquareCap:
1289
                                                PutPage("2 J\n");
1290
                                                break;
1291
                                        case Qt::RoundCap:
1292
                                                PutPage("1 J\n");
1293
                                                break;
1294
                                        default:
1295
                                                PutPage("0 J\n");
1296
                                                break;
1297
                                }
1298
                                switch (ite->PLineJoin)
1299
                                {
1300
                                        case Qt::MiterJoin:
1301
                                                PutPage("0 j\n");
1302
                                                break;
1303
                                        case Qt::BevelJoin:
1304
                                                PutPage("2 j\n");
1305
                                                break;
1306
                                        case Qt::RoundJoin:
1307
                                                PutPage("1 j\n");
1308
                                                break;
1309
                                        default:
1310
                                                PutPage("0 j\n");
1311
                                                break;
1312
                                }
3903 cbradney 1313
                                PutPage("1 0 0 1 "+FToStr(ite->xPos() - pag->xOffset())+" "+FToStr(pag->height() - (ite->yPos()  - pag->yOffset()))+" cm\n");
3934 cbradney 1314
                                if (ite->rotation() != 0)
3133 fschmid 1315
                                {
3934 cbradney 1316
                                        double sr = sin(-ite->rotation()* M_PI / 180.0);
1317
                                        double cr = cos(-ite->rotation()* M_PI / 180.0);
3133 fschmid 1318
                                        if ((cr * cr) < 0.000001)
1319
                                                cr = 0;
1320
                                        if ((sr * sr) < 0.000001)
1321
                                                sr = 0;
1322
                                        PutPage(FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+" 0 0 cm\n");
1323
                                }
1324
                                switch (ite->itemType())
1325
                                {
1326
                                        case PageItem::ImageFrame:
5748 fschmid 1327
                                                if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= 14))
1328
                                                        PutPage(PDF_TransparenzFill(ite));
4546 subik 1329
                                                if ((ite->fillColor() != CommonStrings::None) || (ite->GrType != 0))
3133 fschmid 1330
                                                {
1331
                                                        if (ite->GrType != 0)
1332
                                                                PutPage(PDF_Gradient(ite));
1333
                                                        else
1334
                                                        {
1335
                                                                PutPage(SetClipPath(ite));
1336
                                                                PutPage("h\nf*\n");
1337
                                                        }
1338
                                                }
1339
                                                PutPage("q\n");
1340
                                                if (ite->imageClip.size() != 0)
4744 fschmid 1341
                                                {
3133 fschmid 1342
                                                        PutPage(SetClipPathImage(ite));
4744 fschmid 1343
                                                        PutPage("h\nW*\nn\n");
1344
                                                }
1345
                                                PutPage(SetClipPath(ite));
3133 fschmid 1346
                                                PutPage("h\nW*\nn\n");
1347
                                                if (ite->imageFlippedH())
3934 cbradney 1348
                                                        PutPage("-1 0 0 1 "+FToStr(ite->width())+" 0 cm\n");
3133 fschmid 1349
                                                if (ite->imageFlippedV())
3934 cbradney 1350
                                                        PutPage("1 0 0 -1 0 "+FToStr(-ite->height())+" cm\n");
3133 fschmid 1351
                                                if ((ite->PicAvail) && (!ite->Pfile.isEmpty()))
3985 cbradney 1352
                                                        PutPage(PDF_Image(ite, ite->Pfile, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), false, ite->IProfile, ite->UseEmbedded, ite->IRender));
3133 fschmid 1353
                                                PutPage("Q\n");
4546 subik 1354
                                                if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
3133 fschmid 1355
                                                {
5748 fschmid 1356
                                                        if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= 14))
1357
                                                                PutPage(PDF_TransparenzStroke(ite));
4580 cbradney 1358
                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1359
                                                        {
1360
                                                                PutPage(SetClipPath(ite));
1361
                                                                PutPage("h\nS\n");
1362
                                                        }
1363
                                                        else
1364
                                                        {
4264 craig 1365
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1366
                                                                for (int it = ml.size()-1; it > -1; it--)
1367
                                                                {
6568 fschmid 1368
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1369
                                                                        {
1370
                                                                                PutPage(setStrokeMulti(&ml[it]));
1371
                                                                                PutPage(SetClipPath(ite));
1372
                                                                                PutPage("h\nS\n");
1373
                                                                        }
3133 fschmid 1374
                                                                }
1375
                                                        }
1376
                                                }
1377
                                                break;
1378
                                        case PageItem::TextFrame:
1379
                                                break;
1380
                                        case PageItem::Line:
5748 fschmid 1381
                                                if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= 14))
1382
                                                        PutPage(PDF_TransparenzStroke(ite));
3133 fschmid 1383
                                                if (ite->NamedLStyle.isEmpty())
1384
                                                {
1385
                                                        PutPage("0 0 m\n");
3934 cbradney 1386
                                                        PutPage(FToStr(ite->width())+" 0 l\n");
3133 fschmid 1387
                                                        PutPage("S\n");
1388
                                                }
1389
                                                else
1390
                                                {
4264 craig 1391
                                                        multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1392
                                                        for (int it = ml.size()-1; it > -1; it--)
1393
                                                        {
6568 fschmid 1394
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1395
                                                                        {
1396
                                                                                PutPage(setStrokeMulti(&ml[it]));
1397
                                                                                PutPage("0 0 m\n");
1398
                                                                                PutPage(FToStr(ite->width())+" 0 l\n");
1399
                                                                                PutPage("S\n");
1400
                                                                        }
3133 fschmid 1401
                                                        }
1402
                                                }
4061 craig 1403
                                                if (ite->startArrowIndex() != 0)
3133 fschmid 1404
                                                {
1405
                                                        QWMatrix arrowTrans;
4264 craig 1406
                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->startArrowIndex()-1)).points.copy();
3133 fschmid 1407
                                                        arrowTrans.translate(0, 0);
4580 cbradney 1408
                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1409
                                                        arrowTrans.scale(-1,1);
1410
                                                        arrow.map(arrowTrans);
4264 craig 1411
                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1412
                                                        {
1413
                                                                StartObj(ObjCounter);
4229 craig 1414
                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1415
                                                                Transpar[ShName] = ObjCounter;
1416
                                                                ResCount++;
1417
                                                                ObjCounter++;
1418
                                                                PutDoc("<< /Type /ExtGState\n");
1419
                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1420
                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1421
                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1422
                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1423
                                                                PutPage("/"+ShName+" gs\n");
1424
                                                        }
4016 fschmid 1425
                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1426
                                                        PutPage(SetClipPathArray(&arrow));
1427
                                                        PutPage("h\nf*\n");
1428
                                                }
4061 craig 1429
                                                if (ite->endArrowIndex() != 0)
3133 fschmid 1430
                                                {
1431
                                                        QWMatrix arrowTrans;
4264 craig 1432
                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->endArrowIndex()-1)).points.copy();
3934 cbradney 1433
                                                        arrowTrans.translate(ite->width(), 0);
4580 cbradney 1434
                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1435
                                                        arrow.map(arrowTrans);
4264 craig 1436
                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1437
                                                        {
1438
                                                                StartObj(ObjCounter);
4229 craig 1439
                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1440
                                                                Transpar[ShName] = ObjCounter;
1441
                                                                ResCount++;
1442
                                                                ObjCounter++;
1443
                                                                PutDoc("<< /Type /ExtGState\n");
1444
                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1445
                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1446
                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1447
                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1448
                                                                PutPage("/"+ShName+" gs\n");
1449
                                                        }
4016 fschmid 1450
                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1451
                                                        PutPage(SetClipPathArray(&arrow));
1452
                                                        PutPage("h\nf*\n");
1453
                                                }
1454
                                                break;
3232 cbradney 1455
                                        case PageItem::ItemType1:
1456
                                        case PageItem::ItemType3:
3133 fschmid 1457
                                        case PageItem::Polygon:
5748 fschmid 1458
                                                if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= 14))
1459
                                                        PutPage(PDF_TransparenzFill(ite));
3133 fschmid 1460
                                                if (ite->GrType != 0)
1461
                                                        PutPage(PDF_Gradient(ite));
1462
                                                else
1463
                                                {
4546 subik 1464
                                                        if (ite->fillColor() != CommonStrings::None)
3133 fschmid 1465
                                                        {
1466
                                                                PutPage(SetClipPath(ite));
1467
                                                                PutPage("h\nf*\n");
1468
                                                        }
1469
                                                }
4546 subik 1470
                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3133 fschmid 1471
                                                {
5748 fschmid 1472
                                                        if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= 14))
1473
                                                                PutPage(PDF_TransparenzStroke(ite));
4580 cbradney 1474
                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1475
                                                        {
1476
                                                                PutPage(SetClipPath(ite));
1477
                                                                PutPage("h\nS\n");
1478
                                                        }
1479
                                                        else
1480
                                                        {
4264 craig 1481
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1482
                                                                for (int it = ml.size()-1; it > -1; it--)
1483
                                                                {
6568 fschmid 1484
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1485
                                                                        {
1486
                                                                                PutPage(setStrokeMulti(&ml[it]));
1487
                                                                                PutPage(SetClipPath(ite));
1488
                                                                                PutPage("h\nS\n");
1489
                                                                        }
3133 fschmid 1490
                                                                }
1491
                                                        }
1492
                                                }
1493
                                                break;
1494
                                        case PageItem::PolyLine:
4658 fschmid 1495
                                                if (ite->PoLine.size() > 4) // && ((ite->PoLine.point(0) != ite->PoLine.point(1)) || (ite->PoLine.point(2) != ite->PoLine.point(3))))
3133 fschmid 1496
                                                {
5748 fschmid 1497
                                                        if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= 14))
1498
                                                                PutPage(PDF_TransparenzFill(ite));
3133 fschmid 1499
                                                        if (ite->GrType != 0)
1500
                                                                PutPage(PDF_Gradient(ite));
1501
                                                        else
1502
                                                        {
4546 subik 1503
                                                                if (ite->fillColor() != CommonStrings::None)
3133 fschmid 1504
                                                                {
1505
                                                                        PutPage(SetClipPath(ite));
1506
                                                                        PutPage("h\nf*\n");
1507
                                                                }
1508
                                                        }
1509
                                                }
4546 subik 1510
                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3133 fschmid 1511
                                                {
5748 fschmid 1512
                                                        if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= 14))
1513
                                                                PutPage(PDF_TransparenzStroke(ite));
4580 cbradney 1514
                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1515
                                                        {
1516
                                                                PutPage(SetClipPath(ite, false));
1517
                                                                PutPage("S\n");
1518
                                                        }
1519
                                                        else
1520
                                                        {
4264 craig 1521
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1522
                                                                for (int it = ml.size()-1; it > -1; it--)
1523
                                                                {
6568 fschmid 1524
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1525
                                                                        {
1526
                                                                                PutPage(setStrokeMulti(&ml[it]));
1527
                                                                                PutPage(SetClipPath(ite, false));
1528
                                                                                PutPage("S\n");
1529
                                                                        }
3133 fschmid 1530
                                                                }
1531
                                                        }
1532
                                                }
4061 craig 1533
                                                if (ite->startArrowIndex() != 0)
3133 fschmid 1534
                                                {
1535
                                                        FPoint Start = ite->PoLine.point(0);
1536
                                                        for (uint xx = 1; xx < ite->PoLine.size(); xx += 2)
1537
                                                        {
1538
                                                                FPoint Vector = ite->PoLine.point(xx);
1539
                                                                if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
1540
                                                                {
1541
                                                                        double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
1542
                                                                        QWMatrix arrowTrans;
4264 craig 1543
                                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->startArrowIndex()-1)).points.copy();
3133 fschmid 1544
                                                                        arrowTrans.translate(Start.x(), Start.y());
1545
                                                                        arrowTrans.rotate(r);
4580 cbradney 1546
                                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1547
                                                                        arrow.map(arrowTrans);
4264 craig 1548
                                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1549
                                                                        {
1550
                                                                                StartObj(ObjCounter);
4229 craig 1551
                                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1552
                                                                                Transpar[ShName] = ObjCounter;
1553
                                                                                ResCount++;
1554
                                                                                ObjCounter++;
1555
                                                                                PutDoc("<< /Type /ExtGState\n");
1556
                                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1557
                                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1558
                                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1559
                                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1560
                                                                                PutPage("/"+ShName+" gs\n");
1561
                                                                        }
4016 fschmid 1562
                                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1563
                                                                        PutPage(SetClipPathArray(&arrow));
1564
                                                                        PutPage("h\nf*\n");
1565
                                                                        break;
1566
                                                                }
1567
                                                        }
1568
                                                }
4061 craig 1569
                                                if (ite->endArrowIndex() != 0)
3133 fschmid 1570
                                                {
1571
                                                        FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
1572
                                                        for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
1573
                                                        {
1574
                                                                FPoint Vector = ite->PoLine.point(xx);
1575
                                                                if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
1576
                                                                {
1577
                                                                        double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
1578
                                                                        QWMatrix arrowTrans;
4264 craig 1579
                                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->endArrowIndex()-1)).points.copy();
3133 fschmid 1580
                                                                        arrowTrans.translate(End.x(), End.y());
1581
                                                                        arrowTrans.rotate(r);
4580 cbradney 1582
                                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1583
                                                                        arrow.map(arrowTrans);
4264 craig 1584
                                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1585
                                                                        {
1586
                                                                                StartObj(ObjCounter);
4229 craig 1587
                                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1588
                                                                                Transpar[ShName] = ObjCounter;
1589
                                                                                ResCount++;
1590
                                                                                ObjCounter++;
1591
                                                                                PutDoc("<< /Type /ExtGState\n");
1592
                                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1593
                                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1594
                                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1595
                                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1596
                                                                                PutPage("/"+ShName+" gs\n");
1597
                                                                        }
4016 fschmid 1598
                                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1599
                                                                        PutPage(SetClipPathArray(&arrow));
1600
                                                                        PutPage("h\nf*\n");
1601
                                                                        break;
1602
                                                                }
1603
                                                        }
1604
                                                }
1605
                                                break;
1606
                                        case PageItem::PathText:
1607
                                                if (ite->PoShow)
1608
                                                {
1609
                                                        if (ite->PoLine.size() > 3)
1610
                                                        {
1611
                                                                PutPage("q\n");
4546 subik 1612
                                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3133 fschmid 1613
                                                                {
5748 fschmid 1614
                                                                        if (((ite->lineTransparency() != 0) || (ite->lineBlendmode() != 0)) && (Options.Version >= 14))
1615
                                                                                PutPage(PDF_TransparenzStroke(ite));
4580 cbradney 1616
                                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1617
                                                                        {
1618
                                                                                PutPage(SetClipPath(ite, false));
1619
                                                                                PutPage("S\n");
1620
                                                                        }
1621
                                                                        else
1622
                                                                        {
4264 craig 1623
                                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
6568 fschmid 1624
                                                                                for (int it = ml.size()-1; it > -1; it--)
1625
                                                                                {
1626
                                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
3133 fschmid 1627
                                                                                        {
6568 fschmid 1628
                                                                                                PutPage(setStrokeMulti(&ml[it]));
1629
                                                                                                PutPage(SetClipPath(ite, false));
1630
                                                                                                PutPage("S\n");
3133 fschmid 1631
                                                                                        }
6568 fschmid 1632
                                                                                }
3133 fschmid 1633
                                                                        }
1634
                                                                }
1635
                                                                PutPage("Q\n");
1636
                                                        }
1637
                                                }
5748 fschmid 1638
                                                if (((ite->fillTransparency() != 0) || (ite->fillBlendmode() != 0)) && (Options.Version >= 14))
1639
                                                        PutPage(PDF_TransparenzFill(ite));
3200 cbradney 1640
                                                PutPage(setTextSt(ite, pag->pageNr(), pag));
3133 fschmid 1641
                                                break;
1642
                                        }
1643
                                PutPage("Q\n");
1644
                                StartObj(ObjCounter);
1645
                                ObjCounter++;
1646
                                PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1\n");
3200 cbradney 1647
                                PutDoc("/BBox [ 0 0 "+FToStr(ActPageP->width())+" "+FToStr(ActPageP->height())+" ]\n");
3133 fschmid 1648
                                PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
1649
                                if (Seite.ImgObjects.count() != 0)
1650
                                {
1651
                                        PutDoc("/XObject <<\n");
1652
                                        QMap<QString,int>::Iterator it;
1653
                                        for (it = Seite.ImgObjects.begin(); it != Seite.ImgObjects.end(); ++it)
4229 craig 1654
                                                PutDoc("/"+it.key()+" "+QString::number(it.data())+" 0 R\n");
3133 fschmid 1655
                                        PutDoc(">>\n");
1656
                                }
1657
                                if (Seite.FObjects.count() != 0)
1658
                                {
1659
                                        PutDoc("/Font << \n");
1660
                                        QMap<QString,int>::Iterator it2;
1661
                                        for (it2 = Seite.FObjects.begin(); it2 != Seite.FObjects.end(); ++it2)
4229 craig 1662
                                                PutDoc("/"+it2.key()+" "+QString::number(it2.data())+" 0 R\n");
3133 fschmid 1663
                                        PutDoc(">>\n");
1664
                                }
1665
                                if (Shadings.count() != 0)
1666
                                {
1667
                                        PutDoc("/Shading << \n");
1668
                                        QMap<QString,int>::Iterator it3;
1669
                                        for (it3 = Shadings.begin(); it3 != Shadings.end(); ++it3)
4229 craig 1670
                                                PutDoc("/"+it3.key()+" "+QString::number(it3.data())+" 0 R\n");
3133 fschmid 1671
                                        PutDoc(">>\n");
1672
                                }
6378 fschmid 1673
                                if (Patterns.count() != 0)
1674
                                {
1675
                                        PutDoc("/Pattern << \n");
1676
                                        QMap<QString,int>::Iterator it3p;
1677
                                        for (it3p = Patterns.begin(); it3p != Patterns.end(); ++it3p)
1678
                                                PutDoc("/"+it3p.key()+" "+QString::number(it3p.data())+" 0 R\n");
1679
                                        PutDoc(">>\n");
1680
                                }
3133 fschmid 1681
                                if (Transpar.count() != 0)
1682
                                {
1683
                                        PutDoc("/ExtGState << \n");
1684
                                        QMap<QString,int>::Iterator it3t;
1685
                                        for (it3t = Transpar.begin(); it3t != Transpar.end(); ++it3t)
4229 craig 1686
                                                PutDoc("/"+it3t.key()+" "+QString::number(it3t.data())+" 0 R\n");
3133 fschmid 1687
                                        PutDoc(">>\n");
1688
                                }
1689
                                if ((ICCProfiles.count() != 0) || (spotMap.count() != 0))
1690
                                {
1691
                                        PutDoc("/ColorSpace << \n");
1692
                                        QMap<QString,ICCD>::Iterator it3c;
1693
                                        if (ICCProfiles.count() != 0)
1694
                                        {
1695
                                                for (it3c = ICCProfiles.begin(); it3c != ICCProfiles.end(); ++it3c)
4229 craig 1696
                                                        PutDoc("/"+it3c.data().ResName+" "+QString::number(it3c.data().ResNum)+" 0 R\n");
3133 fschmid 1697
                                        }
1698
                                        QMap<QString,SpotC>::Iterator it3sc;
1699
                                        if (spotMap.count() != 0)
1700
                                        {
1701
                                        for (it3sc = spotMap.begin(); it3sc != spotMap.end(); ++it3sc)
4229 craig 1702
                                                PutDoc("/"+it3sc.data().ResName+" "+QString::number(it3sc.data().ResNum)+" 0 R\n");
3133 fschmid 1703
                                        }
1704
                                        PutDoc(">>\n");
1705
                                }
1706
                                PutDoc(">>\n");
4264 craig 1707
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 1708
                                        Inhalt = CompressStr(&Inhalt);
4229 craig 1709
                                PutDoc("/Length "+QString::number(Inhalt.length()+1));
4264 craig 1710
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 1711
                                        PutDoc("\n/Filter /FlateDecode");
4229 craig 1712
                                PutDoc(" >>\nstream\n"+EncStream(Inhalt, ObjCounter-1)+"\nendstream\nendobj\n");
5685 cbradney 1713
                                QString name = pag