Subversion Repositories Scribus

Rev

Rev 1913 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
8 paul 1
/***************************************************************************
2
                          util.cpp  -  description
3
                             -------------------
4
    begin                : Fri Sep 14 2001
5
    copyright            : (C) 2001 by Franz Schmid
6
    email                : Franz.Schmid@altmuehlnet.de
7
 ***************************************************************************/
8
 
9
/***************************************************************************
10
 *                                                                         *
11
 *   This program is free software; you can redistribute it and/or modify  *
12
 *   it under the terms of the GNU General Public License as published by  *
13
 *   the Free Software Foundation; either version 2 of the License, or     *
14
 *   (at your option) any later version.                                   *
15
 *                                                                         *
16
 ***************************************************************************/
9 Franz 17
 
8 paul 18
#include <qstring.h>
19
#include <qpixmap.h>
20
#include <qbitmap.h>
21
#include <qpainter.h>
22
#include <qfile.h>
23
#include <qfileinfo.h>
24
#include <qtextstream.h>
25
#include <qstringlist.h>
26
#include <qmap.h>
27
#include <qdom.h>
28
#include <qimage.h>
19 Franz 29
#include <qdir.h>
8 paul 30
#include <qpointarray.h>
90 Franz 31
#include <qmessagebox.h>
8 paul 32
#include <cstdlib>
33
#include <cmath>
213 Franz 34
#include <unistd.h>
8 paul 35
#include "md5.h"
201 Franz 36
#include <setjmp.h>
204 Franz 37
#include "qprocess.h"
128 Franz 38
 
612 cbradney 39
#ifdef _MSC_VER
40
 #if (_MSC_VER >= 1200)
41
  #include "win-config.h"
42
 #endif
128 Franz 43
#else
44
 #include "config.h"
45
#endif
46
 
201 Franz 47
extern "C" {
48
#define XMD_H           // shut JPEGlib up
49
#if defined(Q_OS_UNIXWARE)
50
#  define HAVE_BOOLEAN  // libjpeg under Unixware seems to need this
51
#endif
52
#include <jpeglib.h>
53
#include <jerror.h>
54
#undef HAVE_STDLIB_H
55
#ifdef const
56
#  undef const          // remove crazy C hackery in jconfig.h
57
#endif
58
}
59
 
214 Franz 60
#include "scribus.h"
8 paul 61
#include "libpdf/pdflib.h"
68 Franz 62
#include <ft2build.h>
63
#include FT_FREETYPE_H
64
#include FT_OUTLINE_H
65
#include FT_GLYPH_H
8 paul 66
#ifdef HAVE_LIBZ
67
        #include <zlib.h>
68
#endif
69
#ifdef HAVE_TIFF
70
        #include <tiffio.h>
71
#endif
72
#ifdef HAVE_CMS
44 Franz 73
        #include CMS_INC
8 paul 74
extern cmsHPROFILE CMSoutputProf;
75
extern cmsHPROFILE CMSprinterProf;
76
extern cmsHTRANSFORM stdTrans;
77
extern cmsHTRANSFORM stdProof;
78
extern cmsHTRANSFORM stdTransImg;
79
extern cmsHTRANSFORM stdProofImg;
80
extern bool SoftProofing;
81
extern bool Gamut;
82
extern bool CMSuse;
83
extern int IntentMonitor;
84
extern int IntentPrinter;
85
#endif
86
extern ProfilesL InputProfiles;
214 Franz 87
extern ScribusApp* ScApp;
8 paul 88
 
503 cbradney 89
using namespace std;
90
 
203 Franz 91
void ReOrderText(ScribusDoc *doc, ScribusView *view);
125 Franz 92
void WordAndPara(PageItem* b, int *w, int *p, int *c, int *wN, int *pN, int *cN);
124 Franz 93
void CopyPageItem(struct CLBuf *Buffer, PageItem *b);
90 Franz 94
bool overwrite(QWidget *parent, QString filename);
1084 fschmid 95
int setBestEncoding(FT_Face face);
220 Franz 96
FPointArray traceChar(FT_Face face, uint chr, int chs, double *x, double *y, bool &err);
95 Franz 97
FPoint GetMaxClipF(FPointArray Clip);
1084 fschmid 98
QPixmap FontSample(QString da, int s, QString ts, QColor back, bool force = false);
418 Franz 99
QPixmap fontSamples(QString da, int s, QString ts, QColor back);
19 Franz 100
QString Path2Relative(QString Path);
20 Franz 101
QPixmap LoadPDF(QString fn, int Seite, int Size, int *w, int *h);
8 paul 102
bool GlyNames(QMap<uint, QString> *GList, QString Dat);
103
bool GlyIndex(QMap<uint, PDFlib::GlNamInd> *GListInd, QString Dat);
104
QByteArray ComputeMD5Sum(QByteArray *in);
105
char *toHex( uchar u );
106
QString String2Hex(QString *in, bool lang = true);
107
QString CompressStr(QString *in);
1968 fschmid 108
QImage scaleImage(const QImage& src, int width, int height);
8 paul 109
QString ImageToTxt(QImage *im);
110
QString ImageToCMYK(QImage *im);
111
QString ImageToCMYK_PS(QImage *im, int pl, bool pre);
1886 fschmid 112
bool isProgressive(QString fn);
202 Franz 113
void Convert2JPG(QString fn, QImage *image, int Quality, bool isCMYK);
8 paul 114
QString MaskToTxt(QImage *im, bool PDF = true);
203 Franz 115
QString MaskToTxt14(QImage *im);
8 paul 116
void Level2Layer(ScribusDoc *doc, struct Layer *ll, int Level);
117
void BezierPoints(QPointArray *ar, QPoint n1, QPoint n2, QPoint n3, QPoint n4);
80 Franz 118
double xy2Deg(double x, double y);
8 paul 119
QPointArray FlattenPath(FPointArray ina, QValueList<uint> &Segs);
80 Franz 120
QPointArray RegularPolygon(double w, double h, uint c, bool star, double factor, double rota);
121
FPointArray RegularPolygonF(double w, double h, uint c, bool star, double factor, double rota);
8 paul 122
QPixmap loadIcon(QString nam);
1108 fschmid 123
uint getDouble(QString in, bool raw);
8 paul 124
bool loadText(QString nam, QString *Buffer);
80 Franz 125
double Cwidth(ScribusDoc *doc, QString name, QString ch, int Siz, QString ch2 = " ");
220 Franz 126
double RealCWidth(ScribusDoc *doc, QString name, QString ch, int Siz);
80 Franz 127
double QStodouble(QString in);
8 paul 128
int QStoInt(QString in);
129
QString GetAttr(QDomElement *el, QString at, QString def="0");
201 Franz 130
QImage LoadPict(QString fn, bool *gray = 0);
8 paul 131
#ifdef HAVE_CMS
132
QImage ProofPict(QImage *Im, QString Prof, int Rend, cmsHPROFILE emPr=0);
133
QImage LoadPictCol(QString fn, QString Prof, bool UseEmbedded, bool *realCMYK);
134
#else
135
QImage ProofPict(QImage *Im, QString Prof, int Rend);
136
#endif
137
QImage ProofImage(QImage *Im);
204 Franz 138
int callGS(const QStringList & args_in);
139
int copyFile(QString source, QString target);
140
int moveFile(QString source, QString target);
8 paul 141
 
142
#ifdef HAVE_CMS
143
QImage ProofPict(QImage *Im, QString Prof, int Rend, cmsHPROFILE emPr)
144
#else
145
QImage ProofPict(QImage *Im, QString Prof, int Rend)
146
#endif
147
{
148
        bool emp = false;
149
        if (Prof == "")
150
                return Im->copy();
151
#ifdef HAVE_CMS
152
        QImage out = Im->copy();
153
        if ((CMSuse) && (SoftProofing))
167 Franz 154
        {
8 paul 155
                cmsHTRANSFORM xform;
156
                cmsHPROFILE inputProf;
167 Franz 157
                if (emPr != 0)
158
                        inputProf = emPr;
159
                else
160
                {
161
                        inputProf = cmsOpenProfileFromFile(InputProfiles[Prof], "r");
8 paul 162
                        emp = true;
167 Franz 163
                }
8 paul 164
                int dcmsFlags = 0;
167 Franz 165
                dcmsFlags |= Gamut ? cmsFLAGS_GAMUTCHECK : cmsFLAGS_SOFTPROOFING;
8 paul 166
                xform = cmsCreateProofingTransform(inputProf, TYPE_RGBA_8,
167 Franz 167
                                                                                                 CMSoutputProf, TYPE_RGBA_8,
168
                                                                                                 CMSprinterProf,
169
                                                                                                 IntentPrinter,
170
                                                                                                 Rend, dcmsFlags);
8 paul 171
                for (int i=0; i < out.height(); ++i)
167 Franz 172
                {
8 paul 173
                        LPBYTE ptr = out.scanLine(i);
174
                        cmsDoTransform(xform, ptr, ptr, out.width());
167 Franz 175
                }
8 paul 176
                cmsDeleteTransform(xform);
177
                if (emp)
178
                        cmsCloseProfile(inputProf);
167 Franz 179
        }
8 paul 180
        else
167 Franz 181
        {
182
                if (CMSuse)
8 paul 183
                {
184
                        cmsHTRANSFORM xform;
185
                        cmsHPROFILE inputProf;
167 Franz 186
                        if (emPr != 0)
187
                                inputProf = emPr;
188
                        else
189
                        {
190
                                inputProf = cmsOpenProfileFromFile(InputProfiles[Prof], "r");
8 paul 191
                                emp = true;
167 Franz 192
                        }
8 paul 193
                        xform = cmsCreateTransform(inputProf, TYPE_RGBA_8,
167 Franz 194
                                                                                         CMSoutputProf, TYPE_RGBA_8,
195
                                                                                         Rend,
196
                                                                                         0);
8 paul 197
                        for (int i=0; i < out.height(); ++i)
167 Franz 198
                        {
8 paul 199
                                LPBYTE ptr = out.scanLine(i);
200
                                cmsDoTransform(xform, ptr, ptr, out.width());
167 Franz 201
                        }
8 paul 202
                        cmsDeleteTransform(xform);
203
                        if (emp)
204
                                cmsCloseProfile(inputProf);
205
                }
167 Franz 206
        }
8 paul 207
        return out;
208
#else
209
        return Im->copy();
210
#endif
211
}
212
 
213
QImage ProofImage(QImage *Im)
214
{
215
#ifdef HAVE_CMS
216
        QImage out = Im->copy();
217
        if ((CMSuse) && (SoftProofing))
167 Franz 218
        {
219
                for (int i=0; i < out.height(); ++i)
8 paul 220
                {
221
                        LPBYTE ptr = out.scanLine(i);
222
                        cmsDoTransform(stdProofImg, ptr, ptr, out.width());
223
                }
167 Franz 224
        }
8 paul 225
        else
167 Franz 226
        {
227
                if (CMSuse)
8 paul 228
                {
167 Franz 229
                        for (int i=0; i < out.height(); ++i)
8 paul 230
                        {
231
                                LPBYTE ptr = out.scanLine(i);
232
                                cmsDoTransform(stdTransImg, ptr, ptr, out.width());
233
                        }
234
                }
167 Franz 235
        }
8 paul 236
        return out;
237
#else
238
        return Im->copy();
239
#endif
240
}
241
 
204 Franz 242
/******************************************************************
243
 * Function callGS()
244
 *   build the complete list of arguments for the call of our
245
 *   System() function.
246
 *
247
 *   The gs commands are all similar and consist of a few constant
248
 *   arguments, the variablke arguments and the end arguments which
249
 *   are also invariant.
250
 ******************************************************************/
251
 
252
int callGS(const QStringList & args_in)
253
{
1913 fschmid 254
        QString cmd1 = ScApp->Prefs.gs_exe;
255
        cmd1 += " -q -dNOPAUSE";
214 Franz 256
        if (ScApp->HavePngAlpha != 0)
1913 fschmid 257
                cmd1 += " -sDEVICE=png16m";
214 Franz 258
        else
1913 fschmid 259
                cmd1 += " -sDEVICE=pngalpha";
220 Franz 260
        if (ScApp->Prefs.gs_antiText)
1913 fschmid 261
                cmd1 += " -dTextAlphaBits=4";
220 Franz 262
        if (ScApp->Prefs.gs_antiGraph)
1913 fschmid 263
                cmd1 += " -dGraphicsAlphaBits=4";
264
        QString extArgs = args_in.join(" ");
265
        cmd1 += " " + extArgs + " -c showpage -c quit";
266
        return system(cmd1);
204 Franz 267
}
268
 
