Subversion Repositories Scribus

Rev

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