Subversion Repositories Scribus

Rev

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