Subversion Repositories Scribus

Rev

Rev 9620 | Details | Compare with Previous | Last modification | View Log | RSS feed

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