Subversion Repositories Scribus

Rev

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

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