Subversion Repositories Scribus

Rev

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

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