Subversion Repositories Scribus

Rev

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