Subversion Repositories Scribus

Rev

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