269
int copyFile(QString source, QString target)
270
{
271
        if ((source.isNull()) || (target.isNull()))
272
                return -1;
273
        if (source == target)
274
                return -1;
275
        QFile s(source);
276
        QFile t(target);
277
        if (!s.exists())
278
                return -1;
279
        QByteArray bb(s.size());
280
        if (s.open(IO_ReadOnly))
281
        {
282
                s.readBlock(bb.data(), s.size());
283
                s.close();
284
                if (t.open(IO_WriteOnly))
285
                {
286
                        t.writeBlock(bb.data(), bb.size());
287
                        t.close();
288
                }
289
        }
290
        return 0;
291
}
292
 
293
int moveFile(QString source, QString target)
294
{
295
        if ((source.isNull()) || (target.isNull()))
296
                return -1;
297
        if (source == target)
298
                return -1;
299
        copyFile(source, target);
300
        unlink(source);
301
        return 0;
302
}
303
 
1968 fschmid 304
QImage scaleImage(const QImage& src, int width, int height)
305
{
306
        QImage dst;
307
        dst.create(width, height,32);
308
        QRgb* xelrow = 0;
309
        QRgb* tempxelrow = 0;
310
        register QRgb* xP;
311
        register QRgb* nxP;
312
        int rows, cols, rowsread, newrows, newcols;
313
        register int row, col, needtoreadrow;
314
        const uchar maxval = 255;
315
        double xscale, yscale;
316
        long sxscale, syscale;
317
        register long fracrowtofill, fracrowleft;
318
        long* as;
319
        long* rs;
320
        long* gs;
321
        long* bs;
322
        int rowswritten = 0;
323
        cols = src.width();
324
        rows = src.height();
325
        newcols = dst.width();
326
        newrows = dst.height();
327
        long SCALE;
328
        long HALFSCALE;
329
        if (cols > 4096)
330
        {
331
                SCALE = 4096;
332
                HALFSCALE = 2048;
333
        }
334
        else
335
        {
336
                int fac = 4096;
337
                while (cols * fac > 4096)
338
                {
339
                        fac /= 2;
340
                }
341
                SCALE = fac * cols;
342
                HALFSCALE = fac * cols / 2;
343
        }
344
        xscale = (double) newcols / (double) cols;
345
        yscale = (double) newrows / (double) rows;
346
        sxscale = (long)(xscale * SCALE);
347
        syscale = (long)(yscale * SCALE);
348
        if ( newrows != rows )  /* shortcut Y scaling if possible */
349
                tempxelrow = new QRgb[cols];
350
        as = new long[cols];
351
        rs = new long[cols];
352
        gs = new long[cols];
353
        bs = new long[cols];
354
        rowsread = 0;
355
        fracrowleft = syscale;
356
        needtoreadrow = 1;
357
        for ( col = 0; col < cols; ++col )
358
                rs[col] = gs[col] =  as[col] = bs[col] = HALFSCALE;
359
        fracrowtofill = SCALE;
360
        for ( row = 0; row < newrows; ++row )
361
        {
362
                if ( newrows == rows )
363
                        tempxelrow = xelrow = (QRgb*)src.scanLine(rowsread++);
364
                else
365
                {
366
                        while ( fracrowleft < fracrowtofill )
367
                        {
368
                                if ( needtoreadrow && rowsread < rows )
369
                                        xelrow = (QRgb*)src.scanLine(rowsread++);
370
                                for ( col = 0, xP = xelrow; col < cols; ++col, ++xP )
371
                                {
372
                                        as[col] += fracrowleft * qAlpha( *xP );
373
                                        rs[col] += fracrowleft * qRed( *xP );
374
                                        gs[col] += fracrowleft * qGreen( *xP );
375
                                        bs[col] += fracrowleft * qBlue( *xP );
376
                                }
377
                                fracrowtofill -= fracrowleft;
378
                                fracrowleft = syscale;
379
                                needtoreadrow = 1;
380
                        }
381
                        if ( needtoreadrow && rowsread < rows )
382
                        {
383
                                xelrow = (QRgb*)src.scanLine(rowsread++);
384
                                needtoreadrow = 0;
385
                        }
386
                        register long a=0;
387
                        for ( col = 0, xP = xelrow, nxP = tempxelrow; col < cols; ++col, ++xP, ++nxP )
388
                        {
389
                                register long r, g, b;
390
                                a = as[col] + fracrowtofill * qAlpha( *xP );
391
                                r = rs[col] + fracrowtofill * qRed( *xP );
392
                                g = gs[col] + fracrowtofill * qGreen( *xP );
393
                                b = bs[col] + fracrowtofill * qBlue( *xP );
394
                                r /= SCALE;
395
                                if ( r > maxval ) r = maxval;
396
                                g /= SCALE;
397
                                if ( g > maxval ) g = maxval;
398
                                b /= SCALE;
399
                                if ( b > maxval ) b = maxval;
400
                                a /= SCALE;
401
                                if ( a > maxval ) a = maxval;
402
                                *nxP = qRgba( (int)r, (int)g, (int)b , (int)a);
403
                                rs[col] = as[col] = gs[col] = bs[col] = HALFSCALE;
404
                        }
405
                        fracrowleft -= fracrowtofill;
406
                        if ( fracrowleft == 0 )
407
                        {
408
                                fracrowleft = syscale;
409
                                needtoreadrow = 1;
410
                        }
411
                        fracrowtofill = SCALE;
412
                }
413
                if ( newcols == cols )
414
                        memcpy(dst.scanLine(rowswritten++), tempxelrow, newcols*4);
415
                else
416
                {
417
                        register long a, r, g, b;
418
                        register long fraccoltofill, fraccolleft = 0;
419
                        register int needcol;
420
                        nxP = (QRgb*)dst.scanLine(rowswritten++);
421
                        fraccoltofill = SCALE;
422
                        a = r = g = b = HALFSCALE;
423
                        needcol = 0;
424
                        for ( col = 0, xP = tempxelrow; col < cols; ++col, ++xP )
425
                        {
426
                                fraccolleft = sxscale;
427
                                while ( fraccolleft >= fraccoltofill )
428
                                {
429
                                        if ( needcol )
430
                                        {
431
                                                ++nxP;
432
                                                a = r = g = b = HALFSCALE;
433
                                        }
434
                                        a += fraccoltofill * qAlpha( *xP );
435
                                        r += fraccoltofill * qRed( *xP );
436
                                        g += fraccoltofill * qGreen( *xP );
437
                                        b += fraccoltofill * qBlue( *xP );
438
                                        r /= SCALE;
439
                                        if ( r > maxval ) r = maxval;
440
                                        g /= SCALE;
441
                                        if ( g > maxval ) g = maxval;
442
                                        b /= SCALE;
443
                                        if ( b > maxval ) b = maxval;
444
                                        a /= SCALE;
445
                                        if ( a > maxval ) a = maxval;
446
                                        *nxP = qRgba( (int)r, (int)g, (int)b, (int)a );
447
                                        fraccolleft -= fraccoltofill;
448
                                        fraccoltofill = SCALE;
449
                                        needcol = 1;
450
                                }
451
                                if ( fraccolleft > 0 )
452
                                {
453
                                        if ( needcol )
454
                                        {
455
                                                ++nxP;
456
                                                a = r = g = b = HALFSCALE;
457
                                                needcol = 0;
458
                                        }
459
                                        a += fraccolleft * qAlpha( *xP );
460
                                        r += fraccolleft * qRed( *xP );
461
                                        g += fraccolleft * qGreen( *xP );
462
                                        b += fraccolleft * qBlue( *xP );
463
                                        fraccoltofill -= fraccolleft;
464
                                }
465
                        }
466
                        if ( fraccoltofill > 0 )
467
                        {
468
                                --xP;
469
                                a += fraccolleft * qAlpha( *xP );
470
                                r += fraccoltofill * qRed( *xP );
471
                                g += fraccoltofill * qGreen( *xP );
472
                                b += fraccoltofill * qBlue( *xP );
473
                        }
474
                        if ( ! needcol )
475
                        {
476
                                r /= SCALE;
477
                                if ( r > maxval ) r = maxval;
478
                                g /= SCALE;
479
                                if ( g > maxval ) g = maxval;
480
                                b /= SCALE;
481
                                if ( b > maxval ) b = maxval;
482
                                a /= SCALE;
483
                                if ( a > maxval ) a = maxval;
484
                                *nxP = qRgba( (int)r, (int)g, (int)b, (int)a );
485
                        }
486
                }
487
        }
488
        if ( newrows != rows && tempxelrow )// Robust, tempxelrow might be 0 1 day
489
                delete [] tempxelrow;
490
        if ( as )                               // Avoid purify complaint
491
                delete [] as;
492
        if ( rs )                               // Robust, rs might be 0 one day
493
                delete [] rs;
494
        if ( gs )                               // Robust, gs might be 0 one day
495
                delete [] gs;
496
        if ( bs )                               // Robust, bs might be 0 one day
497
                delete [] bs;
498
        return dst;
499
}
500
 
20 Franz 501
QPixmap LoadPDF(QString fn, int Seite, int Size, int *w, int *h)
19 Franz 502
{
503
        QString tmp, cmd1, cmd2;
282 Franz 504
        QString tmpFile = QDir::convertSeparators(QDir::homeDirPath()+"/.scribus/sc.png");
19 Franz 505
        QPixmap pm;
506
        int ret = -1;
507
        tmp.setNum(Seite);
204 Franz 508
        QStringList args;
509
        args.append("-r72");
510
        args.append("-sOutputFile="+tmpFile);
511
        args.append("-dFirstPage="+tmp);
512
        args.append("-dLastPage="+tmp);
1859 fschmid 513
        args.append("\""+fn+"\"");
204 Franz 514
        ret = callGS(args);
19 Franz 515
        if (ret == 0)
167 Franz 516
        {
19 Franz 517
                QImage image;
159 Franz 518
                image.load(tmpFile);
204 Franz 519
                unlink(tmpFile);
167 Franz 520
                QImage im2;
20 Franz 521
                *h = image.height();
522
                *w = image.width();
80 Franz 523
                double sx = image.width() / static_cast<double>(Size);
524
                double sy = image.height() / static_cast<double>(Size);
167 Franz 525
                double t = (sy < sx ? sx : sy);
526
                im2 = image.smoothScale(static_cast<int>(image.width() / t), static_cast<int>(image.height() / t));
19 Franz 527
                pm.convertFromImage(im2);
528
                QPainter p;
529
                p.begin(&pm);
530
                p.setBrush(Qt::NoBrush);
531
                p.setPen(Qt::black);
532
                p.drawRect(0, 0, pm.width(), pm.height());
533
                p.end();
534
                im2.detach();
167 Franz 535
        }
19 Franz 536
        return pm;
537
}
538
 
