Subversion Repositories Scribus

Rev

Rev 7088 | Rev 7121 | 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
                        }
4546 subik 172
 
173
                        if (usingGUI)
174
                        {
4028 cbradney 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;
4649 fschmid 188
                        PDF_ProcessPage(doc.Pages->at(pageNs[a]-1), pageNs[a]-1, doc.PDF_Options.doClip);
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);
4546 subik 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);
6889 fschmid 503
        IDg += "Scribus PDF Library "+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
        {
6165 fschmid 510
                if ((Options.Version == 14) || (Options.Version == 15))
511
                        KeyLen = 16;
512
                else
513
                        KeyLen = 5;
4264 craig 514
                CalcOwnerKey(Options.PassOwner, Options.PassUser);
515
                CalcUserKey(Options.PassUser, Options.Permissions);
3133 fschmid 516
                for (uint cl2 = 0; cl2 < 32; ++cl2)
517
                        ok += QChar(OwnerKey[cl2]);
518
                if (KeyLen > 5)
519
                {
520
                        for (uint cl3 = 0; cl3 < 16; ++cl3)
521
                                uk += QChar(UserKey[cl3]);
522
                        for (uint cl3r = 0; cl3r < 16; ++cl3r)
523
                                uk += QChar(KeyGen[cl3r]);
524
                }
525
                else
526
                {
527
                        for (uint cl = 0; cl < 32; ++cl)
528
                                uk += QChar(UserKey[cl]);
529
                }
530
        }
531
        QDate d = QDate::currentDate();
532
        Datum = "D:";
533
        tmp.sprintf("%4d", d.year());
534
        tmp.replace(QRegExp(" "), "0");
535
        Datum += tmp;
536
        tmp.sprintf("%2d", d.month());
537
        tmp.replace(QRegExp(" "), "0");
538
        Datum += tmp;
539
        tmp.sprintf("%2d", d.day());
540
        tmp.replace(QRegExp(" "), "0");
541
        Datum += tmp;
4229 craig 542
        tmp = QTime::currentTime().toString();
3133 fschmid 543
        tmp.replace(QRegExp(":"), "");
544
        Datum += tmp;
545
        StartObj(2);
546
        PutDoc("<<\n/Creator "+EncString("(Scribus "+QString(VERSION)+")",2)+"\n");
6889 fschmid 547
        PutDoc("/Producer "+EncString("(Scribus PDF Library "+QString(VERSION)+")",2)+"\n");
4718 fschmid 548
        QString docTitle = doc.documentInfo.getTitle();
549
        if ((Options.Version == 12) && (docTitle.isEmpty()))
550
                PutDoc("/Title "+EncString("("+doc.DocName+")",2)+"\n");
551
        else
552
                PutDoc("/Title "+EncString("("+doc.documentInfo.getTitle()+")",2)+"\n");
4264 craig 553
        PutDoc("/Author "+EncString("("+doc.documentInfo.getAuthor()+")",2)+"\n");
554
        PutDoc("/Keywords "+EncString("("+doc.documentInfo.getKeywords()+")",2)+"\n");
3133 fschmid 555
        PutDoc("/CreationDate "+EncString("("+Datum+")",2)+"\n");
556
        PutDoc("/ModDate "+EncString("("+Datum+")",2)+"\n");
4264 craig 557
        if (Options.Version == 12)
3133 fschmid 558
                PutDoc("/GTS_PDFXVersion (PDF/X-3:2002)\n");
559
        PutDoc("/Trapped /False\n>>\nendobj\n");
4229 craig 560
        for (int t = 0; t < 6; ++t)
561
                XRef.append(bytesWritten());
4264 craig 562
        if ((Options.Version == 15) && (Options.useLayers))
4229 craig 563
                XRef.append(bytesWritten());
4264 craig 564
        if (Options.Version == 12)
4229 craig 565
                XRef.append(bytesWritten());
4264 craig 566
        if (Options.Encrypt)
3133 fschmid 567
        {
568
                StartObj(ObjCounter);
569
                Encrypt = ObjCounter;
570
                ObjCounter++;
571
                PutDoc("<<\n/Filter /Standard\n");
572
                PutDoc( KeyLen > 5 ? "/R 3\n/V 2\n/Length 128\n" : "/R 2\n/V 1\n");
573
                PutDoc("/O <"+String2Hex(&ok)+">\n");
574
                PutDoc("/U <"+String2Hex(&uk)+">\n");
4264 craig 575
                PutDoc("/P "+QString::number(Options.Permissions)+"\n>>\nendobj\n");
3133 fschmid 576
        }
577
        RealFonts = DocFonts;
3544 avox 578
        QMap<QString,int> ReallyUsed;
3133 fschmid 579
        ReallyUsed.clear();
580
        PageItem* pgit;
4017 fschmid 581
        QMap<int, QString> ind2PDFabr;
4546 subik 582
        const QString tmpf[] = {"/Courier", "/Courier-Bold", "/Courier-Oblique", "/Courier-BoldOblique",
4017 fschmid 583
                                                                                                "/Helvetica", "/Helvetica-Bold", "/Helvetica-Oblique", "/Helvetica-BoldOblique",
4546 subik 584
                                                                                                "/Times-Roman", "/Times-Bold", "/Times-Italic", "/Times-BoldItalic",
4017 fschmid 585
                                                                                                "/ZapfDingbats", "/Symbol"};
586
        size_t ar = sizeof(tmpf) / sizeof(*tmpf);
587
        for (uint ax = 0; ax < ar; ++ax)
588
                ind2PDFabr[ax] = tmpf[ax];
4264 craig 589
        for (uint c = 0; c < doc.FrameItems.count(); ++c)
3133 fschmid 590
        {
4264 craig 591
                pgit = doc.FrameItems.at(c);
3133 fschmid 592
                if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
593
                {
4084 cbradney 594
                        if (pgit->isAnnotation())
595
                                StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
3133 fschmid 596
                        for (uint e = 0; e < pgit->itemText.count(); ++e)
597
                        {
3544 avox 598
                                ReallyUsed.insert(pgit->itemText.at(e)->cfont->scName(), DocFonts[pgit->itemText.at(e)->cfont->scName()]);
3133 fschmid 599
                        }
600
                }
601
        }
4264 craig 602
        for (uint c = 0; c < doc.MasterItems.count(); ++c)
3133 fschmid 603
        {
4264 craig 604
                pgit = doc.MasterItems.at(c);
3133 fschmid 605
                if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
606
                {
4084 cbradney 607
                        if (pgit->isAnnotation())
608
                                StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
3133 fschmid 609
                        for (uint e = 0; e < pgit->itemText.count(); ++e)
610
                        {
3544 avox 611
                                ReallyUsed.insert(pgit->itemText.at(e)->cfont->scName(), DocFonts[pgit->itemText.at(e)->cfont->scName()]);
3133 fschmid 612
                        }
613
                }
614
        }
4264 craig 615
        for (uint d = 0; d < doc.Items->count(); ++d)
3133 fschmid 616
        {
4264 craig 617
                pgit = doc.Items->at(d);
3133 fschmid 618
                if ((pgit->itemType() == PageItem::TextFrame) || (pgit->itemType() == PageItem::PathText))
619
                {
4084 cbradney 620
                        if (pgit->isAnnotation())
621
                                StdFonts.insert(ind2PDFabr[pgit->annotation().Font()], "");
3133 fschmid 622
                        for (uint e = 0; e < pgit->itemText.count(); ++e)
623
                        {
3544 avox 624
                                ReallyUsed.insert(pgit->itemText.at(e)->cfont->scName(), DocFonts[pgit->itemText.at(e)->cfont->scName()]);
3133 fschmid 625
                        }
626
                }
627
        }
4017 fschmid 628
        a = 0;
629
        QMap<QString, QString>::Iterator itStd;
630
        for (itStd = StdFonts.begin(); itStd != StdFonts.end(); ++itStd)
631
        {
632
                StartObj(ObjCounter);
633
                PutDoc("<<\n/Type /Font\n/Subtype /Type1\n");
634
                PutDoc("/BaseFont "+itStd.key()+"\n");
635
                PutDoc(">>\nendobj\n");
4229 craig 636
                Seite.FObjects["FoStd"+QString::number(a)] = ObjCounter;
637
                itStd.data() = "FoStd"+QString::number(a);
4017 fschmid 638
                ObjCounter++;
639
                a++;
640
        }
3544 avox 641
        QMap<QString,int>::Iterator it;
