Subversion Repositories Scribus

Rev

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