201 Franz 539
QImage LoadPict(QString fn, bool *gray)
8 paul 540
{
84 Franz 541
        QString tmp, dummy, cmd1, cmd2, BBox, tmp2;
8 paul 542
        QChar tc;
543
        QImage Bild;
80 Franz 544
        double x, y, b, h;
8 paul 545
        bool found = false;
546
        int ret = -1;
282 Franz 547
        QString tmpFile = QDir::convertSeparators(QDir::homeDirPath()+"/.scribus/sc.png");
8 paul 548
        QFileInfo fi = QFileInfo(fn);
549
        QString ext = fi.extension(false).lower();
16 Franz 550
        if (ext == "pdf")
167 Franz 551
        {
204 Franz 552
                QStringList args;
553
                args.append("-r72");
554
                args.append("-sOutputFile="+tmpFile);
555
                args.append("-dFirstPage=1");
556
                args.append("-dLastPage=1");
1859 fschmid 557
                args.append("\""+fn+"\"");
204 Franz 558
                ret = callGS(args);
16 Franz 559
                if (ret == 0)
167 Franz 560
                {
16 Franz 561
                        QImage image;
159 Franz 562
                        image.load(tmpFile);
167 Franz 563
                        Bild = image.convertDepth(32);
204 Franz 564
                        unlink(tmpFile);
16 Franz 565
                }
167 Franz 566
        }
8 paul 567
        if ((ext == "eps") || (ext == "ps"))
167 Franz 568
        {
8 paul 569
                QFile f(fn);
570
                if (f.open(IO_ReadOnly))
167 Franz 571
                {
8 paul 572
                        QTextStream ts(&f);
573
                        while (!ts.atEnd())
167 Franz 574
                        {
8 paul 575
                                tc = ' ';
576
                                tmp = "";
577
                                while ((tc != '\n') && (tc != '\r'))
167 Franz 578
                                {
8 paul 579
                                        ts >> tc;
580
                                        if ((tc != '\n') && (tc != '\r'))
581
                                                tmp += tc;
167 Franz 582
                                }
286 Franz 583
                                if (tmp.startsWith("%%BoundingBox:"))
167 Franz 584
                                {
8 paul 585
                                        found = true;
286 Franz 586
                                        BBox = tmp.remove("%%BoundingBox:");
167 Franz 587
                                }
286 Franz 588
                                if (!found)
589
                                {
590
                                        if (tmp.startsWith("%%BoundingBox"))
591
                                        {
592
                                                found = true;
593
                                                BBox = tmp.remove("%%BoundingBox");
594
                                        }
595
                                }
8 paul 596
                                if (tmp.startsWith("%%EndComments"))
597
                                        break;
167 Franz 598
                        }
8 paul 599
                        f.close();
600
                        if (found)
167 Franz 601
                        {
8 paul 602
                                QTextStream ts2(&BBox, IO_ReadOnly);
286 Franz 603
                                ts2 >> x >> y >> b >> h;
204 Franz 604
                                QStringList args;
605
                                args.append("-r72");
606
                                args.append("-sOutputFile="+tmpFile);
607
                                args.append("-g"+tmp.setNum(qRound(b))+"x"+tmp2.setNum(qRound(h)));
1859 fschmid 608
                                args.append("\""+fn+"\"");
204 Franz 609
                                ret = callGS(args);
8 paul 610
                                if (ret == 0)
167 Franz 611
                                {
8 paul 612
                                        QImage image;
159 Franz 613
                                        image.load(tmpFile);
188 Franz 614
                                        image = image.convertDepth(32);
615
                                        image.setAlphaBuffer(true);
214 Franz 616
                                        if (ScApp->HavePngAlpha != 0)
617
                                        {
618
                                                int wi = image.width();
619
                                                int hi = image.height();
620
                                            for( int yi=0; yi < hi; ++yi )
8 paul 621
                                                {
214 Franz 622
                                                        QRgb *s = (QRgb*)(image.scanLine( yi ));
623
                                                        for(int xi=0; xi < wi; ++xi )
8 paul 624
                                                        {
214 Franz 625
                                                                if((*s) == 0xffffffff)
626
                                                                        (*s) &= 0x00ffffff;
627
                                                                s++;
188 Franz 628
                                                        }
629
                                        }
214 Franz 630
                                        }
188 Franz 631
                                        Bild = image.copy(static_cast<int>(x), 0, static_cast<int>(b-x), static_cast<int>(h-y));
204 Franz 632
                                        unlink(tmpFile);
8 paul 633
                                }
634
                        }
635
                }
167 Franz 636
        }
8 paul 637
#ifdef HAVE_TIFF
638
        if (ext == "tif")
167 Franz 639
        {
8 paul 640
                QImage img;
641
                QImage inI2;
642
                TIFF* tif = TIFFOpen(fn, "r");
643
                if(tif)
167 Franz 644
                {
8 paul 645
                        unsigned width, height,size;
646
                        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
647
                        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
648
                        size=width*height;
649
                        uint32 *bits=(uint32*) _TIFFmalloc(size * sizeof (uint32));
650
                        if(bits)
167 Franz 651
                        {
652
                                if (TIFFReadRGBAImage(tif, width, height, bits, 0))
8 paul 653
                                {
189 Franz 654
                                img.create(width,height,32);
655
                                img.setAlphaBuffer(true);
8 paul 656
                                        if(TIFFGetR(0x1234567)==qRed  (0x1234567) &&
657
                                                 TIFFGetG(0x1234567)==qGreen(0x1234567) &&
658
                                                 TIFFGetB(0x1234567)==qBlue (0x1234567))
167 Franz 659
                                        {
8 paul 660
                                                for(unsigned y=0; y<height; ++y)
661
                                                        memcpy(img.scanLine(height-1-y),bits+y*width,width*4);
167 Franz 662
                                        }
8 paul 663
                                        else
167 Franz 664
                                        {
8 paul 665
                                                uint32 *inp=bits;
666
                                                for(unsigned y=0; y<height; ++y)
167 Franz 667
                                                {
8 paul 668
                                                        QRgb *row=(QRgb*) (img.scanLine(height-1-y));
669
                                                        for(unsigned x=0; x<width; ++x)
167 Franz 670
                                                        {
8 paul 671
                                                                const uint32 col=*(inp++);
189 Franz 672
                                                                row[x]=qRgba(TIFFGetR(col), TIFFGetG(col), TIFFGetB(col), TIFFGetA(col));
8 paul 673
                                                        }
674
                                                }
167 Franz 675
                                        }
8 paul 676
                                        Bild = img.copy();
167 Franz 677
                                }
8 paul 678
                                _TIFFfree(bits);
167 Franz 679
                        }
8 paul 680
                        TIFFClose(tif);
681
                }
167 Franz 682
        }
8 paul 683
#endif
684
        else
167 Franz 685
        {
868 fschmid 686
                if (Bild.load(fn))
201 Franz 687
                {
868 fschmid 688
                        if (gray != 0)
689
                        {
690
                                if ((Bild.depth() == 8) && (Bild.isGrayscale()))
691
                                        *gray = true;
692
                                else
693
                                        *gray = false;
694
                        }
695
                        Bild = Bild.convertDepth(32);
201 Franz 696
                }
167 Franz 697
        }
8 paul 698
        return Bild;
699
}
700
 
701
#ifdef HAVE_CMS
702
QImage LoadPictCol(QString fn, QString Prof, bool UseEmbedded, bool *realCMYK)
703
{
84 Franz 704
        QString tmp, dummy, cmd1, cmd2, BBox, tmp2;
8 paul 705
        QChar tc;
706
        QImage Bild;
80 Franz 707
        double x, y, b, h;
8 paul 708
        bool found = false;
709
        int ret = -1;
282 Franz 710
        QString tmpFile = QDir::convertSeparators(QDir::homeDirPath()+"/.scribus/sc.png");
8 paul 711
        QFileInfo fi = QFileInfo(fn);
712
        QString ext = fi.extension(false).lower();
16 Franz 713
        if (ext == "pdf")
167 Franz 714
        {
204 Franz 715
                QStringList args;
716
                args.append("-r72");
717
                args.append("-sOutputFile="+tmpFile);
718
                args.append("-dFirstPage=1");
719
                args.append("-dLastPage=1");
1859 fschmid 720
                args.append("\""+fn+"\"");
204 Franz 721
                ret = callGS(args);
16 Franz 722
                if (ret == 0)
167 Franz 723
                {
16 Franz 724
                        QImage image;
159 Franz 725
                        image.load(tmpFile);
167 Franz 726
                        Bild = image.convertDepth(32);
204 Franz 727
                        unlink(tmpFile);
16 Franz 728
                        *realCMYK = false;
729
                }
167 Franz 730
                }
731
                if ((ext == "eps") || (ext == "ps"))
8 paul 732
                {
167 Franz 733
                        QFile f(fn);
734
                        if (f.open(IO_ReadOnly))
8 paul 735
                        {
167 Franz 736
                                QTextStream ts(&f);
737
                                while (!ts.atEnd())
8 paul 738
                                {
167 Franz 739
                                        tc = ' ';
740
                                        tmp = "";
741
                                        while ((tc != '\n') && (tc != '\r'))
8 paul 742
                                        {
167 Franz 743
                                                ts >> tc;
744
                                                if ((tc != '\n') && (tc != '\r'))
745
                                                        tmp += tc;
8 paul 746
                                        }
286 Franz 747
                                        if (tmp.startsWith("%%BoundingBox:"))
8 paul 748
                                        {
167 Franz 749
                                                found = true;
286 Franz 750
                                                BBox = tmp.remove("%%BoundingBox:");
8 paul 751
                                        }
286 Franz 752
                                        if (!found)
753
                                        {
754
                                                if (tmp.startsWith("%%BoundingBox"))
755
                                                {
756
                                                        found = true;
757
                                                        BBox = tmp.remove("%%BoundingBox");
758
                                                }
759
                                        }
167 Franz 760
                                        if (tmp.startsWith("%%EndComments"))
761
                                                break;
8 paul 762
                                }
167 Franz 763
                                f.close();
764
                                if (found)
8 paul 765
                                {
167 Franz 766
                                        QTextStream ts2(&BBox, IO_ReadOnly);
286 Franz 767
                                        ts2 >> x >> y >> b >> h;
204 Franz 768
                                        QStringList args;
769
                                        args.append("-r72");
770
                                        args.append("-sOutputFile="+tmpFile);
771
                                        args.append("-g"+tmp.setNum(qRound(b))+"x"+tmp2.setNum(qRound(h)));
1859 fschmid 772
                                        args.append("\""+fn+"\"");
204 Franz 773
                                        ret = callGS(args);
167 Franz 774
                                        if (ret == 0)
8 paul 775
                                        {
167 Franz 776
                                                QImage image;
777
                                                image.load(tmpFile);
188 Franz 778
                                                image = image.convertDepth(32);
779
                                                image.setAlphaBuffer(true);
214 Franz 780
                                                if (ScApp->HavePngAlpha != 0)
781
                                                {
782
                                                        int wi = image.width();
783
                                                        int hi = image.height();
784
                                                    for( int yi=0; yi < hi; ++yi )
8 paul 785
                                                        {
214 Franz 786
                                                                QRgb *s = (QRgb*)(image.scanLine( yi ));
787
                                                                for(int xi=0; xi < wi; ++xi )
8 paul 788
                                                                {
214 Franz 789
                                                                        if((*s) == 0xffffffff)
790
                                                                                (*s) &= 0x00ffffff;
791
                                                                        s++;
188 Franz 792
                                                                }
214 Franz 793
                                                        }
794
                                            }
188 Franz 795
                                                Bild = image.copy(static_cast<int>(x), 0, static_cast<int>(b-x), static_cast<int>(h-y));
204 Franz 796
                                                unlink(tmpFile);
167 Franz 797
                                                *realCMYK = false;
8 paul 798
                                        }
799
                                }
800
                        }
801
                }
802
#ifdef HAVE_TIFF
167 Franz 803
                if (ext == "tif")
8 paul 804
                {
167 Franz 805
                        QImage img;
806
                        QImage inI2;
807
                        TIFF* tif = TIFFOpen(fn, "r");
808
                        if(tif)
8 paul 809
                        {
167 Franz 810
                        DWORD EmbedLen = 0;
811
                        LPBYTE EmbedBuffer;
812
                                unsigned width, height,size;
813
                                TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
814
                                TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
815
                                size=width*height;
816
                                uint32 *bits=(uint32*) _TIFFmalloc(size * sizeof (uint32));
817
                                if(bits)
8 paul 818
                                {
167 Franz 819
                                        if (TIFFReadRGBAImage(tif, width, height, bits, 0))
8 paul 820
                                        {
167 Franz 821
                                img.create(width,height,32);
189 Franz 822
                                img.setAlphaBuffer(true);
167 Franz 823
                                                if(TIFFGetR(0x1234567)==qRed  (0x1234567) &&
824
                                                         TIFFGetG(0x1234567)==qGreen(0x1234567) &&
825
                                                         TIFFGetB(0x1234567)==qBlue (0x1234567))
8 paul 826
                                                {
167 Franz 827
                                                        for(unsigned y=0; y<height; ++y)
828
                                                                memcpy(img.scanLine(height-1-y),bits+y*width,width*4);
8 paul 829
                                                }
167 Franz 830
                                                else
8 paul 831
                                                {
167 Franz 832
                                                        uint32 *inp=bits;
833
                                                        for(unsigned y=0; y<height; ++y)
8 paul 834
                                                        {
167 Franz 835
                                                                QRgb *row=(QRgb*) (img.scanLine(height-1-y));
836
                                                                for(unsigned x=0; x<width; ++x)
8 paul 837
                                                                {
167 Franz 838
                                                                        const uint32 col=*(inp++);
189 Franz 839
                                                                        row[x]=qRgba(TIFFGetR(col), TIFFGetG(col), TIFFGetB(col), TIFFGetA(col));
8 paul 840
                                                                }
841
                                                        }
842
                                                }
167 Franz 843
                                                Bild = img.copy();
8 paul 844
                                        }
167 Franz 845
                                        _TIFFfree(bits);
846
                                        cmsHTRANSFORM xform;
847
                                        cmsHPROFILE inputProf;
848
                                        if((TIFFGetField(tif, TIFFTAG_ICCPROFILE, &EmbedLen, &EmbedBuffer)) && (UseEmbedded))
8 paul 849
                                        {
167 Franz 850
                                                inputProf = cmsOpenProfileFromMem(EmbedBuffer, EmbedLen);
851
                                                if (static_cast<int>(cmsGetColorSpace(inputProf)) == icSigRgbData)
8 paul 852
                                                {
167 Franz 853
                                                        switch (static_cast<int>(cmsGetColorSpace(CMSprinterProf)))
8 paul 854
                                                        {
167 Franz 855
                                                                case icSigRgbData:
856
                                                                                *realCMYK = false;
857
                                                                                xform = cmsCreateTransform(inputProf, TYPE_RGBA_8, CMSprinterProf,
858
                                                                                                                                         TYPE_RGBA_8, IntentPrinter, 0);
859
                                                                                break;
860
                                                                case icSigCmykData:
861
                                                                                *realCMYK = true;
862
                                                                                xform = cmsCreateTransform(inputProf, TYPE_RGBA_8, CMSprinterProf,
863
                                                                                                                                         TYPE_CMYK_8, IntentPrinter, 0);
864
                                                                        break;
8 paul 865
                                                        }
167 Franz 866
                                                        for (int i=0; i < Bild.height(); ++i)
8 paul 867
                                                        {
167 Franz 868
                                                                LPBYTE ptr = Bild.scanLine(i);
869
                                                                cmsDoTransform(xform, ptr, ptr, Bild.width());
8 paul 870
                                                        }
871
                                                }
872
                                        }
167 Franz 873
                                        else
8 paul 874
                                        {
167 Franz 875
                                                inputProf = cmsOpenProfileFromFile(InputProfiles[Prof], "r");
876
                                                switch (static_cast<int>(cmsGetColorSpace(CMSprinterProf)))
8 paul 877
                                                {
167 Franz 878
                                                        case icSigRgbData:
879
                                                                                *realCMYK = false;
880
                                                                                xform = cmsCreateTransform(inputProf, TYPE_RGBA_8, CMSprinterProf,
881
                                                                                                                                         TYPE_RGBA_8, IntentPrinter, 0);
882
                                                                                break;
883
                                                        case icSigCmykData:
884
                                                                                *realCMYK = true;
885
                                                                                xform = cmsCreateTransform(inputProf, TYPE_RGBA_8, CMSprinterProf,
886
                                                                                                                                         TYPE_CMYK_8, IntentPrinter, 0);
887
                                                                                break;
8 paul 888
                                                }
167 Franz 889
                                                for (int i=0; i < Bild.height(); ++i)
8 paul 890
                                                {
167 Franz 891
                                                        LPBYTE ptr = Bild.scanLine(i);
892
                                                        cmsDoTransform(xform, ptr, ptr, Bild.width());
8 paul 893
                                                }
894
                                        }
167 Franz 895
                                        cmsDeleteTransform(xform);
896
                                        cmsCloseProfile(inputProf);
8 paul 897
                                }
167 Franz 898
                                TIFFClose(tif);
8 paul 899
                        }
900
                }
901
#endif
902
        else
167 Franz 903
        {
8 paul 904
                cmsHTRANSFORM xform;
905
                cmsHPROFILE inputProf;
906
                Bild.load(fn);
167 Franz 907
                Bild = Bild.convertDepth(32);
8 paul 908
                inputProf = cmsOpenProfileFromFile(InputProfiles[Prof], "r");
49 paul 909
                switch (static_cast<int>(cmsGetColorSpace(CMSprinterProf)))
167 Franz 910
                {
8 paul 911
                        case icSigRgbData:
912
                                *realCMYK = false;
913
                                xform = cmsCreateTransform(inputProf, TYPE_RGBA_8, CMSprinterProf, TYPE_RGBA_8, IntentPrinter, 0);
914
                                break;
915
                        case icSigCmykData:
916
                                *realCMYK = true;
917
                                xform = cmsCreateTransform(inputProf, TYPE_RGBA_8, CMSprinterProf, TYPE_CMYK_8, IntentPrinter, 0);
918
                                break;
167 Franz 919
                }
8 paul 920
                for (int i=0; i < Bild.height(); ++i)
167 Franz 921
                {
8 paul 922
                        LPBYTE ptr = Bild.scanLine(i);
923
                        cmsDoTransform(xform, ptr, ptr, Bild.width());
167 Franz 924
                }
8 paul 925
                cmsDeleteTransform(xform);
150 Franz 926
                cmsCloseProfile(inputProf);
167 Franz 927
        }
8 paul 928
        return Bild;
929
}
930
#endif
931
 