3133 fschmid 642
        a = 0;
643
        for (it = ReallyUsed.begin(); it != ReallyUsed.end(); ++it)
644
        {
645
                Foi::FontFormat fformat = AllFonts[it.key()]->formatCode;
7088 fschmid 646
                if ((!AllFonts[it.key()]->HasNames) || (Options.SubsetList.contains(it.key())))
3133 fschmid 647
                {
3829 cbradney 648
                        QString fon("");
3133 fschmid 649
                        QMap<uint,FPointArray>::Iterator ig;
650
                        for (ig = AllFonts[it.key()]->RealGlyphs.begin(); ig != AllFonts[it.key()]->RealGlyphs.end(); ++ig)
651
                        {
652
                                FPoint np, np1, np2;
653
                                bool nPath = true;
5609 cbradney 654
                                fon = "";
3133 fschmid 655
                                if (ig.data().size() > 3)
656
                                {
657
                                        FPointArray gly = ig.data().copy();
658
                                        QWMatrix mat;
659
                                        mat.scale(0.1, 0.1);
660
                                        gly.map(mat);
661
                                        for (uint poi = 0; poi < gly.size()-3; poi += 4)
662
                                        {
663
                                                if (gly.point(poi).x() > 900000)
664
                                                {
665
                                                        fon += "h\n";
666
                                                        nPath = true;
667
                                                        continue;
668
                                                }
669
                                                if (nPath)
670
                                                {
671
                                                        np = gly.point(poi);
672
                                                        fon += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
673
                                                        nPath = false;
674
                                                }
675
                                                np = gly.point(poi+1);
676
                                                np1 = gly.point(poi+3);
677
                                                np2 = gly.point(poi+2);
678
                                                fon += FToStr(np.x()) + " " + FToStr(-np.y()) + " " +
679
                                                         FToStr(np1.x()) + " " + FToStr(-np1.y()) + " " +
680
                                                         FToStr(np2.x()) + " " + FToStr(-np2.y()) + " c\n";
681
                                        }
682
                                        fon += "h f*\n";
683
                                        np = getMinClipF(&gly);
684
                                        np1 = getMaxClipF(&gly);
685
                                }
5609 cbradney 686
                                else
687
                                {
688
                                        fon = "h";
689
                                        np = FPoint(0, 0);
690
                                        np1 = FPoint(0, 0);
691
                                }
692
                                StartObj(ObjCounter);
693
                                ObjCounter++;
694
                                PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1\n");
695
                                PutDoc("/BBox [ "+FToStr(np.x())+" "+FToStr(-np.y())+" "+FToStr(np1.x())+ " "+FToStr(-np1.y())+" ]\n");
696
                                PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
697
                                PutDoc(">>\n");
698
                                if ((Options.Compress) && (CompAvail))
699
                                        fon = CompressStr(&fon);
700
                                PutDoc("/Length "+QString::number(fon.length()+1));
701
                                if ((Options.Compress) && (CompAvail))
702
                                        PutDoc("\n/Filter /FlateDecode");
703
                                PutDoc(" >>\nstream\n"+EncStream(fon, ObjCounter-1)+"\nendstream\nendobj\n");
704
                                Seite.XObjects[AllFonts[it.key()]->RealName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+QString::number(ig.key())] = ObjCounter-1;
3133 fschmid 705
                        }
706
                        AllFonts[it.key()]->RealGlyphs.clear();
707
                }
708
                else
709
                {
4229 craig 710
                        UsedFontsP.insert(it.key(), "/Fo"+QString::number(a));
4264 craig 711
                        if ((fformat == Foi::PFB) && (Options.EmbedList.contains(it.key())))
3133 fschmid 712
                        {
3829 cbradney 713
                                QString fon("");
3133 fschmid 714
                                StartObj(ObjCounter);
715
                                QByteArray bb;
716
                                AllFonts[it.key()]->RawData(bb);
717
                                uint posi;
718
                                for (posi = 6; posi < bb.size(); ++posi)
719
                                {
720
                                        if ((bb[posi] == static_cast<char>(0x80)) && (static_cast<int>(bb[posi+1]) == 2))
721
                                                break;
722
                                        fon += QChar(bb[posi]);
723
                                }
724
                                int len1 = fon.length();
725
                                uint ulen;
726
                                ulen = bb[posi+2] & 0xff;
727
                                ulen |= (bb[posi+3] << 8) & 0xff00;
728
                                ulen |= (bb[posi+4] << 16) & 0xff0000;
729
                                ulen |= (bb[posi+5] << 24) & 0xff000000;
730
                                if (ulen > bb.size())
731
                                        ulen = bb.size()-7;
732
                                posi += 6;
733
                                for (uint j = 0; j < ulen; ++j)
734
                                        fon += QChar(bb[posi++]);
735
                                posi += 6;
736
                                int len2 = fon.length()-len1;
737
                                for (uint j = posi; j < bb.size(); ++j)
738
                                {
739
                                        if ((bb[j] == static_cast<char>(0x80)) && (static_cast<int>(bb[j+1]) == 3))
740
                                                break;
741
                                        if (bb[j] == '\r')
742
                                                fon += "\n";
743
                                        else
744
                                                fon += QChar(bb[j]);
745
                                }
746
                                int len3 = fon.length()-len2-len1;
4264 craig 747
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 748
                                        fon = CompressStr(&fon);
4229 craig 749
                                PutDoc("<<\n/Length "+QString::number(fon.length()+1)+"\n");
750
                                PutDoc("/Length1 "+QString::number(len1)+"\n");
751
                                PutDoc("/Length2 "+QString::number(len2)+"\n");
752
                                PutDoc("/Length3 "+QString::number(len3)+"\n");
4264 craig 753
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 754
                                        PutDoc("/Filter /FlateDecode\n");
4229 craig 755
                                PutDoc(">>\nstream\n"+EncStream(fon,ObjCounter)+"\nendstream\nendobj\n");
3133 fschmid 756
                                ObjCounter++;
757
                        }
4264 craig 758
                        if ((fformat == Foi::PFA) && (Options.EmbedList.contains(it.key())))
3133 fschmid 759
                        {
3829 cbradney 760
                                QString fon("");
761
                                QString fon2("");
762
                                QString tm("");
3133 fschmid 763
                                uint value;
764
                                bool ok = true;
765
                                StartObj(ObjCounter);
766
                                AllFonts[it.key()]->EmbedFont(fon);
767
                                int len1 = fon.find("eexec")+5;
768
                                fon2 = fon.left(len1)+"\n";
769
                                int len2 = fon.find("0000000000000000000000000");
770
                                if (len2 == -1)
771
                                        len2 = fon.length()+1;
772
                                int count = 0;
773
                                for (int xx = len1; xx < len2-1; ++xx)
774
                                {
775
                                        tm = fon.at(xx);
776
                                        if ((tm == QChar(13)) || (tm == QChar(10)))
777
                                                continue;
778
                                        xx++;
779
                                        count++;
780
                                        tm += fon.at(xx);
781
                                        value = tm.toUInt(&ok, 16);
782
                                        fon2 += QChar(value);
783
                                }
784
                                fon2 += fon.mid(len2);
4264 craig 785
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 786
                                        fon2 = CompressStr(&fon2);
4229 craig 787
                                PutDoc("<<\n/Length "+QString::number(fon2.length()+1)+"\n");
788
                                PutDoc("/Length1 "+QString::number(len1+1)+"\n");
789
                                PutDoc("/Length2 "+QString::number(count)+"\n");
790
                                PutDoc(static_cast<int>(fon.length()-len2) == -1 ? QString("/Length3 0\n") : "/Length3 "+QString::number(fon.length()-len2)+"\n");
4264 craig 791
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 792
                                        PutDoc("/Filter /FlateDecode\n");
4229 craig 793
                                PutDoc(">>\nstream\n"+EncStream(fon2, ObjCounter)+"\nendstream\nendobj\n");
3133 fschmid 794
                                ObjCounter++;
795
                        }
4264 craig 796
                        if ((fformat == Foi::SFNT || fformat == Foi::TTCF) && (Options.EmbedList.contains(it.key())))
3133 fschmid 797
                        {
3829 cbradney 798
                                QString fon("");
3133 fschmid 799
                                StartObj(ObjCounter);
800
                                QByteArray bb;
801
                                AllFonts[it.key()]->RawData(bb);
802
                                //AV: += and append() dont't work because they stop at '\0' :-(
803
                                for (unsigned int i=0; i < bb.size(); i++)
804
                                        fon += QChar(bb[i]);
805
                                int len = fon.length();
4264 craig 806
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 807
                                        fon = CompressStr(&fon);
808
                                //qDebug(QString("sfnt data: size=%1 before=%2 compressed=%3").arg(bb.size()).arg(len).arg(fon.length()));
4229 craig 809
                                PutDoc("<<\n/Length "+QString::number(fon.length()+1)+"\n");
810
                                PutDoc("/Length1 "+QString::number(len)+"\n");
4264 craig 811
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 812
                                        PutDoc("/Filter /FlateDecode\n");
4229 craig 813
                                PutDoc(">>\nstream\n"+EncStream(fon, ObjCounter)+"\nendstream\nendobj\n");
3133 fschmid 814
                                ObjCounter++;
815
                        }
816
                        StartObj(ObjCounter);
817
                        PutDoc("<<\n/Type /FontDescriptor\n");
3440 fschmid 818
                        PutDoc("/FontName /"+AllFonts[it.key()]->RealName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
3133 fschmid 819
                        PutDoc("/FontBBox [ "+AllFonts[it.key()]->FontBBox+" ]\n");
820
                        PutDoc("/Flags ");
3544 avox 821
                        //FIXME: isItalic() should be queried from Foi, not from Qt -- AV
822
                        //QFontInfo fo = QFontInfo(it.data());
3133 fschmid 823
                        int pfl = 0;
824
                        if (AllFonts[it.key()]->IsFixedPitch)
825
                                pfl = pfl ^ 1;
3544 avox 826
                        //if (fo.italic())
827
                        if (AllFonts[it.key()]->ItalicAngle != "0")
3133 fschmid 828
                                pfl = pfl ^ 64;
829
//                      pfl = pfl ^ 4;
830
                        pfl = pfl ^ 32;
4229 craig 831
                        PutDoc(QString::number(pfl)+"\n");
3133 fschmid 832
                        PutDoc("/Ascent "+AllFonts[it.key()]->Ascent+"\n");
833
                        PutDoc("/Descent "+AllFonts[it.key()]->Descender+"\n");
834
                        PutDoc("/CapHeight "+AllFonts[it.key()]->CapHeight+"\n");
835
                        PutDoc("/ItalicAngle "+AllFonts[it.key()]->ItalicAngle+"\n");
836
                        PutDoc("/StemV "+AllFonts[it.key()]->StdVW+"\n");
4264 craig 837
                        if ((fformat == Foi::SFNT || fformat == Foi::TTCF) && (Options.EmbedList.contains(it.key())))
4229 craig 838
                                PutDoc("/FontFile2 "+QString::number(ObjCounter-1)+" 0 R\n");
4264 craig 839
                        if ((fformat == Foi::PFB) && (Options.EmbedList.contains(it.key())))
4229 craig 840
                                PutDoc("/FontFile "+QString::number(ObjCounter-1)+" 0 R\n");
4264 craig 841
                        if ((fformat == Foi::PFA) && (Options.EmbedList.contains(it.key())))
4229 craig 842
                                PutDoc("/FontFile "+QString::number(ObjCounter-1)+" 0 R\n");
3133 fschmid 843
                        PutDoc(">>\nendobj\n");
844
                        ObjCounter++;
4546 subik 845
/*                      if (!FT_Has_PS_Glyph_Names(AllFonts[it.key()])
3133 fschmid 846
                        {
847
                                StartObj(ObjCounter);
848
                                int chCount = 31;
849
                                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 ");
850
                                for (int ww = 31; ww < 256; ++ww)
851
                                {
4229 craig 852
                                        PutDoc(QString::number(static_cast<int>(AllFonts[it.key()]->CharWidth[itg.key()]*
3133 fschmid 853
                                                        1000))+" ");
854
                                        if (itg == gl.end())
855
                                                break;
856
                                        ++itg;
857
                                        chCount++;
858
                                }
859
                                PutDoc("]\nendobj\n");
860
                                ObjCounter++;
861
                                // put widths object
862
                                // encoding dictionary w/ base encoding w/o differences
863
                                StartObj(ObjCounter);
864
                                PutDoc("<<\n/Type /Font\n/Subtype ");
865
                                PutDoc((fformat == Foi::SFNT || fformat == Foi::TTCF) ? "/TrueType\n" : "/Type1\n");
4229 craig 866
                                PutDoc("/Name /Fo"+QString::number(a)+"\n");
3304 fschmid 867
                                PutDoc("/BaseFont /"+AllFonts[it.key()]->RealName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "" )+"\n");
3133 fschmid 868
                                //cf. widths:
869
                                PutDoc("/FirstChar 0\n");
4229 craig 870
                                PutDoc("/LastChar "+QString::number(chCount-1)+"\n");
871
                                PutDoc("/Widths "+QString::number(ObjCounter-1)+" 0 R\n");
872
                                PutDoc("/FontDescriptor "+QString::number(ObjCounter-2)+" 0 R\n");
3133 fschmid 873
                                PutDoc(">>\nendobj\n");
4229 craig 874
                                Seite.FObjects["Fo"+QString::number(a)] = ObjCounter;
3133 fschmid 875
                                ObjCounter++;
876
                        }
877
                        else */
878
//                      {
879
                                GListeInd gl;
880
                                GlyIndex(AllFonts[it.key()], &gl);
881
                                GlyphsIdxOfFont.insert(it.key(), gl);
882
                                uint FontDes = ObjCounter - 1;
883
                                GListeInd::Iterator itg;
884
                                itg = gl.begin();
885
                                GListeInd::Iterator itg2;
886
                                itg2 = gl.begin();
887
                                uint Fcc = gl.count() / 224;
888
                                if ((gl.count() % 224) != 0)
889
                                        Fcc += 1;
890
                                for (uint Fc = 0; Fc < Fcc; ++Fc)
891
                                {
892
                                        StartObj(ObjCounter);
893
                                        int chCount = 31;
894
                                        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 ");
895
                                        for (int ww = 31; ww < 256; ++ww)
896
                                        {
4229 craig 897
                                                PutDoc(QString::number(static_cast<int>(AllFonts[it.key()]->CharWidth[itg.key()]* 1000))+" ");
3133 fschmid 898
                                                if (itg == gl.end())
899
                                                        break;
900
                                                ++itg;
901
                                                chCount++;
902
                                        }
903
                                        PutDoc("]\nendobj\n");
904
                                        ObjCounter++;
905
                                        StartObj(ObjCounter);
906
                                        ObjCounter++;
907
                                        PutDoc("<< /Type /Encoding\n");
908
//                                      PutDoc("/BaseEncoding /" + AllFonts[it.key()]->FontEnc + "\n");
909
                                        PutDoc("/Differences [ 32\n");
910
                                        int crc = 0;
911
                                        for (int ww2 = 32; ww2 < 256; ++ww2)
912
                                        {
913
                                                PutDoc(itg2.data().Name+" ");
914
                                                if (itg2 == gl.end())
915
                                                        break;
916
                                                ++itg2;
917
                                                crc++;
918
                                                if (crc > 8)
919
                                                {
920
                                                        PutDoc("\n");
921
                                                        crc = 0;
922
                                                }
923
                                        }
924
                                        PutDoc("]\n");
4546 subik 925
 
3133 fschmid 926
                                        PutDoc(">>\nendobj\n");
927
                                        StartObj(ObjCounter);
928
                                        PutDoc("<<\n/Type /Font\n/Subtype ");
929
                                        PutDoc((fformat == Foi::SFNT || fformat == Foi::TTCF) ? "/TrueType\n" : "/Type1\n");
4229 craig 930
                                        PutDoc("/Name /Fo"+QString::number(a)+"S"+QString::number(Fc)+"\n");
3440 fschmid 931
                                        PutDoc("/BaseFont /"+AllFonts[it.key()]->RealName().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )+"\n");
3133 fschmid 932
                                        PutDoc("/FirstChar 0\n");
4229 craig 933
                                        PutDoc("/LastChar "+QString::number(chCount-1)+"\n");
934
                                        PutDoc("/Widths "+QString::number(ObjCounter-2)+" 0 R\n");
935
                                        PutDoc("/Encoding "+QString::number(ObjCounter-1)+" 0 R\n");
936
                                        PutDoc("/FontDescriptor "+QString::number(FontDes)+" 0 R\n");
3133 fschmid 937
                                        PutDoc(">>\nendobj\n");
4229 craig 938
                                        Seite.FObjects["Fo"+QString::number(a)+"S"+QString::number(Fc)] = ObjCounter;
3133 fschmid 939
                                        ObjCounter++;
940
                                } // for(Fc)
941
//                      } // FT_Has_PS_Glyph_Names
942
                }
943
                a++;
944
        }
