Subversion Repositories Scribus

Rev

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