932
QString GetAttr(QDomElement *el, QString at, QString def)
933
{
934
        return el->attribute(at, def);
935
}
936
 
937
int QStoInt(QString in)
938
{
939
        bool ok = false;
940
        int c = in.toInt(&ok);
167 Franz 941
        return ok ? c : 0;
8 paul 942
}
943
 
80 Franz 944
double QStodouble(QString in)
8 paul 945
{
946
        bool ok = false;
80 Franz 947
        double c = in.toDouble(&ok);
167 Franz 948
        return ok ? c : 0.0;
8 paul 949
}
950
 
951
QPixmap loadIcon(QString nam)
952
{
870 cbradney 953
        QString pfad = ICONDIR;
954
        pfad += nam;
8 paul 955
        QPixmap pm;
956
        pm.load(pfad);
957
        return pm;
958
}
959
 
1108 fschmid 960
uint getDouble(QString in, bool raw)
961
{
962
        QByteArray bb(4);
963
        if (raw)
964
        {
965
                bb[3] = static_cast<uchar>(QChar(in.at(0)));
966
                bb[2] = static_cast<uchar>(QChar(in.at(1)));
967
                bb[1] = static_cast<uchar>(QChar(in.at(2)));
968
                bb[0] = static_cast<uchar>(QChar(in.at(3)));
969
        }
970
        else
971
        {
972
                bb[0] = static_cast<uchar>(QChar(in.at(0)));
973
                bb[1] = static_cast<uchar>(QChar(in.at(1)));
974
                bb[2] = static_cast<uchar>(QChar(in.at(2)));
975
                bb[3] = static_cast<uchar>(QChar(in.at(3)));
976
        }
977
        uint ret;
978
        ret = bb[0] & 0xff;
979
        ret |= (bb[1] << 8) & 0xff00;
980
        ret |= (bb[2] << 16) & 0xff0000;
981
        ret |= (bb[3] << 24) & 0xff000000;
982
        return ret;
983
}
984
 
8 paul 985
bool loadText(QString nam, QString *Buffer)
986
{
987
        QFile f(nam);
988
        QFileInfo fi(f);
989
        if (!fi.exists())
990
                return false;
991
        uint posi;
167 Franz 992
        bool ret;
8 paul 993
        QByteArray bb(f.size());
994
        if (f.open(IO_ReadOnly))
167 Franz 995
        {
8 paul 996
                f.readBlock(bb.data(), f.size());
997
                f.close();
998
                for (posi = 0; posi < bb.size(); ++posi)
999
                        *Buffer += bb[posi];
1000
                ret = true;
167 Franz 1001
        }
8 paul 1002
        else
1003
                ret = false;
1004
        return ret;
1005
}
1006
 
80 Franz 1007
double Cwidth(ScribusDoc *doc, QString name, QString ch, int Siz, QString ch2)
8 paul 1008
{
80 Franz 1009
        double w;
8 paul 1010
        FT_Vector  delta;
1011
        uint c1 = ch.at(0).unicode();
1012
        uint c2 = ch2.at(0).unicode();
1013
        Foi* fo = (*doc->AllFonts)[name];
1014
        if (fo->CharWidth.contains(c1))
167 Franz 1015
        {
111 Franz 1016
                w = fo->CharWidth[c1]*(Siz / 10.0);
8 paul 1017
                if (fo->HasKern)
167 Franz 1018
                {
8 paul 1019
                        uint cl = FT_Get_Char_Index(doc->FFonts[name], c1);
1020
                        uint cr = FT_Get_Char_Index(doc->FFonts[name], c2);
9 Franz 1021
                        FT_Get_Kerning(doc->FFonts[name], cl, cr, ft_kerning_unscaled, &delta);
111 Franz 1022
                        w += delta.x / fo->uniEM * (Siz / 10.0);
167 Franz 1023
                }
8 paul 1024
                return w;
167 Franz 1025
        }
8 paul 1026
        else
111 Franz 1027
                return static_cast<double>(Siz / 10.0);
8 paul 1028
}
1029
 
220 Franz 1030
double RealCWidth(ScribusDoc *doc, QString name, QString ch, int Siz)
1031
{
221 Franz 1032
        double w, ww;
220 Franz 1033
        uint c1 = ch.at(0).unicode();
1034
        Foi* fo = (*doc->AllFonts)[name];
1035
        if (fo->CharWidth.contains(c1))
1036
        {
1037
                uint cl = FT_Get_Char_Index(doc->FFonts[name], c1);
1038
                FT_Load_Glyph( doc->FFonts[name], cl, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP );
503 cbradney 1039
                w = (doc->FFonts[name]->glyph->metrics.width + fabs((double)doc->FFonts[name]->glyph->metrics.horiBearingX)) / fo->uniEM * (Siz / 10.0);
221 Franz 1040
                ww = doc->FFonts[name]->glyph->metrics.horiAdvance / fo->uniEM * (Siz / 10.0);
1041
                return QMAX(ww, w);
220 Franz 1042
        }
1043
        else
1044
                return static_cast<double>(Siz / 10.0);
1045
}
1046
 
80 Franz 1047
QPointArray RegularPolygon(double w, double h, uint c, bool star, double factor, double rota)
8 paul 1048
{
167 Franz 1049
        uint cx = star ? c * 2 : c;
80 Franz 1050
        double seg = 360.0 / cx;
1051
        double sc = rota + 180.0;
1052
        double di = factor;
8 paul 1053
        int mx = 0;
1054
        int my = 0;
1055
        QPointArray pts = QPointArray();
1056
        for (uint x = 0; x < cx; ++x)
167 Franz 1057
        {
8 paul 1058
                sc = seg * x + 180.0 + rota;
1059
                if (star)
167 Franz 1060
                {
1061
                        double wf = x % 2 == 0 ? w / 2 : w / 2 * di;
1062
                        double hf = x % 2 == 0 ? h / 2 : h / 2 * di;
1063
                        mx = qRound(sin(sc / 180 * M_PI) * (wf) + (w/2));
1064
                        my = qRound(cos(sc / 180 * M_PI) * (hf) + (h/2));
1065
                }
8 paul 1066
                else
167 Franz 1067
                {
8 paul 1068
                        mx = qRound(sin(sc / 180 * M_PI) * (w/2) + (w/2));
1069
                        my = qRound(cos(sc / 180 * M_PI) * (h/2) + (h/2));
167 Franz 1070
                }
8 paul 1071
                pts.resize(x+1);
1072
                pts.setPoint(x, mx, my);
167 Franz 1073
        }
8 paul 1074
        return pts;
1075
}
1076
 
80 Franz 1077
FPointArray RegularPolygonF(double w, double h, uint c, bool star, double factor, double rota)
8 paul 1078
{
167 Franz 1079
        uint cx = star ? c * 2 : c;
80 Franz 1080
        double seg = 360.0 / cx;
1081
        double sc = rota + 180.0;
1082
        double di = factor;
1083
        double mx = 0;
1084
        double my = 0;
8 paul 1085
        FPointArray pts = FPointArray();
1086
        for (uint x = 0; x < cx; ++x)
167 Franz 1087
        {
8 paul 1088
                sc = seg * x + 180.0 + rota;
1089
                if (star)
167 Franz 1090
                {
1091
                        double wf = x % 2 == 0 ? w / 2 : w / 2 * di;
1092
                        double hf = x % 2 == 0 ? h / 2 : h / 2 * di;
1093
                        mx = qRound(sin(sc / 180 * M_PI) * (wf) + (w/2));
1094
                        my = qRound(cos(sc / 180 * M_PI) * (hf) + (h/2));
1095
                }
8 paul 1096
                else
167 Franz 1097
                {
8 paul 1098
                        mx = sin(sc / 180 * M_PI) * (w/2) + (w/2);
1099
                        my = cos(sc / 180 * M_PI) * (h/2) + (h/2);
167 Franz 1100
                }
8 paul 1101
                pts.resize(x+1);
1102
                pts.setPoint(x, mx, my);
167 Franz 1103
        }
8 paul 1104
        return pts;
1105
}
1106
 