4264 craig 945
        if (Options.UseLPI)
3133 fschmid 946
        {
947
                StartObj(ObjCounter);
948
                PutDoc("<<\n/Type /Halftone\n/HalftoneType 5\n");
4264 craig 949
                QMap<QString,LPIData>::const_iterator itlp;
950
                for (itlp = Options.LPISettings.constBegin(); itlp != Options.LPISettings.constEnd(); ++itlp)
3133 fschmid 951
                {
952
                        PutDoc("/"+itlp.key()+"\n<<\n/Type /Halftone\n/HalftoneType 1\n/Frequency ");
4229 craig 953
                        PutDoc(QString::number(itlp.data().Frequency)+"\n/Angle "+QString::number(itlp.data().Angle)+"\n/SpotFunction ");
3829 cbradney 954
                        QString func ("");
3133 fschmid 955
                        switch (itlp.data().SpotFunc)
956
                        {
957
                                case 0:
958
                                        func = "/SimpleDot";
959
                                        break;
960
                                case 1:
961
                                        func = "/Line";
962
                                        break;
963
                                case 2:
964
                                        func = "/Round";
965
                                        break;
966
                                case 3:
967
                                        func = "/Ellipse";
968
                                        break;
969
                                default:
970
                                        func = "/SimpleDot";
971
                                        break;
972
                        }
973
                        PutDoc(func+"\n>>\n");
974
                }
975
                PutDoc("/Default\n<<\n/Type /Halftone\n/HalftoneType 1\n/Frequency 50\n/Angle 45\n/SpotFunction /Round\n>>\n");
976
                PutDoc(">>\nendobj\n");
977
                ObjCounter++;
978
                StartObj(ObjCounter);
4229 craig 979
                HTName = ResNam+QString::number(ResCount);
3133 fschmid 980
                Transpar[HTName] = ObjCounter;
4229 craig 981
                PutDoc("<< /Type /ExtGState\n/HT "+QString::number(ObjCounter-1)+" 0 R\n>>\nendobj\n");
3133 fschmid 982
                ResCount++;
983
                ObjCounter++;
984
        }
