Subversion Repositories Scribus

Rev

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