Subversion Repositories Scribus

Rev

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