Subversion Repositories Scribus

Rev

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

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