1107
QPointArray FlattenPath(FPointArray ina, QValueList<uint> &Segs)
1108
{
1109
        QPointArray Bez(4);
1110
        QPointArray outa, cli;
1111
        Segs.clear();
1112
        if (ina.size() > 3)
167 Franz 1113
        {
1114
                for (uint poi=0; poi<ina.size()-3; poi += 4)
8 paul 1115
                {
167 Franz 1116
                        if (ina.point(poi).x() > 900000)
8 paul 1117
                        {
1118
                                outa.resize(outa.size()+1);
1119
                                outa.setPoint(outa.size()-1, cli.point(cli.size()-1));
80 Franz 1120
                                Segs.append(outa.size());
8 paul 1121
                                continue;
167 Franz 1122
                        }
8 paul 1123
                        BezierPoints(&Bez, ina.pointQ(poi), ina.pointQ(poi+1), ina.pointQ(poi+3), ina.pointQ(poi+2));
1124
                        cli = Bez.cubicBezier();
1125
                        outa.putPoints(outa.size(), cli.size()-1, cli);
167 Franz 1126
                }
8 paul 1127
                outa.resize(outa.size()+1);
1128
                outa.setPoint(outa.size()-1, cli.point(cli.size()-1));
167 Franz 1129
        }
8 paul 1130
        return outa;
1131
}
1132
 
80 Franz 1133
double xy2Deg(double x, double y)
8 paul 1134
{
1135
        return (atan2(y,x)*(180.0/M_PI));
1136
}
1137
 
1138
void BezierPoints(QPointArray *ar, QPoint n1, QPoint n2, QPoint n3, QPoint n4)
1139
{
1140
        ar->setPoint(0, n1);
1141
        ar->setPoint(1, n2);
1142
        ar->setPoint(2, n3);
1143
        ar->setPoint(3, n4);
1144
        return;
1145
}
1146
 
1147
void Level2Layer(ScribusDoc *doc, struct Layer *ll, int Level)
1148
{
1149
        for (uint la2 = 0; la2 < doc->Layers.count(); ++la2)
167 Franz 1150
        {
1151
                if (doc->Layers[la2].Level == Level)
8 paul 1152
                {
1153
                        ll->Sichtbar = doc->Layers[la2].Sichtbar;
1154
                        ll->Drucken = doc->Layers[la2].Drucken;
1155
                        ll->LNr = doc->Layers[la2].LNr;
1156
                        break;
1157
                }
167 Franz 1158
        }
8 paul 1159
}
1160
 
1161
QString ImageToTxt(QImage *im)
1162
{
1163
        int h = im->height();
1164
        int w = im->width();
1165
        QString ImgStr = "";
1166
        for( int yi=0; yi < h; ++yi )
167 Franz 1167
        {
8 paul 1168
                QRgb * s = (QRgb*)(im->scanLine( yi ));
1169
                for( int xi=0; xi < w; ++xi )
167 Franz 1170
                {
8 paul 1171
                        QRgb r=*s++;
1172
                        unsigned char u=qRed(r);
1173
                        ImgStr += u;
1174
                        u=qGreen(r);
1175
                        ImgStr += u;
1176
                        u=qBlue(r);
1177
                        ImgStr += u;
1178
                }
167 Franz 1179
        }
8 paul 1180
        return ImgStr;
1181
}
1182
 
1183
QString ImageToCMYK(QImage *im)
1184
{
1185
        int h = im->height();
1186
        int w = im->width();
1187
        QString ImgStr = "";
1188
        for( int yi=0; yi < h; ++yi )
167 Franz 1189
        {
8 paul 1190
                QRgb * s = (QRgb*)(im->scanLine( yi ));
1191
                for( int xi=0; xi < w; ++xi )
167 Franz 1192
                {
201 Franz 1193
                        QRgb r=*s;
8 paul 1194
                        int c = 255 - qRed(r);
1195
                        int m = 255 - qGreen(r);
1196
                        int y = 255 - qBlue(r);
1197
                        int k = QMIN(QMIN(c, m), y);
201 Franz 1198
                        *s = qRgba(m - k, y - k, k, c - k);
8 paul 1199
                        ImgStr += c - k;
1200
                        ImgStr += m - k;
1201
                        ImgStr += y - k;
1202
                        ImgStr += k;
201 Franz 1203
                        s++;
8 paul 1204
                }
167 Franz 1205
        }
8 paul 1206
        return ImgStr;
1207
}
1208
 
1209
QString ImageToCMYK_PS(QImage *im, int pl, bool pre)
1210
{
1211
        int h = im->height();
1212
        int w = im->width();
1213
        QString ImgStr = "";
1214
        if (pre)
167 Franz 1215
        {
1216
                for( int yi=0; yi < h; ++yi )
8 paul 1217
                {
1218
                        QRgb * s = (QRgb*)(im->scanLine( yi ));
1219
                        for( int xi=0; xi < w; ++xi )
167 Franz 1220
                        {
8 paul 1221
                                QRgb r=*s++;
1222
                                int c = qRed(r);
1223
                                int m = qGreen(r);
1224
                                int y = qBlue(r);
1225
                                int k = qAlpha(r);
1226
                                if (pl == -1)
167 Franz 1227
                                {
8 paul 1228
                                        ImgStr += c;
1229
                                        ImgStr += m;
1230
                                        ImgStr += y;
1231
                                        ImgStr += k;
167 Franz 1232
                                }
8 paul 1233
                                else
167 Franz 1234
                                {
8 paul 1235
                                        if (pl == -2)
1236
                                                ImgStr += QMIN(255, qRound(0.3 * c + 0.59 * m + 0.11 * y + k));
1237
                                        if (pl == 1)
1238
                                                ImgStr += c;
1239
                                        if (pl == 2)
1240
                                                ImgStr += m;
1241
                                        if (pl == 3)
1242
                                                ImgStr += y;
1243
                                        if (pl == 0)
1244
                                                ImgStr += k;
1245
                                }
1246
                        }
1247
                }
167 Franz 1248
        }
8 paul 1249
        else
167 Franz 1250
        {
1251
                for( int yi=0; yi < h; ++yi )
8 paul 1252
                {
1253
                        QRgb * s = (QRgb*)(im->scanLine( yi ));
1254
                        for( int xi=0; xi < w; ++xi )
167 Franz 1255
                        {
8 paul 1256
                                QRgb r=*s++;
1257
                                int c = 255 - qRed(r);
1258
                                int m = 255 - qGreen(r);
1259
                                int y = 255 - qBlue(r);
1260
                                int k = QMIN(QMIN(c, m), y);
1261
                                if (pl == -1)
167 Franz 1262
                                {
8 paul 1263
                                        ImgStr += c - k;
1264
                                        ImgStr += m - k;
1265
                                        ImgStr += y - k;
1266
                                        ImgStr += k;
167 Franz 1267
                                }
8 paul 1268
                                else
167 Franz 1269
                                {
8 paul 1270
                                        if (pl == -2)
1271
                                                ImgStr += QMIN(255, qRound(0.3 * c + 0.59 * m + 0.11 * y + k));
1272
                                        if (pl == 1)
1273
                                                ImgStr += c - k;
1274
                                        if (pl == 2)
1275
                                                ImgStr += m - k;
1276
                                        if (pl == 3)
1277
                                                ImgStr += y - k;
1278
                                        if (pl == 0)
1279
                                                ImgStr += k;
1280
                                }
1281
                        }
1282
                }
167 Franz 1283
        }
8 paul 1284
        return ImgStr;
1285
}
1286
 
1287
QString MaskToTxt(QImage *im, bool PDF)
1288
{
1289
        int h = im->height();
1290
        int w = im->width();
167 Franz 1291
        int w2;
1292
        w2 = w / 8;
1293
        if ((w % 8) != 0)
1294
                w2++;
8 paul 1295
        QString ImgStr = "";
1296
        for( int yi=0; yi < h; ++yi )
167 Franz 1297
        {
8 paul 1298
                uchar * s = im->scanLine( yi );
1299
                for( int xi=0; xi < w2; ++xi )
167 Franz 1300
                {
8 paul 1301
                        unsigned char u = *(s+xi);
167 Franz 1302
                        ImgStr += PDF ? ~u : u;
8 paul 1303
                }
167 Franz 1304
        }
8 paul 1305
        return ImgStr;
1306
}
1307
 
203 Franz 1308
QString MaskToTxt14(QImage *im)
1309
{
1310
        int h = im->height();
1311
        int w = im->width();
1312
        QString ImgStr = "";
1313
        for( int yi=0; yi < h; ++yi )
1314
        {
1315
                QRgb * s = (QRgb*)(im->scanLine( yi ));
1316
                for( int xi=0; xi < w; ++xi )
1317
                {
1318
                        QRgb r=*s++;
1319
                        unsigned char u=qAlpha(r);
1320
                        ImgStr += u;
1321
                }
1322
        }
1323
        return ImgStr;
1324
}
1325
 
201 Franz 1326
typedef struct my_error_mgr
1327
{
1328
  struct jpeg_error_mgr pub;            /* "public" fields */
1329
  jmp_buf setjmp_buffer;  /* for return to caller */
1330
} *my_error_ptr;
1331
 
1332
/*
1333
 * Here's the routine that will replace the standard error_exit method:
1334
 */
1335
 
1336
static void my_error_exit (j_common_ptr cinfo)
1337
{
1338
  my_error_ptr myerr = (my_error_ptr) cinfo->err;
1339
  (*cinfo->err->output_message) (cinfo);
1340
  longjmp (myerr->setjmp_buffer, 1);
1341
}
1342
 
1886 fschmid 1343
bool isProgressive(QString fn)
1344
{
1345
        struct jpeg_decompress_struct cinfo;
1346
        struct my_error_mgr         jerr;
1347
        FILE     *infile;
1348
        bool ret = false;
1349
        cinfo.err = jpeg_std_error (&jerr.pub);
1350
        jerr.pub.error_exit = my_error_exit;
1351
        infile = NULL;
1352
        if (setjmp (jerr.setjmp_buffer))
1353
        {
1354
                jpeg_destroy_decompress (&cinfo);
1355
                if (infile)
1356
                        fclose (infile);
1357
                return ret;
1358
        }
1359
        jpeg_create_decompress (&cinfo);
1360
        if ((infile = fopen (fn, "rb")) == NULL)
1361
                return ret;
1362
        jpeg_stdio_src(&cinfo, infile);
1363
        jpeg_read_header(&cinfo, TRUE);
1364
        ret = jpeg_has_multiple_scans(&cinfo);
1365
        fclose (infile);
1366
        jpeg_destroy_decompress (&cinfo);
1367
        return ret;
1368
}
1369
 
