Subversion Repositories Scribus

Rev

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