Subversion Repositories Scribus

Rev

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