202 Franz 1370
void Convert2JPG(QString fn, QImage *image, int Quality, bool isCMYK)
201 Franz 1371
{
1372
        struct jpeg_compress_struct cinfo;
1373
        struct my_error_mgr         jerr;
1374
        FILE     *outfile;
1375
        JSAMPROW row_pointer[1];
1376
        row_pointer[0] = 0;
1377
        cinfo.err = jpeg_std_error (&jerr.pub);
1378
        jerr.pub.error_exit = my_error_exit;
1379
        outfile = NULL;
1380
        if (setjmp (jerr.setjmp_buffer))
1381
        {
1382
                jpeg_destroy_compress (&cinfo);
1383
                if (outfile)
1384
                        fclose (outfile);
1385
                return;
1386
        }
1387
        jpeg_create_compress (&cinfo);
1388
        if ((outfile = fopen (fn, "wb")) == NULL)
1389
                return;
1390
        jpeg_stdio_dest (&cinfo, outfile);
1391
        cinfo.image_width  = image->width();
1392
        cinfo.image_height = image->height();
1393
        if (isCMYK)
1394
        {
1395
                cinfo.in_color_space = JCS_CMYK;
1396
                cinfo.input_components = 4;
1397
        }
1398
        else
1399
        {
1400
                cinfo.in_color_space = JCS_RGB;
1401
                cinfo.input_components = 3;
1402
        }
1403
        jpeg_set_defaults (&cinfo);
202 Franz 1404
        int qual[] = { 95, 85, 75, 50, 25 };  // These are the JPEG Quality settings 100 means best, 0 .. don't discuss
1405
        jpeg_set_quality (&cinfo, qual[Quality], true);
201 Franz 1406
        jpeg_start_compress (&cinfo, TRUE);
1407
        row_pointer[0] = new uchar[cinfo.image_width*cinfo.input_components];
1408
        int w = cinfo.image_width;
1409
        while (cinfo.next_scanline < cinfo.image_height)
1410
        {
1411
                uchar *row = row_pointer[0];
1412
                if (isCMYK)
1413
                {
1414
                        QRgb* rgba = (QRgb*)image->scanLine(cinfo.next_scanline);
1415
                        for (int i=0; i<w; ++i)
1416
                        {
1417
                                *row++ = qAlpha(*rgba);
1418
                                *row++ = qRed(*rgba);
1419
                                *row++ = qGreen(*rgba);
1420
                                *row++ = qBlue(*rgba);
1421
                                ++rgba;
1422
                        }
1423
                }
1424
                else
1425
                {
1426
                        QRgb* rgb = (QRgb*)image->scanLine(cinfo.next_scanline);
1427
                        for (int i=0; i<w; i++)
1428
                        {
1429
                                *row++ = qRed(*rgb);
1430
                                *row++ = qGreen(*rgb);
1431
                                *row++ = qBlue(*rgb);
1432
                                ++rgb;
1433
                        }
1434
                }
1435
                jpeg_write_scanlines (&cinfo, row_pointer, 1);
1436
        }
1437
        jpeg_finish_compress (&cinfo);
1438
        fclose (outfile);
1439
        jpeg_destroy_compress (&cinfo);
1440
        delete [] row_pointer[0];
1441
}
1442
 
8 paul 1443
QString CompressStr(QString *in)
1444
{
1445
        QString out = "";
1446
#ifdef HAVE_LIBZ
1447
        QByteArray bb(in->length());
1448
        for (uint ax = 0; ax < in->length(); ++ax)
1449
                bb[ax] = uchar(QChar(in->at(ax)));
1450
        uLong exlen = uint(bb.size() * 0.001 + 16) + bb.size();
1451
        QByteArray bc(exlen);
1452
        compress2((Byte *)bc.data(), &exlen, (Byte *)bb.data(), uLong(bb.size()), 9);
1453
        for (uint cl = 0; cl < exlen; ++cl)
1454
                out += bc[cl];
1455
#else
1456
        out = *in;
1457
#endif
1458
        return out;
1459
}
1460
 
1461
char *toHex( uchar u )
1462
{
1463
    static char hexVal[3];
1464
    int i = 1;
1465
    while ( i >= 0 )
167 Franz 1466
        {
1467
                ushort hex = (u & 0x000f);
1468
                if ( hex < 0x0a )
8 paul 1469
                hexVal[i] = '0'+hex;
167 Franz 1470
                else
8 paul 1471
                hexVal[i] = 'A'+(hex-0x0a);
167 Franz 1472
                u = u >> 4;
8 paul 1473
                        i--;
167 Franz 1474
    }
8 paul 1475
    hexVal[2] = '\0';
1476
    return hexVal;
1477
}
1478
 
1479
QString String2Hex(QString *in, bool lang)
1480
{
1481
        int i = 0;
1482
        QString out = "";
1483
        for( uint xi = 0; xi < in->length(); ++xi )
167 Franz 1484
        {
8 paul 1485
                out += toHex(uchar(QChar(in->at(xi))));
1486
                ++i;
1487
                if ((i>40) && (lang))
167 Franz 1488
                {
8 paul 1489
                        out += '\n';
1490
                        i=0;
1491
                }
167 Franz 1492
        }
8 paul 1493
        return out;
1494
}
1495
 
1496
QByteArray ComputeMD5Sum(QByteArray *in)
1497
{
1498
        QByteArray MDsum(16);
49 paul 1499
        md5_buffer (in->data(), in->size(), reinterpret_cast<void*>(MDsum.data()));
8 paul 1500
        return MDsum;
1501
}
1502
 
19 Franz 1503
QString Path2Relative(QString Path)
1504
{
1505
        QString Ndir = "";
1506
        QStringList Pdir = QStringList::split("/", QDir::currentDirPath());
1507
        QFileInfo Bfi = QFileInfo(Path);
1508
        QStringList Bdir = QStringList::split("/", Bfi.dirPath(true));
1509
        bool ende = true;
1510
        uint dcoun = 0;
1511
        uint dcoun2 = 0;
1512
        while (ende)
167 Franz 1513
        {
19 Franz 1514
                if (Pdir[dcoun] == Bdir[dcoun])
1515
                        dcoun++;
1516
                else
1517
                        break;
1518
                if (dcoun > Pdir.count())
1519
                        break;
167 Franz 1520
        }
19 Franz 1521
        dcoun2 = dcoun;
1522
        for (uint ddx2 = dcoun; ddx2 < Pdir.count(); ddx2++)
1523
                Ndir += "../";
1524
        for (uint ddx = dcoun2; ddx < Bdir.count(); ddx++)
1525
                Ndir += Bdir[ddx]+"/";
1526
        Ndir += Bfi.fileName();
1527
        return Ndir;
1528
}
1529
 
1084 fschmid 1530
int setBestEncoding(FT_Face face)
8 paul 1531
{
1532
        FT_ULong  charcode;
895 fschmid 1533
        FT_UInt   gindex;
875 fschmid 1534
        bool foundEncoding = false;
895 fschmid 1535
        int countUniCode = 0;
1536
        int chmapUniCode = 0;
1537
        int chmapCustom = 0;
1084 fschmid 1538
        int retVal = 0;
895 fschmid 1539
        FT_CharMap defaultEncoding = face->charmap;
391 Franz 1540
        for(int u = 0; u < face->num_charmaps; u++)
1541
        {
895 fschmid 1542
                if (face->charmaps[u]->encoding == FT_ENCODING_UNICODE )
391 Franz 1543
                {
895 fschmid 1544
                        FT_Set_Charmap(face, face->charmaps[u]);
1545
                        chmapUniCode = u;
1546
                        gindex = 0;
1547
                        charcode = FT_Get_First_Char( face, &gindex );
1548
                        while ( gindex != 0 )
875 fschmid 1549
                        {
895 fschmid 1550
                                countUniCode++;
1551
                                charcode = FT_Get_Next_Char( face, charcode, &gindex );
875 fschmid 1552
                        }
1553
                }
895 fschmid 1554
                if (face->charmaps[u]->encoding == FT_ENCODING_ADOBE_CUSTOM)
875 fschmid 1555
                {
895 fschmid 1556
                        chmapCustom = u;
1557
                        foundEncoding = true;
1084 fschmid 1558
                        retVal = 1;
1559
                        break;
875 fschmid 1560
                }
1064 cbradney 1561
                else if (face->charmaps[u]->encoding == FT_ENCODING_MS_SYMBOL)
1562
                {
1563
                        chmapCustom = u;
1564
                        foundEncoding = true;
1084 fschmid 1565
                        retVal = 2;
1566
                        break;
1064 cbradney 1567
                }
875 fschmid 1568
        }
1898 fschmid 1569
        if (countUniCode == face->num_glyphs-1)
1084 fschmid 1570
        {
895 fschmid 1571
                FT_Set_Charmap(face, face->charmaps[chmapUniCode]);
1084 fschmid 1572
                retVal = 0;
1573
        }
895 fschmid 1574
        else if (foundEncoding)
1575
                FT_Set_Charmap(face, face->charmaps[chmapCustom]);
1576
        else
1084 fschmid 1577
        {
895 fschmid 1578
                FT_Set_Charmap(face, defaultEncoding);
1084 fschmid 1579
                retVal = 0;
1580
        }
1581
        return retVal;
895 fschmid 1582
}
1583
 
1584
bool GlyNames(QMap<uint, QString> *GList, QString Dat)
1585
{
1586
        bool error;
1587
        char *buf[50];
1588
        FT_Library library;
1589
        FT_Face face;
1590
        FT_ULong  charcode;
1591
        FT_UInt gindex;
1592
        error = FT_Init_FreeType(&library);
1593
        error = FT_New_Face(library, Dat, 0, &face);
1594
        setBestEncoding(face);
77 Franz 1595
        gindex = 0;
167 Franz 1596
        charcode = FT_Get_First_Char(face, &gindex );
1597
        while (gindex != 0)
1598
        {
8 paul 1599
                FT_Get_Glyph_Name(face, gindex, buf, 50);
49 paul 1600
                GList->insert(charcode, QString(reinterpret_cast<char*>(buf)));
167 Franz 1601
        charcode = FT_Get_Next_Char(face, charcode, &gindex );
1602
        }
8 paul 1603
        FT_Done_FreeType( library );
1604
        return true;
1605
}
1606
 
1607
bool GlyIndex(QMap<uint, PDFlib::GlNamInd> *GListInd, QString Dat)
1608
{
1609
        struct PDFlib::GlNamInd gln;
1610
        bool error;
1611
        char *buf[50];
1612
        FT_Library library;
1613
        FT_Face face;
1614
        FT_ULong  charcode;
167 Franz 1615
        FT_UInt   gindex;
1616
        uint counter1 = 32;
1617
        uint counter2 = 0;
8 paul 1618
        error = FT_Init_FreeType(&library);
1619
        error = FT_New_Face(library, Dat, 0, &face);
895 fschmid 1620
        setBestEncoding(face);
77 Franz 1621
        gindex = 0;
167 Franz 1622
        charcode = FT_Get_First_Char(face, &gindex );
1623
        while (gindex != 0)
1624
        {
8 paul 1625
                FT_Get_Glyph_Name(face, gindex, buf, 50);
1626
                gln.Code = counter1 + counter2;
49 paul 1627
                gln.Name = "/"+QString(reinterpret_cast<char*>(buf));
8 paul 1628
                GListInd->insert(charcode, gln);
167 Franz 1629
        charcode = FT_Get_Next_Char(face, charcode, &gindex );
1630
        counter1++;
1631
        if (counter1 > 255)
1632
                {
8 paul 1633
                        counter1 = 32;
1634
                        counter2 += 0x100;
1635
                }
167 Franz 1636
        }
8 paul 1637
        FT_Done_FreeType( library );
1638
        return true;
1639
}
1640
 
1641
FPoint firstP;
1642
bool FirstM;
1643
 
1644
int traceMoveto( FT_Vector *to, FPointArray *composite )
1645
{
1646
        double tox = ( to->x / 64.0 );
1647
        double toy = ( to->y / 64.0 );
1648
        if (!FirstM)
167 Franz 1649
        {
68 Franz 1650
                composite->addPoint(firstP);
1651
                composite->addPoint(firstP);
1652
                composite->setMarker();
167 Franz 1653
        }
8 paul 1654
        else
1655
                FirstM = false;
68 Franz 1656
        composite->addPoint(FPoint(tox, toy));
1657
        composite->addPoint(FPoint(tox, toy));
8 paul 1658
        firstP = FPoint(tox, toy);
1659
        return 0;
1660
}
1661
 
1662
int traceLineto( FT_Vector *to, FPointArray *composite )
1663
{
1664
        double tox = ( to->x / 64.0 );
1665
        double toy = ( to->y / 64.0 );
120 Franz 1666
        if (composite->size() > 4)
167 Franz 1667
        {
120 Franz 1668
                FPoint b1 = composite->point(composite->size()-4);
1669
                FPoint b2 = composite->point(composite->size()-3);
1670
                FPoint b3 = composite->point(composite->size()-2);
1671
                FPoint b4 = composite->point(composite->size()-1);
1672
                FPoint n1 = FPoint(tox, toy);
1673
                FPoint n2 = FPoint(tox, toy);
1674
                FPoint n3 = FPoint(tox, toy);
1675
                FPoint n4 = FPoint(tox, toy);
1676
                if ((b1 == n1) && (b2 == n2) && (b3 == n3) && (b4 == n4))
1677
                        return 0;
167 Franz 1678
        }
68 Franz 1679
        composite->addPoint(FPoint(tox, toy));
1680
        composite->addPoint(FPoint(tox, toy));
1681
        composite->addPoint(FPoint(tox, toy));
1682
        composite->addPoint(FPoint(tox, toy));
8 paul 1683
        return 0;
1684
}
1685
 
