Subversion Repositories Scribus

Rev

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

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