Subversion Repositories Scribus

Rev

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

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