Subversion Repositories Scribus

Rev

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