Subversion Repositories Scribus

Rev

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