Subversion Repositories Scribus

Rev

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