Subversion Repositories Scribus

Rev

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