Subversion Repositories Scribus

Rev

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