Subversion Repositories Scribus

Rev

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

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