Subversion Repositories Scribus

Rev

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