1686
int traceQuadraticBezier( FT_Vector *control, FT_Vector *to, FPointArray *composite )
1687
{
1688
        double x1 = ( control->x / 64.0 );
1689
        double y1 = ( control->y / 64.0 );
1690
        double x2 = ( to->x / 64.0 );
1691
        double y2 = ( to->y / 64.0 );
120 Franz 1692
        if (composite->size() > 4)
167 Franz 1693
        {
120 Franz 1694
                FPoint b1 = composite->point(composite->size()-4);
1695
                FPoint b2 = composite->point(composite->size()-3);
1696
                FPoint b3 = composite->point(composite->size()-2);
1697
                FPoint b4 = composite->point(composite->size()-1);
1698
                FPoint n1 = FPoint(x2, y2);
1699
                FPoint n2 = FPoint(x1, y1);
1700
                FPoint n3 = FPoint(x2, y2);
1701
                FPoint n4 = FPoint(x2, y2);
1702
                if ((b1 == n1) && (b2 == n2) && (b3 == n3) && (b4 == n4))
1703
                        return 0;
167 Franz 1704
        }
68 Franz 1705
        composite->addPoint(FPoint(x2, y2));
1706
        composite->addPoint(FPoint(x1, y1));
1707
        composite->addPoint(FPoint(x2, y2));
1708
        composite->addPoint(FPoint(x2, y2));
8 paul 1709
        return 0;
167 Franz 1710
}
8 paul 1711
 
1712
int traceCubicBezier( FT_Vector *p, FT_Vector *q, FT_Vector *to, FPointArray *composite )
1713
{
1714
        double x1 = ( p->x / 64.0 );
1715
        double y1 = ( p->y / 64.0 );
1716
        double x2 = ( q->x / 64.0 );
1717
        double y2 = ( q->y / 64.0 );
1718
        double x3 = ( to->x / 64.0 );
1719
        double y3 = ( to->y / 64.0 );
120 Franz 1720
        if (composite->size() > 4)
167 Franz 1721
        {
120 Franz 1722
                FPoint b1 = composite->point(composite->size()-4);
1723
                FPoint b2 = composite->point(composite->size()-3);
1724
                FPoint b3 = composite->point(composite->size()-2);
1725
                FPoint b4 = composite->point(composite->size()-1);
1726
                FPoint n1 = FPoint(x3, y3);
1727
                FPoint n2 = FPoint(x2, y2);
1728
                FPoint n3 = FPoint(x3, y3);
1729
                FPoint n4 = FPoint(x3, y3);
1730
                if ((b1 == n1) && (b2 == n2) && (b3 == n3) && (b4 == n4))
1731
                        return 0;
167 Franz 1732
        }
8 paul 1733
        composite->setPoint(composite->size()-1, FPoint(x1, y1));
68 Franz 1734
        composite->addPoint(FPoint(x3, y3));
1735
        composite->addPoint(FPoint(x2, y2));
1736
        composite->addPoint(FPoint(x3, y3));
1737
        composite->addPoint(FPoint(x3, y3));
8 paul 1738
        return 0;
1739
}
1740
 
1741
FT_Outline_Funcs OutlineMethods =
1742
{
1743
        (FT_Outline_MoveTo_Func) traceMoveto,
1744
        (FT_Outline_LineTo_Func) traceLineto,
1745
        (FT_Outline_ConicTo_Func) traceQuadraticBezier,
1746
        (FT_Outline_CubicTo_Func) traceCubicBezier,
1747
        0,
1748
 
1749
};
1750
 
220 Franz 1751
FPointArray traceChar(FT_Face face, uint chr, int chs, double *x, double *y, bool *err)
8 paul 1752
{
220 Franz 1753
        bool error = false;
8 paul 1754
        FT_UInt glyphIndex;
1755
        FPointArray pts, pts2;
1756
        pts.resize(0);
220 Franz 1757
        pts2.resize(0);
8 paul 1758
        firstP = FPoint(0,0);
1759
        FirstM = true;
220 Franz 1760
        error = FT_Set_Char_Size( face, 0, chs*64, 72, 72 );
1761
        if (error)
1762
        {
1763
                *err = error;
1764
                return pts2;
1765
        }
8 paul 1766
        glyphIndex = FT_Get_Char_Index(face, chr);
220 Franz 1767
        if (glyphIndex == 0)
1768
        {
1769
                *err = true;
1770
                return pts2;
1771
        }
1772
        error = FT_Load_Glyph( face, glyphIndex, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP );
1773
        if (error)
1774
        {
1775
                *err = error;
1776
                return pts2;
1777
        }
1778
        error = FT_Outline_Decompose(&face->glyph->outline, &OutlineMethods, reinterpret_cast<void*>(&pts));
1779
        if (error)
1780
        {
1781
                *err = error;
1782
                return pts2;
1783
        }
87 Franz 1784
        *x = face->glyph->metrics.horiBearingX / 64.0;
1785
        *y = face->glyph->metrics.horiBearingY / 64.0;
8 paul 1786
        QWMatrix ma;
1787
        ma.scale(1, -1);
1788
        pts.map(ma);
1789
        pts.translate(0, chs);
1790
        pts2.putPoints(0, pts.size()-2, pts, 0);
1791
        return pts2;
1792
}
90 Franz 1793
 
95 Franz 1794
FPoint GetMaxClipF(FPointArray Clip)
1795
{
1796
        FPoint np, rp;
1797
        double mx = 0;
1798
        double my = 0;
1799
        for (uint c = 0; c < Clip.size(); ++c)
167 Franz 1800
        {
95 Franz 1801
                np = Clip.point(c);
1802
                if (np.x() > 900000)
1803
                        continue;
1804
                if (np.x() > mx)
1805
                        mx = np.x();
1806
                if (np.y() > my)
1807
                        my = np.y();
167 Franz 1808
        }
95 Franz 1809
        rp = FPoint(mx, my);
1810
        return rp;
1811
}
1812
 
1084 fschmid 1813
QPixmap FontSample(QString da, int s, QString ts, QColor back, bool force)
92 Franz 1814
{
1815
        FT_Face face;
1816
        FT_Library library;
95 Franz 1817
        double x, y, ymax;
92 Franz 1818
        bool error;
1819
        int  pen_x;
95 Franz 1820
        FPoint gp;
92 Franz 1821
        error = FT_Init_FreeType( &library );
1822
        error = FT_New_Face( library, da, 0, &face );
1084 fschmid 1823
        int encode = setBestEncoding(face);
92 Franz 1824
        double uniEM = static_cast<double>(face->units_per_EM);
95 Franz 1825
        int h = qRound(face->height / uniEM) * s + 1;
1826
        double a = static_cast<double>(face->descender) / uniEM * s + 1;
92 Franz 1827
        int w = qRound((face->bbox.xMax - face->bbox.xMin) / uniEM) * s * (ts.length()+1);
1828
        QPixmap pm(w, h);
1829
        pm.fill();
1830
        pen_x = 0;
95 Franz 1831
        ymax = 0.0;
92 Franz 1832
        ScPainter *p = new ScPainter(&pm, pm.width(), pm.height());
1833
        p->setFillMode(1);
1834
        p->setLineWidth(0.0);
1835
        p->setBrush(back);
1836
        p->drawRect(0.0, 0.0, static_cast<double>(w), static_cast<double>(h));
1837
        p->setBrush(Qt::black);
1084 fschmid 1838
        FPointArray gly;
1839
        uint dv;
1840
        dv = ts[0].unicode();
1841
        error = false;
1842
        gly = traceChar(face, dv, s, &x, &y, &error);
1843
        if (((encode != 0) || (error)) && (!force))
167 Franz 1844
        {
221 Franz 1845
                error = false;
1084 fschmid 1846
                FT_ULong  charcode;
1847
                FT_UInt gindex;
1848
                gindex = 0;
1849
                charcode = FT_Get_First_Char(face, &gindex );
1850
                for (uint n = 0; n < ts.length(); ++n)
167 Franz 1851
                {
1084 fschmid 1852
                        gly = traceChar(face, charcode, s, &x, &y, &error);
1853
                        if (error)
1854
                                break;
1855
                        if (gly.size() > 3)
1856
                        {
1857
                                gly.translate(static_cast<double>(pen_x) / 64.0, a);
1858
                                gp = GetMaxClipF(gly);
1859
                                ymax = QMAX(ymax, gp.y());
1860
                                p->setupPolygon(&gly);
1861
                                p->fillPath();
1862
                        }
1863
                        pen_x += face->glyph->advance.x;
1864
                        charcode = FT_Get_Next_Char(face, charcode, &gindex );
1865
                        if (gindex == 0)
1866
                                break;
167 Franz 1867
                }
1868
        }
1084 fschmid 1869
        else
1870
        {
1871
                for (uint n = 0; n < ts.length(); ++n)
1872
                {
1873
                        dv = ts[n].unicode();
1874
                        error = false;
1875
                        gly = traceChar(face, dv, s, &x, &y, &error);
1876
                        if (gly.size() > 3)
1877
                        {
1878
                                gly.translate(static_cast<double>(pen_x) / 64.0, a);
1879
                                gp = GetMaxClipF(gly);
1880
                                ymax = QMAX(ymax, gp.y());
1881
                                p->setupPolygon(&gly);
1882
                                p->fillPath();
1883
                        }
1884
                        pen_x += face->glyph->advance.x;
1885
                }
1886
        }
92 Franz 1887
        p->end();
95 Franz 1888
        pm.resize(QMIN(qRound(gp.x()), w), QMIN(qRound(ymax), h));
92 Franz 1889
        delete p;
1890
        FT_Done_FreeType( library );
1891
        return pm;
1892
}
1893
 
418 Franz 1894
/** Same as FontSample() with \n strings support added.
1895
09/26/2004 petr vanek
1896
*/
1897
QPixmap fontSamples(QString da, int s, QString ts, QColor back)
1898
{
1899
        QStringList lines = QStringList::split("\n", ts);
1900
        QPixmap ret(640, 480);
1901
        QPixmap sample;
1902
        QPainter *painter = new QPainter(&ret);
1903
        int y = 0;
1904
        int x = 0;
1905
        ret.fill(back);
1906
        for ( QStringList::Iterator it = lines.begin(); it != lines.end(); ++it ) {
1907
                sample = FontSample(da, s, *it, back);
1084 fschmid 1908
                if (!sample.isNull())
1909
                        painter->drawPixmap(0, y, sample, 0, 0);
418 Franz 1910
                y = y + sample.height();
1911
                if (x < sample.width())
1912
                        x = sample.width();
1913
        } // for
1914
        delete(painter);
1915
        QPixmap final(x, y);
1084 fschmid 1916
        if ((x != 0) && (y != 0))
1917
        {
1918
                QPainter *fpainter = new QPainter(&final);
1919
                fpainter->drawPixmap(0, 0, ret, 0, 0, x, y);
1920
                delete(fpainter);
1921
        }
418 Franz 1922
        return final;
1923
}
1924
 
90 Franz 1925
/***************************************************************************
1926
    begin                : Wed Oct 29 2003
1927
    copyright            : (C) 2003 The Scribus Team
1928
    email                : paul@all-the-johnsons.co.uk
1929
 ***************************************************************************/
1930
// check if the file exists, if it does, ask if they're sure
1931
// return true if they're sure, else return false;
1932
 
1933
bool overwrite(QWidget *parent, QString filename)
1934
{
167 Franz 1935
        bool retval = true;
1936
        QFileInfo fi(filename);
1937
        if (fi.exists())
90 Franz 1938
        {
167 Franz 1939
        int t = QMessageBox::warning(parent, QObject::tr("Warning"),
1940
                                                QObject::tr("Do you really want to overwrite the File:\n%1 ?").arg(filename),
1941
                        QMessageBox::No, QMessageBox::Yes, QMessageBox::NoButton);
1942
            if (t == QMessageBox::No)
90 Franz 1943
                        retval = false;
1944
        }
1945
  return retval;
1946
}
124 Franz 1947
 