985
#ifdef HAVE_CMS
4264 craig 986
        if ((CMSuse) && (Options.UseProfiles))
3133 fschmid 987
        {
988
                StartObj(ObjCounter);
989
                ObjCounter++;
990
                QString dataP;
991
                struct ICCD dataD;
4264 craig 992
                loadText(ScMW->InputProfiles[Options.SolidProf], &dataP);
3133 fschmid 993
                PutDoc("<<\n");
4264 craig 994
                if ((Options.Compress) && (CompAvail))
3133 fschmid 995
                {
996
                        PutDoc("/Filter /FlateDecode\n");
997
                        dataP = CompressStr(&dataP);
998
                }
4229 craig 999
                PutDoc("/Length "+QString::number(dataP.length()+1)+"\n");
4264 craig 1000
                PutDoc("/N "+QString::number(Options.SComp)+"\n");
4229 craig 1001
                PutDoc(">>\nstream\n"+EncStream(dataP, ObjCounter-1)+"\nendstream\nendobj\n");
3133 fschmid 1002
                StartObj(ObjCounter);
4229 craig 1003
                dataD.ResName = ResNam+QString::number(ResCount);
1004
                dataD.ICCArray = "[ /ICCBased "+QString::number(ObjCounter-1)+" 0 R ]";
3133 fschmid 1005
                dataD.ResNum = ObjCounter;
4264 craig 1006
                ICCProfiles[Options.SolidProf] = dataD;
4229 craig 1007
                PutDoc("[ /ICCBased "+QString::number(ObjCounter-1)+" 0 R ]\n");
3133 fschmid 1008
                PutDoc("endobj\n");
1009
                ResCount++;
1010
                ObjCounter++;
1011
        }
1012
#endif
4264 craig 1013
        if (((Options.isGrayscale == false) && (Options.UseRGB == false)) && (Options.UseSpotColors))
3133 fschmid 1014
        {
4264 craig 1015
                doc.getUsedColors(colorsToUse);
3133 fschmid 1016
                ColorList::Iterator itf;
1017
                for (itf = colorsToUse.begin(); itf != colorsToUse.end(); ++itf)
1018
                {
1019
                        if ((colorsToUse[itf.key()].isSpotColor()) || (colorsToUse[itf.key()].isRegistrationColor()))
1020
                        {
1021
                                int cc, cm, cy, ck;
1022
                                struct SpotC spotD;
1023
                                colorsToUse[itf.key()].getCMYK(&cc, &cm, &cy, &ck);
1024
                                QString colorDesc = "{\ndup "+FToStr(static_cast<double>(cc) / 255)+"\nmul exch dup ";
1025
                                colorDesc += FToStr(static_cast<double>(cm) / 255)+"\nmul exch dup ";
1026
                                colorDesc += FToStr(static_cast<double>(cy) / 255)+"\nmul exch ";
1027
                                colorDesc += FToStr(static_cast<double>(ck) / 255)+" mul }";
1028
                                StartObj(ObjCounter);
1029
                                ObjCounter++;
1030
                                PutDoc("<<\n/FunctionType 4\n");
1031
                                PutDoc("/Domain [0.0 1.0]\n");
1032
                                PutDoc("/Range [0.0 1.0 0.0 1.0 0.0 1.0 0.0 1.0]\n");
4229 craig 1033
                                PutDoc("/Length "+QString::number(colorDesc.length()+1)+"\n");
1034
                                PutDoc(">>\nstream\n"+EncStream(colorDesc, ObjCounter-1)+"\nendstream\nendobj\n");
3133 fschmid 1035
                                StartObj(ObjCounter);
1036
                                PutDoc("[ /Separation /");
1037
                                if (colorsToUse[itf.key()].isRegistrationColor())
1038
                                        PutDoc("All");
1039
                                else
7072 fschmid 1040
                                        PutDoc(itf.key().simplifyWhiteSpace().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "#20" ));
4229 craig 1041
                                PutDoc(" /DeviceCMYK "+QString::number(ObjCounter-1)+" 0 R ]\nendobj\n");
1042
                                spotD.ResName = spotNam+QString::number(spotCount);
3133 fschmid 1043
                                spotD.ResNum = ObjCounter;
1044
                                spotMap.insert(itf.key(), spotD);
1045
                                spotCount++;
1046
                                ObjCounter++;
1047
                        }
1048
                }
1049
        }
4264 craig 1050
        if ((Options.Version == 15) && (Options.useLayers))
3133 fschmid 1051
        {
1052
                struct Layer ll;
1053
                struct OCGInfo ocg;
1054
                ll.isPrintable = false;
1055
                ll.LNr = 0;
1056
                int Lnr = 0;
3829 cbradney 1057
                QString ocgNam("oc");
4264 craig 1058
                uint docLayersCount=doc.Layers.count();
3829 cbradney 1059
                for (uint la = 0; la < docLayersCount; ++la)
3133 fschmid 1060
                {
3829 cbradney 1061
                        QString tmp("");
4264 craig 1062
                        Level2Layer(&doc, &ll, Lnr);
3133 fschmid 1063
                        ocg.Name = ocgNam+tmp.setNum(ll.LNr);
1064
                        ocg.ObjNum = ObjCounter;
1065
                        ocg.visible = ll.isViewable;
1066
                        OCGEntries.insert(ll.Name, ocg);
1067
                        StartObj(ObjCounter);
1068
                        ObjCounter++;
1069
                        PutDoc("<<\n");
1070
                        PutDoc("/Type /OCG\n");
1071
                        PutDoc("/Name ("+ll.Name+")\n");
1072
                        PutDoc(">>\nendobj\n");
1073
                        Lnr++;
1074
                }
1075
        }
1076
        return true;
1077
}
1078
 
