Subversion Repositories Scribus

Rev

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

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