1948
void CopyPageItem(struct CLBuf *Buffer, PageItem *b)
1949
{
1950
        uint a;
1951
        Buffer->PType = b->PType;
1952
        Buffer->Xpos = b->Xpos;
1953
        Buffer->Ypos = b->Ypos;
1954
        Buffer->Width = b->Width;
1955
        Buffer->Height = b->Height;
1956
        Buffer->RadRect = b->RadRect;
1957
        Buffer->FrameType = b->FrameType;
1958
        Buffer->ClipEdited = b->ClipEdited;
1959
        Buffer->Pwidth = b->Pwidth;
1960
        Buffer->Pcolor = b->Pcolor;
1961
        Buffer->Pcolor2 = b->Pcolor2;
1962
        Buffer->Shade = b->Shade;
1963
        Buffer->Shade2 = b->Shade2;
295 Franz 1964
        Buffer->GrColor = "";
1965
        Buffer->GrColor2 = "";
1966
        Buffer->GrShade = 100;
1967
        Buffer->GrShade2 = 100;
1968
        Buffer->fill_gradient = b->fill_gradient;
124 Franz 1969
        Buffer->GrType = b->GrType;
292 Franz 1970
        Buffer->GrStartX = b->GrStartX;
1971
        Buffer->GrStartY = b->GrStartY;
1972
        Buffer->GrEndX = b->GrEndX;
1973
        Buffer->GrEndY = b->GrEndY;
124 Franz 1974
        Buffer->TxtStroke = b->TxtStroke;
1975
        Buffer->TxtFill = b->TxtFill;
1976
        Buffer->ShTxtStroke = b->ShTxtStroke;
1977
        Buffer->ShTxtFill = b->ShTxtFill;
1978
        Buffer->TxtScale = b->TxtScale;
1979
        Buffer->TxTStyle = b->TxTStyle;
1980
        Buffer->Rot = b->Rot;
1981
        Buffer->PLineArt = b->PLineArt;
1982
        Buffer->PLineEnd = b->PLineEnd;
1983
        Buffer->PLineJoin = b->PLineJoin;
1984
        Buffer->LineSp = b->LineSp;
1985
        Buffer->LocalScX = b->LocalScX;
1986
        Buffer->LocalScY = b->LocalScY;
1987
        Buffer->LocalX = b->LocalX;
1988
        Buffer->LocalY = b->LocalY;
1989
        Buffer->PicArt = b->PicArt;
1990
        Buffer->flippedH = b->flippedH;
1991
        Buffer->flippedV = b->flippedV;
1992
        Buffer->BBoxX = b->BBoxX;
1993
        Buffer->BBoxH = b->BBoxH;
1994
        Buffer->isPrintable = b->isPrintable;
1995
        Buffer->isBookmark = b->isBookmark;
1996
        Buffer->BMnr = b->BMnr;
1997
        Buffer->isAnnotation = b->isAnnotation;
1998
        Buffer->AnType = b->AnType;
1999
        Buffer->AnAction = b->AnAction;
2000
        Buffer->An_E_act = b->An_E_act;
2001
        Buffer->An_X_act = b->An_X_act;
2002
        Buffer->An_D_act = b->An_D_act;
2003
        Buffer->An_Fo_act = b->An_Fo_act;
2004
        Buffer->An_Bl_act = b->An_Bl_act;
2005
        Buffer->An_K_act = b->An_K_act;
2006
        Buffer->An_F_act = b->An_F_act;
2007
        Buffer->An_V_act = b->An_V_act;
2008
        Buffer->An_C_act = b->An_C_act;
2009
        Buffer->An_Extern = b->An_Extern;
2010
        Buffer->AnZiel = b->AnZiel;
2011
        Buffer->AnName = b->AnName;
2012
        Buffer->AnActType = b->AnActType;
2013
        Buffer->AnToolTip = b->AnToolTip;
2014
        Buffer->AnBwid = b->AnBwid;
2015
        Buffer->AnBsty = b->AnBsty;
2016
        Buffer->AnFeed = b->AnFeed;
2017
        Buffer->AnFlag = b->AnFlag;
2018
        Buffer->AnFont = b->AnFont;
2019
        Buffer->AnRollOver = b->AnRollOver;
2020
        Buffer->AnDown = b->AnDown;
2021
        Buffer->AnFormat = b->AnFormat;
2022
        Buffer->AnVis = b->AnVis;
2023
        Buffer->AnMaxChar = b->AnMaxChar;
2024
        Buffer->AnChkStil = b->AnChkStil;
2025
        Buffer->AnIsChk = b->AnIsChk;
2026
        Buffer->AnAAact = b->AnAAact;
2027
        Buffer->AnBColor = b->AnBColor;
2028
        Buffer->AnHTML = b->AnHTML;
2029
        Buffer->AnUseIcons = b->AnUseIcons;
2030
        Buffer->AnIPlace = b->AnIPlace;
2031
        Buffer->AnScaleW = b->AnScaleW;
2032
        Buffer->Extra = b->Extra;
2033
        Buffer->TExtra = b->TExtra;
2034
        Buffer->BExtra = b->BExtra;
2035
        Buffer->RExtra = b->RExtra;
2036
        Buffer->Pfile = b->Pfile;
2037
        Buffer->Pfile2 = b->Pfile2;
2038
        Buffer->Pfile3 = b->Pfile3;
2039
        QString Text = "";
2040
        if (b->Ptext.count() != 0)
167 Franz 2041
        {
2042
                for (a=0; a<b->Ptext.count(); ++a)
124 Franz 2043
                {
2044
                        if( (b->Ptext.at(a)->ch == "\n") || (b->Ptext.at(a)->ch == "\r"))
2045
                                Text += QString(QChar(5))+"\t";
157 Franz 2046
                        else if(b->Ptext.at(a)->ch == "\t")
139 Franz 2047
                                Text += QString(QChar(4))+"\t";
124 Franz 2048
                        else
2049
                                Text += b->Ptext.at(a)->ch+"\t";
2050
                        Text += b->Ptext.at(a)->cfont+"\t";
2051
                        Text += QString::number(b->Ptext.at(a)->csize / 10.0)+"\t";
2052
                        Text += b->Ptext.at(a)->ccolor+"\t";
2053
                        Text += QString::number(b->Ptext.at(a)->cextra)+"\t";
2054
                        Text += QString::number(b->Ptext.at(a)->cshade)+'\t';
2055
                        Text += QString::number(b->Ptext.at(a)->cstyle)+'\t';
2056
                        Text += QString::number(b->Ptext.at(a)->cab)+'\t';
2057
                        Text += b->Ptext.at(a)->cstroke+"\t";
2058
                        Text += QString::number(b->Ptext.at(a)->cshade2)+'\t';
2059
                        Text += QString::number(b->Ptext.at(a)->cscale)+'\n';
2060
                }
167 Franz 2061
        }
124 Franz 2062
        Buffer->Ptext = Text;
2063
        Buffer->Clip = b->Clip.copy();
2064
        Buffer->PoLine = b->PoLine.copy();
340 Franz 2065
        Buffer->ContourLine = b->ContourLine.copy();
2066
        Buffer->UseContour = b->UseContour;
139 Franz 2067
        Buffer->TabValues = b->TabValues;
2068
        Buffer->DashValues = b->DashValues;
2069
        Buffer->DashOffset = b->DashOffset;
124 Franz 2070
        Buffer->PoShow = b->PoShow;
2071
        Buffer->BaseOffs = b->BaseOffs;
2072
        Buffer->Textflow = b->Textflow;
2073
        Buffer->Textflow2 = b->Textflow2;
2074
        Buffer->Ausrich = b->Ausrich;
2075
        Buffer->IFont = b->IFont;
2076
        Buffer->ISize = b->ISize;
2077
        Buffer->ExtraV = b->ExtraV;
2078
        Buffer->Groups = b->Groups;
2079
        Buffer->IProfile = b->IProfile;
2080
        Buffer->IRender = b->IRender;
2081
        Buffer->UseEmbedded = b->UseEmbedded;
2082
        Buffer->EmProfile = b->EmProfile;
2083
        Buffer->LayerNr = b->LayerNr;
2084
        Buffer->ScaleType = b->ScaleType;
2085
        Buffer->AspectRatio = b->AspectRatio;
2086
        Buffer->Locked = b->Locked;
205 Franz 2087
        Buffer->LockRes = b->LockRes;
124 Franz 2088
        Buffer->Transparency = b->Transparency;
2089
        Buffer->TranspStroke = b->TranspStroke;
2090
        Buffer->Reverse = b->Reverse;
2091
        Buffer->InvPict = b->InvPict;
2092
        Buffer->NamedLStyle = b->NamedLStyle;
2093
        Buffer->Language = b->Language;
134 Franz 2094
        Buffer->Cols = b->Cols;
135 Franz 2095
        Buffer->ColGap = b->ColGap;
232 Franz 2096
        Buffer->isTableItem = b->isTableItem;
2097
        Buffer->TopLine = b->TopLine;
2098
        Buffer->LeftLine = b->LeftLine;
2099
        Buffer->RightLine = b->RightLine;
2100
        Buffer->BottomLine = b->BottomLine;
234 Franz 2101
        if (b->isTableItem)
2102
        {
2103
                if (b->TopLink != 0)
2104
                        Buffer->TopLinkID = b->TopLink->ItemNr;
2105
                else
2106
                        Buffer->TopLinkID = -1;
2107
                if (b->LeftLink != 0)
2108
                        Buffer->LeftLinkID = b->LeftLink->ItemNr;
2109
                else
2110
                        Buffer->LeftLinkID = -1;
2111
                if (b->RightLink != 0)
2112
                        Buffer->RightLinkID = b->RightLink->ItemNr;
2113
                else
2114
                        Buffer->RightLinkID = -1;
2115
                if (b->BottomLink != 0)
2116
                        Buffer->BottomLinkID = b->BottomLink->ItemNr;
2117
                else
2118
                        Buffer->BottomLinkID = -1;
2119
        }
124 Franz 2120
}
125 Franz 2121
 
2122
void WordAndPara(PageItem* b, int *w, int *p, int *c, int *wN, int *pN, int *cN)
2123
{
2124
        QChar Dat = QChar(32);
2125
        int para = 0;
2126
        int ww = 0;
2127
        int cc = 0;
2128
        int paraN = 0;
2129
        int wwN = 0;
2130
        int ccN = 0;
2131
        bool first = true;
2132
        PageItem *nb = b;
2133
        PageItem *nbl = b;
2134
        while (nb != 0)
167 Franz 2135
        {
125 Franz 2136
                if (nb->BackBox != 0)
2137
                        nb = nb->BackBox;
2138
                else
2139
                        break;
167 Franz 2140
        }
125 Franz 2141
        while (nb != 0)
167 Franz 2142
        {
2143
                for (uint a = 0; a < nb->Ptext.count(); ++a)
125 Franz 2144
                {
2145
                        QChar b = nb->Ptext.at(a)->ch[0];
2146
                        if (b == QChar(13))
167 Franz 2147
                        {
125 Franz 2148
                                if (a >= nb->MaxChars)
2149
                                        paraN++;
2150
                                else
2151
                                        para++;
167 Franz 2152
                        }
125 Franz 2153
                        if ((!b.isLetterOrNumber()) && (Dat.isLetterOrNumber()) && (!first))
167 Franz 2154
                        {
125 Franz 2155
                                if (a >= nb->MaxChars)
2156
                                        wwN++;
2157
                                else
2158
                                        ww++;
167 Franz 2159
                        }
125 Franz 2160
                        if (a >= nb->MaxChars)
2161
                                ccN++;
2162
                        else
2163
                                cc++;
167 Franz 2164
                Dat = b;
125 Franz 2165
                        first = false;
2166
        }
2167
                nbl = nb;
2168
                nb = nb->NextBox;
167 Franz 2169
        }
125 Franz 2170
        if (nbl->MaxChars < nbl->Ptext.count())
2171
                paraN++;
2172
        else
2173
                para++;
2174
        if (Dat.isLetterOrNumber())
167 Franz 2175
        {
125 Franz 2176
                if (nbl->MaxChars < nbl->Ptext.count())
2177
                        wwN++;
2178
                else
2179
                        ww++;
167 Franz 2180
        }
125 Franz 2181
        *w = ww;
2182
        *p = para;
2183
        *c = cc;
2184
        *wN = wwN;
2185
        *pN = paraN;
2186
        *cN = ccN;
2187
}
203 Franz 2188
 
2189
void ReOrderText(ScribusDoc *doc, ScribusView *view)
2190
{
2191
        double savScale = doc->Scale;
2192
        doc->Scale = 1.0;
2193
        doc->RePos = true;
2194
        QPixmap pgPix(10, 10);
2195
        QRect rd = QRect(0,0,9,9);
2196
        ScPainter *painter = new ScPainter