4241 craig 1079
void PDFlib::PDF_TemplatePage(const Page* pag, bool )
3133 fschmid 1080
{
1081
        QString tmp;
1082
        ActPageP = pag;
1083
        PageItem* ite;
1084
        QPtrList<PageItem> PItems;
1085
        int Lnr = 0;
1086
        struct Layer ll;
1087
        ll.isPrintable = false;
1088
        ll.LNr = 0;
1089
        Inhalt = "";
1090
        Seite.AObjects.clear();
4264 craig 1091
        for (uint la = 0; la < doc.Layers.count(); ++la)
3133 fschmid 1092
        {
4264 craig 1093
                Level2Layer(&doc, &ll, Lnr);
1094
                PItems = doc.MasterItems;
3133 fschmid 1095
                if (ll.isPrintable)
1096
                {
4264 craig 1097
                        if ((Options.Version == 15) && (Options.useLayers))
3133 fschmid 1098
                                PutPage("/OC /"+OCGEntries[ll.Name].Name+" BDC\n");
1099
                        for (uint a = 0; a < PItems.count(); ++a)
1100
                        {
1101
                                Inhalt = "";
1102
                                ite =PItems.at(a);
1103
                                if (ite->LayerNr != ll.LNr)
1104
                                        continue;
4726 fschmid 1105
                                double x = pag->xOffset();
1106
                                double y = pag->yOffset();
1107
                                double w = pag->width();
1108
                                double h1 = pag->height();
4580 cbradney 1109
                                double ilw=ite->lineWidth();
4726 fschmid 1110
                                double x2 = ite->BoundingX - ilw / 2.0;
1111
                                double y2 = ite->BoundingY - ilw / 2.0;
1112
                                double w2 = ite->BoundingW + ilw;
1113
                                double h2 = ite->BoundingH + ilw;
1114
                                if (!( QMAX( x, x2 ) <= QMIN( x+w, x2+w2 ) && QMAX( y, y2 ) <= QMIN( y+h1, y2+h2 )))
3133 fschmid 1115
                                        continue;
1116
                                if (ite->ChangedMasterItem)
1117
                                        continue;
3200 cbradney 1118
                                if ((!pag->PageNam.isEmpty()) && (ite->OwnPage != static_cast<int>(pag->pageNr())) && (ite->OwnPage != -1))
3133 fschmid 1119
                                        continue;
1120
                                PutPage("q\n");
4264 craig 1121
                                if (((ite->fillTransparency() != 0) || (ite->lineTransparency() != 0)) && (Options.Version >= 14))
3133 fschmid 1122
                                        PutPage(PDF_Transparenz(ite));
4679 fschmid 1123
/* Bookmarks on Master Pages do not make any sense */
1124
//                              if ((ite->isBookmark) && (Options.Bookmarks))
1125
//                                      PDF_Bookmark(ite, pag->height() - (ite->yPos() - pag->yOffset()));
4698 cbradney 1126
                                if (!ite->printEnabled() || ((ite->itemType() == PageItem::TextFrame) && (!pag->PageNam.isEmpty())))
3133 fschmid 1127
                                {
1128
                                        PutPage("Q\n");
1129
                                        continue;
1130
                                }
4546 subik 1131
                                if (ite->fillColor() != CommonStrings::None)
3133 fschmid 1132
                                        PutPage(putColor(ite->fillColor(), ite->fillShade(), true));
4546 subik 1133
                                if (ite->lineColor() != CommonStrings::None)
3133 fschmid 1134
                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), false));
4580 cbradney 1135
                                Inhalt += FToStr(fabs(ite->lineWidth()))+" w\n";
3133 fschmid 1136
                                if (ite->DashValues.count() != 0)
1137
                                {
1138
                                        PutPage("[ ");
1139
                                        QValueList<double>::iterator it;
1140
                                        for ( it = ite->DashValues.begin(); it != ite->DashValues.end(); ++it )
1141
                                        {
1142
                                                int da = static_cast<int>(*it);
1143
                                                if (da != 0)
4229 craig 1144
                                                        PutPage(QString::number(da)+" ");
3133 fschmid 1145
                                        }
4229 craig 1146
                                        PutPage("] "+QString::number(static_cast<int>(ite->DashOffset))+" d\n");
3133 fschmid 1147
                                }
1148
                                else
1149
                                {
4580 cbradney 1150
                                        QString Dt = FToStr(QMAX(2*fabs(ite->lineWidth()), 1));
1151
                                        QString Da = FToStr(QMAX(6*fabs(ite->lineWidth()), 1));
3133 fschmid 1152
                                        switch (ite->PLineArt)
1153
                                        {
1154
                                                case Qt::SolidLine:
1155
                                                        PutPage("[] 0 d\n");
1156
                                                        break;
1157
                                                case Qt::DashLine:
1158
                                                        PutPage("["+Da+" "+Dt+"] 0 d\n");
1159
                                                        break;
1160
                                                case Qt::DotLine:
1161
                                                        PutPage("["+Dt+"] 0 d\n");
1162
                                                        break;
1163
                                                case Qt::DashDotLine:
1164
                                                        PutPage("["+Da+" "+Dt+" "+Dt+" "+Dt+"] 0 d\n");
1165
                                                        break;
1166
                                                case Qt::DashDotDotLine:
1167
                                                        PutPage("["+Da+" "+Dt+" "+Dt+" "+Dt+" "+Dt+" "+Dt+"] 0 d\n");
1168
                                                        break;
1169
                                                default:
1170
                                                        PutPage("[] 0 d\n");
1171
                                                        break;
1172
                                        }
1173
                                }
1174
                                switch (ite->PLineEnd)
1175
                                {
1176
                                        case Qt::FlatCap:
1177
                                                PutPage("0 J\n");
1178
                                                break;
1179
                                        case Qt::SquareCap:
1180
                                                PutPage("2 J\n");
1181
                                                break;
1182
                                        case Qt::RoundCap:
1183
                                                PutPage("1 J\n");
1184
                                                break;
1185
                                        default:
1186
                                                PutPage("0 J\n");
1187
                                                break;
1188
                                }
1189
                                switch (ite->PLineJoin)
1190
                                {
1191
                                        case Qt::MiterJoin:
1192
                                                PutPage("0 j\n");
1193
                                                break;
1194
                                        case Qt::BevelJoin:
1195
                                                PutPage("2 j\n");
1196
                                                break;
1197
                                        case Qt::RoundJoin:
1198
                                                PutPage("1 j\n");
1199
                                                break;
1200
                                        default:
1201
                                                PutPage("0 j\n");
1202
                                                break;
1203
                                }
3903 cbradney 1204
                                PutPage("1 0 0 1 "+FToStr(ite->xPos() - pag->xOffset())+" "+FToStr(pag->height() - (ite->yPos()  - pag->yOffset()))+" cm\n");
3934 cbradney 1205
                                if (ite->rotation() != 0)
3133 fschmid 1206
                                {
3934 cbradney 1207
                                        double sr = sin(-ite->rotation()* M_PI / 180.0);
1208
                                        double cr = cos(-ite->rotation()* M_PI / 180.0);
3133 fschmid 1209
                                        if ((cr * cr) < 0.000001)
1210
                                                cr = 0;
1211
                                        if ((sr * sr) < 0.000001)
1212
                                                sr = 0;
1213
                                        PutPage(FToStr(cr)+" "+FToStr(sr)+" "+FToStr(-sr)+" "+FToStr(cr)+" 0 0 cm\n");
1214
                                }
1215
                                switch (ite->itemType())
1216
                                {
1217
                                        case PageItem::ImageFrame:
4546 subik 1218
                                                if ((ite->fillColor() != CommonStrings::None) || (ite->GrType != 0))
3133 fschmid 1219
                                                {
1220
                                                        if (ite->GrType != 0)
1221
                                                                PutPage(PDF_Gradient(ite));
1222
                                                        else
1223
                                                        {
1224
                                                                PutPage(SetClipPath(ite));
1225
                                                                PutPage("h\nf*\n");
1226
                                                        }
1227
                                                }
1228
                                                PutPage("q\n");
1229
                                                if (ite->imageClip.size() != 0)
4744 fschmid 1230
                                                {
3133 fschmid 1231
                                                        PutPage(SetClipPathImage(ite));
4744 fschmid 1232
                                                        PutPage("h\nW*\nn\n");
1233
                                                }
1234
                                                PutPage(SetClipPath(ite));
3133 fschmid 1235
                                                PutPage("h\nW*\nn\n");
1236
                                                if (ite->imageFlippedH())
3934 cbradney 1237
                                                        PutPage("-1 0 0 1 "+FToStr(ite->width())+" 0 cm\n");
3133 fschmid 1238
                                                if (ite->imageFlippedV())
3934 cbradney 1239
                                                        PutPage("1 0 0 -1 0 "+FToStr(-ite->height())+" cm\n");
3133 fschmid 1240
                                                if ((ite->PicAvail) && (!ite->Pfile.isEmpty()))
3985 cbradney 1241
                                                        PutPage(PDF_Image(ite, ite->Pfile, ite->imageXScale(), ite->imageYScale(), ite->imageXOffset(), -ite->imageYOffset(), false, ite->IProfile, ite->UseEmbedded, ite->IRender));
3133 fschmid 1242
                                                PutPage("Q\n");
4546 subik 1243
                                                if (((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty())) && (!ite->isTableItem))
3133 fschmid 1244
                                                {
4580 cbradney 1245
                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1246
                                                        {
1247
                                                                PutPage(SetClipPath(ite));
1248
                                                                PutPage("h\nS\n");
1249
                                                        }
1250
                                                        else
1251
                                                        {
4264 craig 1252
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1253
                                                                for (int it = ml.size()-1; it > -1; it--)
1254
                                                                {
6569 fschmid 1255
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1256
                                                                        {
1257
                                                                                PutPage(setStrokeMulti(&ml[it]));
1258
                                                                                PutPage(SetClipPath(ite));
1259
                                                                                PutPage("h\nS\n");
1260
                                                                        }
3133 fschmid 1261
                                                                }
1262
                                                        }
1263
                                                }
1264
                                                break;
1265
                                        case PageItem::TextFrame:
1266
                                                break;
1267
                                        case PageItem::Line:
1268
                                                if (ite->NamedLStyle.isEmpty())
1269
                                                {
1270
                                                        PutPage("0 0 m\n");
3934 cbradney 1271
                                                        PutPage(FToStr(ite->width())+" 0 l\n");
3133 fschmid 1272
                                                        PutPage("S\n");
1273
                                                }
1274
                                                else
1275
                                                {
4264 craig 1276
                                                        multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1277
                                                        for (int it = ml.size()-1; it > -1; it--)
1278
                                                        {
6569 fschmid 1279
                                                                if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1280
                                                                {
1281
                                                                        PutPage(setStrokeMulti(&ml[it]));
1282
                                                                        PutPage("0 0 m\n");
1283
                                                                        PutPage(FToStr(ite->width())+" 0 l\n");
1284
                                                                        PutPage("S\n");
1285
                                                                }
3133 fschmid 1286
                                                        }
1287
                                                }
4061 craig 1288
                                                if (ite->startArrowIndex() != 0)
3133 fschmid 1289
                                                {
1290
                                                        QWMatrix arrowTrans;
4264 craig 1291
                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->startArrowIndex()-1)).points.copy();
3133 fschmid 1292
                                                        arrowTrans.translate(0, 0);
4580 cbradney 1293
                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1294
                                                        arrowTrans.scale(-1,1);
1295
                                                        arrow.map(arrowTrans);
4264 craig 1296
                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1297
                                                        {
1298
                                                                StartObj(ObjCounter);
4229 craig 1299
                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1300
                                                                Transpar[ShName] = ObjCounter;
1301
                                                                ResCount++;
1302
                                                                ObjCounter++;
1303
                                                                PutDoc("<< /Type /ExtGState\n");
1304
                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1305
                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1306
                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1307
                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1308
                                                                PutPage("/"+ShName+" gs\n");
1309
                                                        }
4016 fschmid 1310
                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1311
                                                        PutPage(SetClipPathArray(&arrow));
1312
                                                        PutPage("h\nf*\n");
1313
                                                }
