Subversion Repositories Scribus

Rev

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

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