Subversion Repositories Scribus

Rev

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