4061 craig 1314
                                                if (ite->endArrowIndex() != 0)
3133 fschmid 1315
                                                {
1316
                                                        QWMatrix arrowTrans;
4264 craig 1317
                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->endArrowIndex()-1)).points.copy();
3934 cbradney 1318
                                                        arrowTrans.translate(ite->width(), 0);
4580 cbradney 1319
                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1320
                                                        arrow.map(arrowTrans);
4264 craig 1321
                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1322
                                                        {
1323
                                                                StartObj(ObjCounter);
4229 craig 1324
                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1325
                                                                Transpar[ShName] = ObjCounter;
1326
                                                                ResCount++;
1327
                                                                ObjCounter++;
1328
                                                                PutDoc("<< /Type /ExtGState\n");
1329
                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1330
                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1331
                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1332
                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1333
                                                                PutPage("/"+ShName+" gs\n");
1334
                                                        }
4016 fschmid 1335
                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1336
                                                        PutPage(SetClipPathArray(&arrow));
1337
                                                        PutPage("h\nf*\n");
1338
                                                }
1339
                                                break;
3232 cbradney 1340
                                        case PageItem::ItemType1:
1341
                                        case PageItem::ItemType3:
3133 fschmid 1342
                                        case PageItem::Polygon:
1343
                                                if (ite->GrType != 0)
1344
                                                        PutPage(PDF_Gradient(ite));
1345
                                                else
1346
                                                {
4546 subik 1347
                                                        if (ite->fillColor() != CommonStrings::None)
3133 fschmid 1348
                                                        {
1349
                                                                PutPage(SetClipPath(ite));
1350
                                                                PutPage("h\nf*\n");
1351
                                                        }
1352
                                                }
4546 subik 1353
                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3133 fschmid 1354
                                                {
4580 cbradney 1355
                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1356
                                                        {
1357
                                                                PutPage(SetClipPath(ite));
1358
                                                                PutPage("h\nS\n");
1359
                                                        }
1360
                                                        else
1361
                                                        {
4264 craig 1362
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1363
                                                                for (int it = ml.size()-1; it > -1; it--)
1364
                                                                {
6569 fschmid 1365
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1366
                                                                        {
1367
                                                                                PutPage(setStrokeMulti(&ml[it]));
1368
                                                                                PutPage(SetClipPath(ite));
1369
                                                                                PutPage("h\nS\n");
1370
                                                                        }
3133 fschmid 1371
                                                                }
1372
                                                        }
1373
                                                }
1374
                                                break;
1375
                                        case PageItem::PolyLine:
4658 fschmid 1376
                                                if (ite->PoLine.size() > 4) // && ((ite->PoLine.point(0) != ite->PoLine.point(1)) || (ite->PoLine.point(2) != ite->PoLine.point(3))))
3133 fschmid 1377
                                                {
1378
                                                        if (ite->GrType != 0)
1379
                                                                PutPage(PDF_Gradient(ite));
1380
                                                        else
1381
                                                        {
4546 subik 1382
                                                                if (ite->fillColor() != CommonStrings::None)
3133 fschmid 1383
                                                                {
1384
                                                                        PutPage(SetClipPath(ite));
1385
                                                                        PutPage("h\nf*\n");
1386
                                                                }
1387
                                                        }
1388
                                                }
4546 subik 1389
                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3133 fschmid 1390
                                                {
4580 cbradney 1391
                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1392
                                                        {
1393
                                                                PutPage(SetClipPath(ite, false));
1394
                                                                PutPage("S\n");
1395
                                                        }
1396
                                                        else
1397
                                                        {
4264 craig 1398
                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
3133 fschmid 1399
                                                                for (int it = ml.size()-1; it > -1; it--)
1400
                                                                {
6569 fschmid 1401
                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
1402
                                                                        {
1403
                                                                                PutPage(setStrokeMulti(&ml[it]));
1404
                                                                                PutPage(SetClipPath(ite, false));
1405
                                                                                PutPage("S\n");
1406
                                                                        }
3133 fschmid 1407
                                                                }
1408
                                                        }
1409
                                                }
4061 craig 1410
                                                if (ite->startArrowIndex() != 0)
3133 fschmid 1411
                                                {
1412
                                                        FPoint Start = ite->PoLine.point(0);
1413
                                                        for (uint xx = 1; xx < ite->PoLine.size(); xx += 2)
1414
                                                        {
1415
                                                                FPoint Vector = ite->PoLine.point(xx);
1416
                                                                if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
1417
                                                                {
1418
                                                                        double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
1419
                                                                        QWMatrix arrowTrans;
4264 craig 1420
                                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->startArrowIndex()-1)).points.copy();
3133 fschmid 1421
                                                                        arrowTrans.translate(Start.x(), Start.y());
1422
                                                                        arrowTrans.rotate(r);
4580 cbradney 1423
                                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1424
                                                                        arrow.map(arrowTrans);
4264 craig 1425
                                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1426
                                                                        {
1427
                                                                                StartObj(ObjCounter);
4229 craig 1428
                                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1429
                                                                                Transpar[ShName] = ObjCounter;
1430
                                                                                ResCount++;
1431
                                                                                ObjCounter++;
1432
                                                                                PutDoc("<< /Type /ExtGState\n");
1433
                                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1434
                                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1435
                                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1436
                                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1437
                                                                                PutPage("/"+ShName+" gs\n");
1438
                                                                        }
4016 fschmid 1439
                                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1440
                                                                        PutPage(SetClipPathArray(&arrow));
1441
                                                                        PutPage("h\nf*\n");
1442
                                                                        break;
1443
                                                                }
