Subversion Repositories Scribus

Rev

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

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