Subversion Repositories Scribus

Rev

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