1444
                                                        }
1445
                                                }
4061 craig 1446
                                                if (ite->endArrowIndex() != 0)
3133 fschmid 1447
                                                {
1448
                                                        FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
1449
                                                        for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
1450
                                                        {
1451
                                                                FPoint Vector = ite->PoLine.point(xx);
1452
                                                                if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
1453
                                                                {
1454
                                                                        double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
1455
                                                                        QWMatrix arrowTrans;
4264 craig 1456
                                                                        FPointArray arrow = (*doc.arrowStyles.at(ite->endArrowIndex()-1)).points.copy();
3133 fschmid 1457
                                                                        arrowTrans.translate(End.x(), End.y());
1458
                                                                        arrowTrans.rotate(r);
4580 cbradney 1459
                                                                        arrowTrans.scale(ite->lineWidth(), ite->lineWidth());
3133 fschmid 1460
                                                                        arrow.map(arrowTrans);
4264 craig 1461
                                                                        if ((ite->lineTransparency() != 0) && (Options.Version >= 14))
3133 fschmid 1462
                                                                        {
1463
                                                                                StartObj(ObjCounter);
4229 craig 1464
                                                                                QString ShName = ResNam+QString::number(ResCount);
3133 fschmid 1465
                                                                                Transpar[ShName] = ObjCounter;
1466
                                                                                ResCount++;
1467
                                                                                ObjCounter++;
1468
                                                                                PutDoc("<< /Type /ExtGState\n");
1469
                                                                                PutDoc("/CA "+FToStr(1.0 - ite->lineTransparency())+"\n");
1470
                                                                                PutDoc("/ca "+FToStr(1.0 - ite->lineTransparency())+"\n");
1471
                                                                                PutDoc("/SMask /None\n/AIS false\n/OPM 1\n");
1472
                                                                                PutDoc("/BM /Normal\n>>\nendobj\n");
1473
                                                                                PutPage("/"+ShName+" gs\n");
1474
                                                                        }
4016 fschmid 1475
                                                                        PutPage(putColor(ite->lineColor(), ite->lineShade(), true));
3133 fschmid 1476
                                                                        PutPage(SetClipPathArray(&arrow));
1477
                                                                        PutPage("h\nf*\n");
1478
                                                                        break;
1479
                                                                }
1480
                                                        }
1481
                                                }
1482
                                                break;
1483
                                        case PageItem::PathText:
1484
                                                if (ite->PoShow)
1485
                                                {
1486
                                                        if (ite->PoLine.size() > 3)
1487
                                                        {
1488
                                                                PutPage("q\n");
4546 subik 1489
                                                                if ((ite->lineColor() != CommonStrings::None) || (!ite->NamedLStyle.isEmpty()))
3133 fschmid 1490
                                                                {
4580 cbradney 1491
                                                                        if ((ite->NamedLStyle.isEmpty()) && (ite->lineWidth() != 0.0))
3133 fschmid 1492
                                                                        {
1493
                                                                                PutPage(SetClipPath(ite, false));
1494
                                                                                PutPage("S\n");
1495
                                                                        }
1496
                                                                        else
1497
                                                                        {
4264 craig 1498
                                                                                multiLine ml = doc.MLineStyles[ite->NamedLStyle];
6569 fschmid 1499
                                                                                for (int it = ml.size()-1; it > -1; it--)
1500
                                                                                {
1501
                                                                                        if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
3133 fschmid 1502
                                                                                        {
6569 fschmid 1503
                                                                                                PutPage(setStrokeMulti(&ml[it]));
1504
                                                                                                PutPage(SetClipPath(ite, false));
1505
                                                                                                PutPage("S\n");
3133 fschmid 1506
                                                                                        }
6569 fschmid 1507
                                                                                }
3133 fschmid 1508
                                                                        }
1509
                                                                }
1510
                                                                PutPage("Q\n");
1511
                                                        }
1512
                                                }
3200 cbradney 1513
                                                PutPage(setTextSt(ite, pag->pageNr(), pag));
3133 fschmid 1514
                                                break;
1515
                                        }
1516
                                PutPage("Q\n");
1517
                                StartObj(ObjCounter);
1518
                                ObjCounter++;
1519
                                PutDoc("<<\n/Type /XObject\n/Subtype /Form\n/FormType 1\n");
3200 cbradney 1520
                                PutDoc("/BBox [ 0 0 "+FToStr(ActPageP->width())+" "+FToStr(ActPageP->height())+" ]\n");
3133 fschmid 1521
                                PutDoc("/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI]\n");
1522
                                if (Seite.ImgObjects.count() != 0)
1523
                                {
1524
                                        PutDoc("/XObject <<\n");
1525
                                        QMap<QString,int>::Iterator it;
1526
                                        for (it = Seite.ImgObjects.begin(); it != Seite.ImgObjects.end(); ++it)
4229 craig 1527
                                                PutDoc("/"+it.key()+" "+QString::number(it.data())+" 0 R\n");
3133 fschmid 1528
                                        PutDoc(">>\n");
1529
                                }
1530
                                if (Seite.FObjects.count() != 0)
1531
                                {
1532
                                        PutDoc("/Font << \n");
1533
                                        QMap<QString,int>::Iterator it2;
1534
                                        for (it2 = Seite.FObjects.begin(); it2 != Seite.FObjects.end(); ++it2)
4229 craig 1535
                                                PutDoc("/"+it2.key()+" "+QString::number(it2.data())+" 0 R\n");
3133 fschmid 1536
                                        PutDoc(">>\n");
1537
                                }
1538
                                if (Shadings.count() != 0)
1539
                                {
1540
                                        PutDoc("/Shading << \n");
1541
                                        QMap<QString,int>::Iterator it3;
1542
                                        for (it3 = Shadings.begin(); it3 != Shadings.end(); ++it3)
4229 craig 1543
                                                PutDoc("/"+it3.key()+" "+QString::number(it3.data())+" 0 R\n");
3133 fschmid 1544
                                        PutDoc(">>\n");
1545
                                }
1546
                                if (Transpar.count() != 0)
1547
                                {
1548
                                        PutDoc("/ExtGState << \n");
1549
                                        QMap<QString,int>::Iterator it3t;
1550
                                        for (it3t = Transpar.begin(); it3t != Transpar.end(); ++it3t)
4229 craig 1551
                                                PutDoc("/"+it3t.key()+" "+QString::number(it3t.data())+" 0 R\n");
3133 fschmid 1552
                                        PutDoc(">>\n");
1553
                                }
1554
                                if ((ICCProfiles.count() != 0) || (spotMap.count() != 0))
1555
                                {
1556
                                        PutDoc("/ColorSpace << \n");
1557
                                        QMap<QString,ICCD>::Iterator it3c;
1558
                                        if (ICCProfiles.count() != 0)
1559
                                        {
1560
                                                for (it3c = ICCProfiles.begin(); it3c != ICCProfiles.end(); ++it3c)
4229 craig 1561
                                                        PutDoc("/"+it3c.data().ResName+" "+QString::number(it3c.data().ResNum)+" 0 R\n");
3133 fschmid 1562
                                        }
1563
                                        QMap<QString,SpotC>::Iterator it3sc;
1564
                                        if (spotMap.count() != 0)
1565
                                        {
1566
                                        for (it3sc = spotMap.begin(); it3sc != spotMap.end(); ++it3sc)
4229 craig 1567
                                                PutDoc("/"+it3sc.data().ResName+" "+QString::number(it3sc.data().ResNum)+" 0 R\n");
3133 fschmid 1568
                                        }
1569
                                        PutDoc(">>\n");
1570
                                }
1571
                                PutDoc(">>\n");
4264 craig 1572
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 1573
                                        Inhalt = CompressStr(&Inhalt);
4229 craig 1574
                                PutDoc("/Length "+QString::number(Inhalt.length()+1));
4264 craig 1575
                                if ((Options.Compress) && (CompAvail))
3133 fschmid 1576
                                        PutDoc("\n/Filter /FlateDecode");
