Subversion Repositories Scribus

Rev

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

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