Subversion Repositories Scribus

Rev

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