4229 craig 1577
                                PutDoc(" >>\nstream\n"+EncStream(Inhalt, ObjCounter-1)+"\nendstream\nendobj\n");
1578
                                QString name = pag->PageNam.simplifyWhiteSpace().replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" ) + QString::number(ite->ItemNr);
3133 fschmid 1579
                                Seite.XObjects[name] = ObjCounter-1;
1580
                                }
4264 craig 1581
                                if ((Options.Version == 15) && (Options.useLayers))
3133 fschmid 1582
                                        PutPage("EMC\n");
1583
                        }
1584
                Lnr++;
1585
        }
1586
}
1587
 
4241 craig 1588
void PDFlib::PDF_Begin_Page(const Page* pag, QPixmap pm)
3133 fschmid 1589
{
1590
        QString tmp;
1591
        ActPageP = pag;
1592
        Inhalt = "";
1593
        Seite.AObjects.clear();
4264 craig 1594
        if (Options.Thumbnails)
3133 fschmid 1595
        {
1596
                ScImage img = pm.convertToImage();
1597
                QString im = img.ImageToTxt();
4264 craig 1598
                if ((Options.Compress) && (CompAvail))
3133 fschmid 1599
                        im = CompressStr(&im);
1600
                StartObj(ObjCounter);
4229 craig 1601
                PutDoc("<<\n/Width "+QString::number(img.width())+"\n");
1602
                PutDoc("/Height "+QString::number(img.height())+"\n");
3133 fschmid 1603
                PutDoc("/ColorSpace /DeviceRGB\n/BitsPerComponent 8\n");
4229 craig 1604
                PutDoc("/Length "+QString::number(im.length()+1)+"\n");
4264 craig 1605
                if ((Options.Compress) && (CompAvail))
3133 fschmid 1606
                        PutDoc("/Filter /FlateDecode\n");
4229 craig 1607
                PutDoc(">>\nstream\n"+EncStream(im, ObjCounter)+"\nendstream\nendobj\n");
3133 fschmid 1608
                Seite.Thumb = ObjCounter;
1609
                ObjCounter++;
1610
        }
1611
}
1612
 
1613
void PDFlib::PDF_End_Page()
1614
{
3200 cbradney 1615
        uint PgNr =  ActPageP->pageNr();
3133 fschmid 1616
        Seite.ObjNum = ObjCounter;
4084 cbradney 1617
        WritePDFStream(Inhalt);
5605 cbradney 1618
        int Gobj;
1619
        if ((Options.Version >= 14) && (Transpar.count() != 0))
1620
        {
1621
                StartObj(ObjCounter);
1622
                Gobj = ObjCounter;
1623
                ObjCounter++;
1624
                PutDoc("<< /S /Transparency\n");
1625
                if (Options.UseRGB)
1626
                        PutDoc("/CS /DeviceRGB\n");
1627
                else
1628
                {
1629
                        if (Options.isGrayscale)
1630
                                PutDoc("/CS /DeviceGray\n");
1631
                        else
1632
#ifdef HAVE_CMS
1633
                        {
1634
                                if ((CMSuse) && (Options.UseProfiles))
1635
                                        PutDoc("/CS "+ICCProfiles[Options.SolidProf].ICCArray+"\n");
1636
                                else
1637
#endif
1638
                                        PutDoc("/CS /DeviceCMYK\n");
1639
#ifdef HAVE_CMS
1640
                        }
1641
#endif
1642
                }
1643
                PutDoc(">>\nendobj\n");
1644
        }
3133 fschmid 1645
        StartObj(ObjCounter);
1646
        PutDoc("<<\n/Type /Page\n/Parent 4 0 R\n");
3200 cbradney 1647
        PutDoc("/MediaBox [0 0 "+FToStr(ActPageP->width())+" "+FToStr(ActPageP->height())+"]\n");
6894 fschmid 1648
        if (Options.Version == 12)
1649
                PutDoc("/TrimBox ["+FToStr(Options.BleedLeft)+" "+FToStr(Options.BleedBottom)+" "+FToStr(ActPageP->width()-Options.BleedRight)+" "+FToStr(ActPageP->height()-Options.BleedTop)+"]\n");
1650
        else
1651
                PutDoc("/TrimBox [0 0 "+FToStr(ActPageP->width())+" "+FToStr(ActPageP->height())+"]\n");
4264 craig 1652
        PutDoc("/Rotate "+QString::number(Options.RotateDeg)+"\n");
4229 craig 1653
        PutDoc("/Contents "+QString::number(Seite.ObjNum)+" 0 R\n");
5605 cbradney 1654
        if ((Options.Version >= 14) && (Transpar.count() != 0))
1655
                PutDoc("/Group "+QString::number(Gobj)+" 0 R\n");
4264 craig 1656
        if (Options.Thumbnails)
4229 craig 1657
                PutDoc("/Thumb "+QString::number(Seite.Thumb)+" 0 R\n");
3133 fschmid 1658
        if (Seite.AObjects.count() != 0)
1659
        {
1660
                PutDoc("/Annots [ ");
1661
                for (uint b = 0; b < Seite.AObjects.count(); ++b)
4229 craig 1662
                        PutDoc(QString::number(Seite.AObjects[b])+" 0 R ");
3133 fschmid 1663
                PutDoc("]\n");
1664
        }
4264 craig 1665
        if (Options.PresentMode)
3133 fschmid 1666
        {
4932 fschmid 1667
                if (Options.PresentVals[PgNr].pageViewDuration > 0)
1668
                        PutDoc("/Dur "+QString::number(Options.PresentVals[PgNr].pageViewDuration)+"\n");
4264 craig 1669
                if (Options.PresentVals[PgNr].effectType != 0)
3133 fschmid 1670
                {
1671
                        PutDoc("/Trans << /Type /Trans\n");
4264 craig 1672
                        PutDoc("/D "+QString::number(Options.PresentVals[PgNr].pageEffectDuration)+"\n");
1673
                        switch (Options.PresentVals[PgNr].effectType)
3133 fschmid 1674
                        {
1675
                                case 1:
1676
                                        PutDoc("/S /Blinds\n");
4264 craig 1677
                                        PutDoc(Options.PresentVals[PgNr].Dm == 0 ? "/Dm /H\n" : "/Dm /V\n");
3133 fschmid 1678
                                        break;
1679
                                case 2:
1680
                                        PutDoc("/S /Box\n");
4264 craig 1681
                                        PutDoc(Options.PresentVals[PgNr].M == 0 ? "/M /I\n" : "/M /O\n");
3133 fschmid 1682
                                        break;
1683
                                case 3:
1684
                                        PutDoc("/S /Dissolve\n");
1685
                                        break;
1686
                                case 4:
1687
                                        PutDoc("/S /Glitter\n");
1688
                                        PutDoc("/Di ");
4264 craig 1689
                                        switch (Options.PresentVals[PgNr].Di)
3133 fschmid 1690
                                        {
1691
                                                case 0:
1692
                                                        PutDoc("0");
1693
                                                        break;
1694
                                                case 1:
1695
                                                        PutDoc("270");
1696
                                                        break;
1697
                                                case 4:
1698
                                                        PutDoc("315");
1699
                                                        break;
1700
                                                default:
1701
                                                        PutDoc("0");
1702
                                                        break;
1703
                                        }
1704
                                        PutDoc("\n");
1705
                                        break;
1706
                                case 5:
1707
                                        PutDoc("/S /Split\n");
4264 craig 1708
                                        PutDoc(Options.PresentVals[PgNr].Dm == 0 ? "/Dm /H\n" : "/Dm /V\n");
1709
                                        PutDoc(Options.PresentVals[PgNr].M == 0 ? "/M /I\n" : "/M /O\n");
3133 fschmid 1710
                                        break;
1711
                                case 6:
1712
                                        PutDoc("/S /Wipe\n");
1713
                                        PutDoc("/Di ");
4264 craig 1714
                                        switch (Options.PresentVals[PgNr].Di)
3133 fschmid 1715
                                        {
1716
                                                case 0:
1717
                                                        PutDoc("0");
1718
                                                        break;
1719
                                                case 1:
1720
                                                        PutDoc("270");
1721
                                                        break;
1722
                                                case 2:
1723
                                                        PutDoc("90");
1724
                                                        break;
1725
                                                case 3:
1726
                                                        PutDoc("180");
1727
                                                        break;
1728
                                                default:
1729
                                                        PutDoc("0");
1730