Subversion Repositories Scribus

Rev

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