Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
13371 jghali 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
7
 
8
#include <QByteArray>
9
#include <QCursor>
10
#include <QDrag>
11
#include <QFile>
12
#include <QList>
13
#include <QMimeData>
14
#include <QRegExp>
15
#include <QStack>
16
#include <QDebug>
17
 
18
#include <cmath>
19
#include <cstdlib>
20
 
21
#include "commonstrings.h"
22
#include "customfdialog.h"
23
#include "importxfig.h"
24
#include "loadsaveplugin.h"
25
#include "missing.h"
26
#include "multiprogressdialog.h"
27
#include "pagesize.h"
28
#include "prefscontext.h"
29
#include "prefsfile.h"
30
#include "prefsmanager.h"
31
#include "prefsmanager.h"
32
#include "prefstable.h"
33
#include "propertiespalette.h"
34
#include "rawimage.h"
13497 jghali 35
#include "scclocale.h"
13371 jghali 36
#include "sccolorengine.h"
37
#include "scconfig.h"
38
#include "scmimedata.h"
39
#include "scpaths.h"
40
#include "scpattern.h"
41
#include "scpattern.h"
42
#include "scribus.h"
43
#include "scribusXml.h"
44
#include "scribuscore.h"
13503 cbradney 45
#include "sctextstream.h"
13371 jghali 46
#include "selection.h"
47
#include "undomanager.h"
48
#include "util.h"
49
#include "util_formats.h"
50
#include "util_icon.h"
51
#include "util_math.h"
52
 
53
extern SCRIBUS_API ScribusQApp * ScQApp;
54
 
55
XfigPlug::XfigPlug(ScribusDoc* doc, int flags)
56
{
57
        tmpSel=new Selection(this, false);
58
        m_Doc=doc;
59
        interactive = (flags & LoadSavePlugin::lfInteractive);
60
}
61
 
62
bool XfigPlug::import(QString fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
63
{
64
        QString fName = fNameIn;
65
        bool success = false;
66
        interactive = (flags & LoadSavePlugin::lfInteractive);
67
        importerFlags = flags;
68
        cancel = false;
69
        double x, y, b, h;
70
        bool ret = false;
71
        CustColors.clear();
72
        importedColors.insert(0, "Black");
73
        importedColors.insert(1, "Blue");
74
        importedColors.insert(2, "Green");
75
        importedColors.insert(3, "Cyan");
76
        importedColors.insert(4, "Red");
77
        importedColors.insert(5, "Magenta");
78
        importedColors.insert(6, "Yellow");
79
        importedColors.insert(7, "White");
80
        importedColors.insert(8, "Blue4");
81
        importedColors.insert(9, "Blue3");
82
        importedColors.insert(10, "Blue2");
83
        importedColors.insert(11, "LtBlue");
84
        importedColors.insert(12, "Green4");
85
        importedColors.insert(13, "Green3");
86
        importedColors.insert(14, "Green2");
87
        importedColors.insert(15, "Cyan4");
88
        importedColors.insert(16, "Cyan3");
89
        importedColors.insert(17, "Cyan2");
90
        importedColors.insert(18, "Red4");
91
        importedColors.insert(19, "Red3");
92
        importedColors.insert(20, "Red2");
93
        importedColors.insert(21, "Magenta4");
94
        importedColors.insert(22, "Magenta3");
95
        importedColors.insert(23, "Magenta2");
96
        importedColors.insert(24, "Brown4");
97
        importedColors.insert(25, "Brown3");
98
        importedColors.insert(26, "Brown2");
99
        importedColors.insert(27, "Pink4");
100
        importedColors.insert(28, "Pink3");
101
        importedColors.insert(29, "Pink2");
102
        importedColors.insert(30, "Pink");
103
        importedColors.insert(31, "Gold");
104
        CustColors.insert("Blue", ScColor(255, 0, 0, 0));
105
        CustColors.insert("Blue4", ScColor(0, 0, 144));
106
        CustColors.insert("Blue3", ScColor(0, 0, 176));
107
        CustColors.insert("Blue2", ScColor(0, 0, 208));
108
        CustColors.insert("LtBlue", ScColor(135, 206, 255));
109
        CustColors.insert("Cyan", ScColor(255, 0, 0, 0));
110
        CustColors.insert("Cyan4", ScColor(0, 144, 144));
111
        CustColors.insert("Cyan3", ScColor(0, 176, 176));
112
        CustColors.insert("Cyan2", ScColor(0, 208, 208));
113
        CustColors.insert("Green", ScColor(255, 0, 255, 0));
114
        CustColors.insert("Green4", ScColor(0, 144, 0));
115
        CustColors.insert("Green3", ScColor(0, 176, 0));
116
        CustColors.insert("Green2", ScColor(0, 208, 0));
117
        CustColors.insert("Red", ScColor(0, 255, 255, 0));
118
        CustColors.insert("Red4", ScColor(144, 0, 0));
119
        CustColors.insert("Red3", ScColor(176, 0, 0));
120
        CustColors.insert("Red2", ScColor(208, 0, 0));
121
        CustColors.insert("Yellow", ScColor(0, 0, 255, 0));
122
        CustColors.insert("Magenta", ScColor(0, 255, 0, 0));
123
        CustColors.insert("Magenta4", ScColor(144, 0, 144));
124
        CustColors.insert("Magenta3", ScColor(176, 0, 176));
125
        CustColors.insert("Magenta2", ScColor(208, 0, 208));
126
        CustColors.insert("Brown4", ScColor(128, 48, 0));
127
        CustColors.insert("Brown3", ScColor(160, 64, 0));
128
        CustColors.insert("Brown2", ScColor(192, 96, 0));
129
        CustColors.insert("Pink4", ScColor(255, 128, 128));
130
        CustColors.insert("Pink3", ScColor(255, 160, 160));
131
        CustColors.insert("Pink2", ScColor(255, 192, 192));
132
        CustColors.insert("Pink", ScColor(255, 224, 224));
133
        CustColors.insert("Gold", ScColor(255, 215, 0));
134
        QFileInfo fi = QFileInfo(fName);
135
        if ( !ScCore->usingGUI() )
136
        {
137
                interactive = false;
138
                showProgress = false;
139
        }
140
        baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
141
        if ( showProgress )
142
        {
143
                ScribusMainWindow* mw=(m_Doc==0) ? ScCore->primaryMainWindow() : m_Doc->scMW();
144
                progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
145
                QStringList barNames, barTexts;
146
                barNames << "GI";
147
                barTexts << tr("Analyzing File:");
148
                QList<bool> barsNumeric;
149
                barsNumeric << false;
150
                progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
151
                progressDialog->setOverallTotalSteps(3);
152
                progressDialog->setOverallProgress(0);
153
                progressDialog->setProgress("GI", 0);
154
                progressDialog->show();
155
                connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
156
                qApp->processEvents();
157
        }
158
        else
159
                progressDialog = NULL;
160
/* Set default Page to size defined in Preferences */
161
        x = 0.0;
162
        y = 0.0;
163
        b = 0.0;
164
        h = 0.0;
165
        if (progressDialog)
166
        {
167
                progressDialog->setOverallProgress(1);
168
                qApp->processEvents();
169
        }
170
        parseHeader(fName, x, y, b, h);
171
        docX = x;
172
        docY = y;
173
        if (b == 0.0)
174
                b = PrefsManager::instance()->appPrefs.PageWidth;
175
        if (h == 0.0)
176
                h = PrefsManager::instance()->appPrefs.PageHeight;
177
        docWidth = b - x;
178
        docHeight = h - y;
179
        baseX = 0;
180
        baseY = 0;
181
        if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
182
        {
183
                m_Doc->setPage(b-x, h-y, 0, 0, 0, 0, 0, 0, false, false);
184
                m_Doc->addPage(0);
185
                m_Doc->view()->addPage(0, true);
186
                baseX = 0;
187
                baseY = 0;
188
        }
189
        else
190
        {
191
                if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
192
                {
193
                        m_Doc=ScCore->primaryMainWindow()->doFileNew(b-x, h-y, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
194
                        ScCore->primaryMainWindow()->HaveNewDoc();
195
                        ret = true;
196
                        baseX = 0;
197
                        baseY = 0;
198
                }
199
        }
200
        if (flags & LoadSavePlugin::lfCreateDoc)
201
        {
202
                m_Doc->documentInfo.setAuthor(docCreator);
203
                m_Doc->documentInfo.setPublisher(docOrganisation);
204
                m_Doc->documentInfo.setTitle(docTitle);
205
                m_Doc->documentInfo.setDate(docDate+" "+docTime);
206
        }
207
        if ((!ret) && (interactive))
208
        {
209
                baseX = m_Doc->currentPage()->xOffset();
210
                baseY = m_Doc->currentPage()->yOffset();
211
        }
212
        if ((ret) || (!interactive))
213
        {
214
                if (b-x > h-y)
215
                        m_Doc->PageOri = 1;
216
                else
217
                        m_Doc->PageOri = 0;
218
                m_Doc->m_pageSize = "Custom";
219
        }
220
        Elements.clear();
221
        FPoint minSize = m_Doc->minCanvasCoordinate;
222
        FPoint maxSize = m_Doc->maxCanvasCoordinate;
223
        FPoint cOrigin = m_Doc->view()->canvasOrigin();
224
        m_Doc->setLoading(true);
225
        m_Doc->DoDrawing = false;
226
        m_Doc->view()->updatesOn(false);
14751 fschmid 227
        bool wasScriptRunning = m_Doc->scMW()->ScriptRunning;
13371 jghali 228
        m_Doc->scMW()->ScriptRunning = true;
229
        qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
230
        QString CurDirP = QDir::currentPath();
231
        QDir::setCurrent(fi.path());
232
        if (convert(fName))
233
        {
234
                tmpSel->clear();
235
                QDir::setCurrent(CurDirP);
236
                if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
237
                {
238
                        bool isGroup = true;
239
                        int firstElem = -1;
240
                        if (Elements.at(0)->Groups.count() != 0)
241
                                firstElem = Elements.at(0)->Groups.top();
242
                        for (int bx = 0; bx < Elements.count(); ++bx)
243
                        {
244
                                PageItem* bxi = Elements.at(bx);
245
                                if (bxi->Groups.count() != 0)
246
                                {
247
                                        if (bxi->Groups.top() != firstElem)
248
                                                isGroup = false;
249
                                }
250
                                else
251
                                        isGroup = false;
252
                        }
253
                        if (!isGroup)
254
                        {
255
                                double minx = 99999.9;
256
                                double miny = 99999.9;
257
                                double maxx = -99999.9;
258
                                double maxy = -99999.9;
259
                                uint lowestItem = 999999;
260
                                uint highestItem = 0;
261
                                for (int a = 0; a < Elements.count(); ++a)
262
                                {
263
                                        Elements.at(a)->Groups.push(m_Doc->GroupCounter);
264
                                        PageItem* currItem = Elements.at(a);
265
                                        lowestItem = qMin(lowestItem, currItem->ItemNr);
266
                                        highestItem = qMax(highestItem, currItem->ItemNr);
267
                                        double x1, x2, y1, y2;
268
                                        currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
269
                                        minx = qMin(minx, x1);
270
                                        miny = qMin(miny, y1);
271
                                        maxx = qMax(maxx, x2);
272
                                        maxy = qMax(maxy, y2);
273
                                }
274
                                double gx = minx;
275
                                double gy = miny;
276
                                double gw = maxx - minx;
277
                                double gh = maxy - miny;
278
                                PageItem *high = m_Doc->Items->at(highestItem);
279
                                int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, gx, gy, gw, gh, 0, m_Doc->toolSettings.dBrush, m_Doc->toolSettings.dPen, true);
280
                                PageItem *neu = m_Doc->Items->takeAt(z);
281
                                m_Doc->Items->insert(lowestItem, neu);
282
                                neu->Groups.push(m_Doc->GroupCounter);
283
                                neu->setItemName( tr("Group%1").arg(neu->Groups.top()));
284
                                neu->AutoName = false;
285
                                neu->isGroupControl = true;
286
                                neu->groupsLastItem = high;
287
                                neu->setTextFlowMode(PageItem::TextFlowDisabled);
288
                                for (int a = 0; a < m_Doc->Items->count(); ++a)
289
                                {
290
                                        m_Doc->Items->at(a)->ItemNr = a;
291
                                }
292
                                Elements.prepend(neu);
293
                                m_Doc->GroupCounter++;
294
                        }
295
                }
296
                m_Doc->DoDrawing = true;
14751 fschmid 297
                m_Doc->scMW()->ScriptRunning = wasScriptRunning;
13371 jghali 298
                m_Doc->setLoading(false);
299
                qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
300
                if ((Elements.count() > 0) && (!ret) && (interactive))
301
                {
302
                        if (flags & LoadSavePlugin::lfScripted)
303
                        {
304
                                bool loadF = m_Doc->isLoading();
305
                                m_Doc->setLoading(false);
306
                                m_Doc->changed();
307
                                m_Doc->setLoading(loadF);
308
                                m_Doc->m_Selection->delaySignalsOn();
309
                                for (int dre=0; dre<Elements.count(); ++dre)
310
                                {
311
                                        m_Doc->m_Selection->addItem(Elements.at(dre), true);
312
                                }
313
                                m_Doc->m_Selection->delaySignalsOff();
314
                                m_Doc->m_Selection->setGroupRect();
315
                                m_Doc->view()->updatesOn(true);
316
                        }
317
                        else
318
                        {
319
                                m_Doc->DragP = true;
320
                                m_Doc->DraggedElem = 0;
321
                                m_Doc->DragElements.clear();
322
                                m_Doc->m_Selection->delaySignalsOn();
323
                                for (int dre=0; dre<Elements.count(); ++dre)
324
                                {
325
                                        m_Doc->DragElements.append(Elements.at(dre)->ItemNr);
326
                                        tmpSel->addItem(Elements.at(dre), true);
327
                                }
328
                                tmpSel->setGroupRect();
329
                                ScriXmlDoc *ss = new ScriXmlDoc();
330
                                ScElemMimeData* md = new ScElemMimeData();
331
                                md->setScribusElem(ss->WriteElem(m_Doc, m_Doc->view(), tmpSel));
332
                                delete ss;
333
/*#ifndef Q_WS_MAC*/
334
// see #2196
335
                                m_Doc->itemSelection_DeleteItem(tmpSel);
336
/*#else
337
                                qDebug("xfigimport: leaving items on page");
338
#endif*/
339
                                m_Doc->view()->updatesOn(true);
340
                                m_Doc->m_Selection->delaySignalsOff();
341
                                // We must copy the TransationSettings object as it is owned
342
                                // by handleObjectImport method afterwards
343
                                TransactionSettings* transacSettings = new TransactionSettings(trSettings);
344
                                m_Doc->view()->handleObjectImport(md, transacSettings);
345
                                m_Doc->DragP = false;
346
                                m_Doc->DraggedElem = 0;
347
                                m_Doc->DragElements.clear();
348
                        }
349
                }
350
                else
351
                {
352
                        m_Doc->changed();
353
                        m_Doc->reformPages();
354
                        m_Doc->view()->updatesOn(true);
355
                }
356
                success = true;
357
        }
358
        else
359
        {
360
                QDir::setCurrent(CurDirP);
361
                m_Doc->DoDrawing = true;
14751 fschmid 362
                m_Doc->scMW()->ScriptRunning = wasScriptRunning;
13371 jghali 363
                m_Doc->view()->updatesOn(true);
364
                qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
365
        }
366
        if (interactive)
367
                m_Doc->setLoading(false);
368
        //CB If we have a gui we must refresh it if we have used the progressbar
369
        if ((showProgress) && (!interactive))
370
                m_Doc->view()->DrawNew();
371
        return success;
372
}
373
 
374
XfigPlug::~XfigPlug()
375
{
376
        if (progressDialog)
377
                delete progressDialog;
378
        delete tmpSel;
379
}
380
 
381
bool XfigPlug::parseHeader(QString fName, double &x, double &y, double &b, double &h)
382
{
383
        QString tmp, BBox, tmp2, FarNam;
384
        ScColor cc;
385
        bool found = false;
386
        QFile f(fName);
387
        if (f.open(QIODevice::ReadOnly))
388
        {
389
                QDataStream ts(&f);
390
                QString version = readLinefromDataStream(ts);
391
                if (!version.startsWith("#FIG 3"))
392
                {
393
                        f.close();
394
                        return false;
395
                }
396
                QString orientation = readLinefromDataStream(ts);
397
                QString justification = readLinefromDataStream(ts);
398
                QString units = readLinefromDataStream(ts);
399
                QString papersize = readLinefromDataStream(ts);
400
                PageSize ps(papersize);
401
                if (orientation.startsWith("Landscape"))
402
                {
403
                        h = ps.width();
404
                        b = ps.height();
405
                }
406
                else
407
                {
408
                        b = ps.width();
409
                        h = ps.height();
410
                }
411
                f.close();
412
                found = true;
413
        }
414
        return found;
415
}
416
 
417
void XfigPlug::parseColor(QString data)
418
{
419
        if (data.isEmpty())
420
                return;
421
        int colorNum, dummy;
422
        QString colorValues;
423
        ScColor tmp;
13497 jghali 424
        ScTextStream Code(&data, QIODevice::ReadOnly);
13371 jghali 425
        Code >> dummy >> colorNum >> colorValues;
426
        tmp.setNamedColor(colorValues);
427
        tmp.setSpotColor(false);
428
        tmp.setRegistrationColor(false);
429
        QString namPrefix = "FromXfig%1-"+colorValues;
430
        CustColors.insert(namPrefix.arg(colorNum), tmp);
431
        importedColors.insert(colorNum, namPrefix.arg(colorNum));
432
}
433
 
434
void XfigPlug::useColor(int colorNum, int area_fill, bool forFill)
435
{
436
        QString color = CommonStrings::None;
437
        int shade = 100;
438
        if (forFill)
439
        {
440
                if (area_fill == -1)
441
                        color = CommonStrings::None;
442
                else
443
                {
444
                        if ((colorNum == -1) || (colorNum == 0))
445
                        {
446
                                if (area_fill == 0)
447
                                {
448
                                        color = "White";
449
                                        shade = 100;
450
                                }
451
                                else if (area_fill == 20)
452
                                {
453
                                        color = "Black";
454
                                        shade = 100;
455
                                }
456
                                else if ((area_fill > 0) && (area_fill < 20))
457
                                {
458
                                        color = "Black";
459
                                        shade = qRound(100.0 / 19.0 * area_fill);
460
                                }
461
                        }
462
                        else if (colorNum == 7)
463
                        {
464
                                if (area_fill == 0)
465
                                {
466
                                        color = "Black";
467
                                        shade = 100;
468
                                }
469
                                else if (area_fill == 20)
470
                                {
471
                                        color = "White";
472
                                        shade = 100;
473
                                }
474
                                else if ((area_fill > 0) && (area_fill < 20))
475
                                {
476
                                        color = "Black";
477
                                        shade = qRound(100.0 / 19.0 * (20 - area_fill));
478
                                }
479
                        }
480
                        else
481
                        {
482
                                if (importedColors.contains(colorNum))
483
                                {
484
                                        color = importedColors[colorNum];
485
                                        if (!m_Doc->PageColors.contains(color))
486
                                                m_Doc->PageColors.insert(color, CustColors[color]);
487
                                        int sat = area_fill - 20;
488
                                        if ((sat > 0) && (sat < 20))
489
                                                shade = qRound(100.0 / 19.0 * sat);
490
                                }
491
                                else
492
                                        color = CommonStrings::None;
493
                        }
494
                }
495
                CurrColorFill = color;
496
                CurrFillShade = shade;
497
        }
498
        else
499
        {
500
                if (area_fill == -1)
501
                        CurrColorStroke = CommonStrings::None;
502
                else
503
                {
504
                        if ((colorNum == -1) || (colorNum == 0))
505
                                CurrColorStroke = "Black";
506
                        else
507
                        {
508
                                if (importedColors.contains(colorNum))
509
                                {
510
                                        CurrColorStroke = importedColors[colorNum];
511
                                        if (!m_Doc->PageColors.contains(CurrColorStroke))
512
                                                m_Doc->PageColors.insert(CurrColorStroke, CustColors[CurrColorStroke]);
513
                                }
514
                                else
515
                                        CurrColorStroke = CommonStrings::None;
516
                        }
517
                }
518
        }
519
}
520
 
521
QVector<double> XfigPlug::getDashValues(double linewidth, int code)
522
{
523
        QVector<double> tmp;
524
        if (code == 1)
525
        {
526
                tmp << qMax(4.0 * linewidth, 0.1);
527
                tmp << qMax(2.0 * linewidth, 0.1);
528
        }
529
        else if (code == 2)
530
        {
531
                tmp << qMax(1.0 * linewidth, 0.1);
532
                tmp << qMax(2.0 * linewidth, 0.1);
533
        }
534
        else if (code == 3)
535
        {
536
                tmp << qMax(4.0 * linewidth, 0.1);
537
                tmp << qMax(2.0 * linewidth, 0.1);
538
                tmp << qMax(1.0 * linewidth, 0.1);
539
                tmp << qMax(2.0 * linewidth, 0.1);
540
        }
541
        else if (code == 4)
542
        {
543
                tmp << qMax(4.0 * linewidth, 0.1);
544
                tmp << qMax(2.0 * linewidth, 0.1);
545
                tmp << qMax(1.0 * linewidth, 0.1);
546
                tmp << qMax(2.0 * linewidth, 0.1);
547
                tmp << qMax(1.0 * linewidth, 0.1);
548
                tmp << qMax(2.0 * linewidth, 0.1);
549
        }
550
        else if (code == 5)
551
        {
552
                tmp << qMax(4.0 * linewidth, 0.1);
553
                tmp << qMax(2.0 * linewidth, 0.1);
554
                tmp << qMax(1.0 * linewidth, 0.1);
555
                tmp << qMax(2.0 * linewidth, 0.1);
556
                tmp << qMax(1.0 * linewidth, 0.1);
557
                tmp << qMax(2.0 * linewidth, 0.1);
558
                tmp << qMax(1.0 * linewidth, 0.1);
559
                tmp << qMax(2.0 * linewidth, 0.1);
560
        }
561
        return tmp;
562
}
563
 
564
void XfigPlug::processArrows(int forward_arrow, QString fArrowData, int backward_arrow, QString bArrowData, int depth, PageItem *ite)
565
{
566
        int             arrow_typeAF;                   // (enumeration type)
567
        int             arrow_styleAF;                  // (enumeration type)
568
        float   arrow_thicknessAF;              // (1/80 inch)
569
        float   arrow_widthAF;                  // (Fig units)
570
        float   arrow_heightAF;                 // (Fig units)
571
        int             arrow_typeAB;                   // (enumeration type)
572
        int             arrow_styleAB;                  // (enumeration type)
573
        float   arrow_thicknessAB;              // (1/80 inch)
574
        float   arrow_widthAB;                  // (Fig units)
575
        float   arrow_heightAB;                 // (Fig units)
576
        FPointArray arrow;
577
        int z = -1;
578
        PageItem::ItemType iteType;
579
        if (forward_arrow == 1)
580
        {
581
                arrow.resize(0);
13497 jghali 582
                ScTextStream CodeAF(&fArrowData, QIODevice::ReadOnly);
13371 jghali 583
                CodeAF >> arrow_typeAF >> arrow_styleAF >> arrow_thicknessAF >> arrow_widthAF >> arrow_heightAF;
584
                arrow_widthAF = fig2Pts(arrow_widthAF);
585
                arrow_heightAF = fig2Pts(arrow_heightAF);
586
                arrow_thicknessAF = arrow_thicknessAF / 80.0 * 72.0;
587
                FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
588
                for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
589
                {
590
                        FPoint Vector = ite->PoLine.point(xx);
591
                        if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
592
                        {
593
                                double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
594
                                QMatrix arrowTrans;
595
                                if (arrow_typeAF == 0)
596
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5");
597
                                else if (arrow_typeAF == 1)
598
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5 z");
599
                                else if (arrow_typeAF == 2)
600
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5 L -0.7 0 z");
601
                                else if (arrow_typeAF == 3)
602
                                        arrow.parseSVG("M -0.7, -0.5 L 0, 0 L -0.7, 0.5 L -1 0 z");
603
                                arrowTrans.translate(End.x(), End.y());
604
                                arrowTrans.rotate(r);
605
                                arrowTrans.scale(arrow_heightAF, arrow_widthAF);
606
                                arrow.map(arrowTrans);
607
                                break;
608
                        }
609
                }
610
                QString fillC = "White";
611
                if (arrow_styleAF == 1)
612
                        fillC = CurrColorStroke;
613
                if (arrow_typeAF == 0)
614
                {
615
                        fillC = CommonStrings::None;
616
                        iteType = PageItem::PolyLine;
617
                }
618
                else
619
                        iteType = PageItem::Polygon;
620
                z = m_Doc->itemAdd(iteType, PageItem::Unspecified, ite->xPos(), ite->yPos(), 10, 10, arrow_thicknessAF, fillC, CurrColorStroke, true);
621
                if (z >= 0)
622
                {
623
                        PageItem *item = m_Doc->Items->at(z);
624
                        item->PoLine = arrow.copy();
625
                        item->ClipEdited = true;
626
                        item->FrameType = 3;
627
                        item->setFillShade(CurrFillShade);
628
                        item->setLineShade(CurrStrokeShade);
629
                        FPoint wh = getMaxClipF(&item->PoLine);
630
                        item->setWidthHeight(wh.x(),wh.y());
631
                        item->setTextFlowMode(PageItem::TextFlowDisabled);
632
                        m_Doc->AdjustItemSize(item);
633
                        item->setWidthHeight(qMax(item->width(), 1.0), qMax(item->height(), 1.0));
634
                        depthMap.insert(999 - depth, currentItemNr);
635
                        currentItemNr++;
636
                }
637
        }
638
        if (backward_arrow == 1)
639
        {
640
                arrow.resize(0);
13497 jghali 641
                ScTextStream CodeAB(&bArrowData, QIODevice::ReadOnly);
13371 jghali 642
                CodeAB >> arrow_typeAB >> arrow_styleAB >> arrow_thicknessAB >> arrow_widthAB >> arrow_heightAB;
643
                arrow_widthAB = fig2Pts(arrow_widthAB);
644
                arrow_heightAB = fig2Pts(arrow_heightAB);
645
                arrow_thicknessAB = arrow_thicknessAB / 80.0 * 72.0;
646
                FPointArray arrow;
647
                FPoint Start = ite->PoLine.point(0);
648
                for (uint xx = 1; xx < ite->PoLine.size(); xx += 2)
649
                {
650
                        FPoint Vector = ite->PoLine.point(xx);
651
                        if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
652
                        {
653
                                double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
654
                                QMatrix arrowTrans;
655
                                if (arrow_typeAB == 0)
656
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5");
657
                                else if (arrow_typeAB == 1)
658
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5 z");
659
                                else if (arrow_typeAB == 2)
660
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5 L -0.7 0 z");
661
                                else if (arrow_typeAB == 3)
662
                                        arrow.parseSVG("M -0.7, -0.5 L 0, 0 L -0.7, 0.5 L -1 0 z");
663
                                arrowTrans.translate(Start.x(), Start.y());
664
                                arrowTrans.rotate(r);
665
                                arrowTrans.scale(arrow_heightAB, arrow_widthAB);
666
                                arrow.map(arrowTrans);
667
                                break;
668
                        }
669
                }
670
                QString fillC = "White";
671
                if (arrow_styleAB == 1)
672
                        fillC = CurrColorStroke;
673
                if (arrow_typeAB == 0)
674
                {
675
                        fillC = CommonStrings::None;
676
                        iteType = PageItem::PolyLine;
677
                }
678
                else
679
                        iteType = PageItem::Polygon;
680
                z = m_Doc->itemAdd(iteType, PageItem::Unspecified, ite->xPos(), ite->yPos(), 10, 10, arrow_thicknessAB, fillC, CurrColorStroke, true);
681
                if (z >= 0)
682
                {
683
                        PageItem *item = m_Doc->Items->at(z);
684
                        item->PoLine = arrow.copy();
685
                        item->ClipEdited = true;
686
                        item->FrameType = 3;
687
                        item->setFillShade(CurrFillShade);
688
                        item->setLineShade(CurrStrokeShade);
689
                        FPoint wh = getMaxClipF(&item->PoLine);
690
                        item->setWidthHeight(wh.x(),wh.y());
691
                        item->setTextFlowMode(PageItem::TextFlowDisabled);
692
                        m_Doc->AdjustItemSize(item);
693
                        item->setWidthHeight(qMax(item->width(), 1.0), qMax(item->height(), 1.0));
694
                        depthMap.insert(999 - depth, currentItemNr);
695
                        currentItemNr++;
696
                }
697
        }
698
}
699
 
700
void XfigPlug::processPolyline(QDataStream &ts, QString data)
701
{
702
        QString tmp = data;
703
        QString fArrowData = "";
704
        QString bArrowData = "";
705
        int             command;
706
        int             subtype;                                // (1: polyline, 2: box, 3: polygon, 4: arc-box, 5: imported-picture bounding-box)
707
        int             line_style;                             // (enumeration type)
708
        int             thickness;                              // (1/80 inch)
709
        int             pen_color;                              // (enumeration type, pen color)
710
        int             fill_color;                             // (enumeration type, fill color)
711
        int             depth;                                  // (enumeration type)
712
        int             pen_style;                              // (pen style, not used)
713
        int             area_fill;                              // (enumeration type, -1 = no fill)
714
        double  style_val;                              // (1/80 inch)
715
        int             join_style;                     // (enumeration type)
716
        int             cap_style;                              // (enumeration type, only used for POLYLINE)
717
        int             radius;                                 // (1/80 inch, radius of arc-boxes)
718
        int             forward_arrow;                  // (0: off, 1: on)
719
        int             backward_arrow;                 // (0: off, 1: on)
720
        int             npoints;                                // (number of points in line)
721
        int pointsRead = 0;
722
        int imgFlipped;
723
        QString imgFile;
724
        double x, y;
725
        Coords.resize(0);
726
        Coords.svgInit();
727
        bool first = true;
13497 jghali 728
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
13371 jghali 729
        Code >> command >> subtype >> line_style >> thickness >> pen_color >> fill_color >> depth >> pen_style;
730
        Code >> area_fill >> style_val >> join_style >> cap_style >> radius >> forward_arrow >> backward_arrow >> npoints;
731
        if (forward_arrow == 1)
732
                fArrowData = readLinefromDataStream(ts);
733
        if (backward_arrow == 1)
734
                bArrowData = readLinefromDataStream(ts);
735
        if (subtype == 5)
736
        {
737
                tmp = readLinefromDataStream(ts);
13497 jghali 738
                ScTextStream imf(&tmp, QIODevice::ReadOnly);
13371 jghali 739
                imf >> imgFlipped >> imgFile;
740
        }
741
        while (!ts.atEnd())
742
        {
743
                tmp = readLinefromDataStream(ts);
13497 jghali 744
                ScTextStream pts(&tmp, QIODevice::ReadOnly);
13371 jghali 745
                while (!pts.atEnd())
746
                {
747
                        pts >> x >> y;
748
                        x = fig2Pts(x) - docX;
749
                        y = fig2Pts(y) - docY;
750
                        if (first)
751
                        {
752
                                Coords.svgMoveTo(x, y);
753
                                first = false;
754
                        }
755
                        else
756
                                Coords.svgLineTo(x, y);
757
                        pointsRead++;
758
                }
759
                if (pointsRead == npoints)
760
                {
761
                        if (npoints == 1)
762
                                Coords.svgLineTo(x, y);
763
                        break;
764
                }
765
        }
766
        useColor(pen_color, 0, false);
767
        useColor(fill_color, area_fill, true);
768
        LineW = thickness / 80.0 * 72.0;
769
        int z = -1;
770
        PageItem *ite;
771
        if (subtype == 1)
772
                z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
773
        else if ((subtype == 2) || (subtype == 3) || (subtype == 4))
774
        {
775
                z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
776
                Coords.svgClosePath();
777
        }
778
        else if (subtype == 5)
779
        {
780
                z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
781
                Coords.svgClosePath();
782
        }
783
        else
784
                z = -1;
785
        if (z >= 0)
786
        {
787
                ite = m_Doc->Items->at(z);
788
                ite->PoLine = Coords.copy();
789
                ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
790
                ite->ClipEdited = true;
791
                ite->FrameType = 3;
792
                ite->setFillShade(CurrFillShade);
793
                ite->setLineShade(CurrStrokeShade);
794
                if (line_style > 0)
795
                        ite->setDashes(getDashValues(LineW, line_style));
796
                if (subtype == 1)
797
                {
798
                        if (join_style == 0)
799
                                ite->setLineJoin(Qt::MiterJoin);
800
                        else if (join_style == 1)
801
                                ite->setLineJoin(Qt::RoundJoin);
802
                        else if (join_style == 2)
803
                                ite->setLineJoin(Qt::BevelJoin);
804
                        if (cap_style == 0)
805
                                ite->setLineEnd(Qt::FlatCap);
806
                        else if (cap_style == 1)
807
                                ite->setLineEnd(Qt::RoundCap);
808
                        else if (cap_style == 2)
809
                                ite->setLineEnd(Qt::SquareCap);
810
                }
811
                FPoint wh = getMaxClipF(&ite->PoLine);
812
                ite->setWidthHeight(wh.x(),wh.y());
813
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
814
                m_Doc->AdjustItemSize(ite);
815
                ite->setWidthHeight(qMax(ite->width(), 1.0), qMax(ite->height(), 1.0));
816
                if (subtype == 4)
817
                {
818
                        ite->setCornerRadius(radius / 80.0 * 72.0);
819
                        ite->FrameType = 2;
820
                        ite->ClipEdited = false;
821
                        ite->updateClip();
822
                }
823
                if (subtype == 5)
824
                {
825
                        ite->Pfile = baseFile + "/" + imgFile;
826
                        m_Doc->loadPict(ite->Pfile, ite, false);
827
                        ite->setImageXYScale(72.0 / 80.0, 72.0 / 80.0);
828
                        ite->setImageXYOffset(0, 0);
829
                }
830
                depthMap.insert(999 - depth, currentItemNr);
831
                currentItemNr++;
832
                if ((ite->itemType() == PageItem::PolyLine) && ((forward_arrow == 1) || (backward_arrow == 1)))
833
                        processArrows(forward_arrow, fArrowData, backward_arrow, bArrowData, depth, ite);
834
        }
835
}
836
 
837
void XfigPlug::processSpline(QDataStream &ts, QString data)
838
{
839
        QString tmp = data;
840
        QString fArrowData = "";
841
        QString bArrowData = "";
842
        int             command;
843
        int             subtype;                                // 0: open approximated spline
844
                                                                        // 1: closed approximated spline
845
                                                                        // 2: open   interpolated spline
846
                                                                        // 3: closed interpolated spline
847
                                                                        // 4: open   x-spline 
848
                                                                        // 5: closed x-spline
849
        int             line_style;                             // (enumeration type)
850
        int             thickness;                              // (1/80 inch)
851
        int             pen_color;                              // (enumeration type, pen color)
852
        int             fill_color;                             // (enumeration type, fill color)
853
        int             depth;                                  // (enumeration type)
854
        int             pen_style;                              // (pen style, not used)
855
        int             area_fill;                              // (enumeration type, -1 = no fill)
856
        double  style_val;                              // (1/80 inch)
857
        int             cap_style;                              // (enumeration type, only used for POLYLINE)
858
        int             forward_arrow;                  // (0: off, 1: on)
859
        int             backward_arrow;                 // (0: off, 1: on)
860
        int             npoints;                                // (number of points in line)
861
        int pointsRead = 0;
862
        double x, y;
863
        Coords.resize(0);
864
        Coords.svgInit();
865
        bool first = true;
13497 jghali 866
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
13371 jghali 867
        Code >> command >> subtype >> line_style >> thickness >> pen_color >> fill_color >> depth >> pen_style;
868
        Code >> area_fill >> style_val >> cap_style >> forward_arrow >> backward_arrow >> npoints;
869
        if (forward_arrow == 1)
870
                fArrowData = readLinefromDataStream(ts);
871
        if (backward_arrow == 1)
872
                bArrowData = readLinefromDataStream(ts);
873
        while (!ts.atEnd())
874
        {
875
                tmp = readLinefromDataStream(ts);
13497 jghali 876
                ScTextStream pts(&tmp, QIODevice::ReadOnly);
13371 jghali 877
                while (!pts.atEnd())
878
                {
879
                        pts >> x >> y;
880
                        x = fig2Pts(x) - docX;
881
                        y = fig2Pts(y) - docY;
882
                        if (first)
883
                        {
884
                                Coords.svgMoveTo(x, y);
885
                                first = false;
886
                        }
887
                        else
888
                                Coords.svgLineTo(x, y);
889
                        pointsRead++;
890
                }
891
                if (pointsRead == npoints)
892
                {
893
                        if (npoints == 1)
894
                                Coords.svgLineTo(x, y);
895
                        break;
896
                }
897
        }
898
        pointsRead = 0;
899
        while (!ts.atEnd())
900
        {
901
                tmp = readLinefromDataStream(ts);
13497 jghali 902
                ScTextStream pts(&tmp, QIODevice::ReadOnly);
13371 jghali 903
                while (!pts.atEnd())
904
                {
905
                        pts >> x;
906
                        pointsRead++;
907
                }
908
                if (pointsRead == npoints)
909
                        break;
910
        }
911
        useColor(pen_color, 0, false);
912
        useColor(fill_color, area_fill, true);
913
        LineW = thickness / 80.0 * 72.0;
914
        int z = -1;
915
        PageItem *ite;
916
        if ((subtype == 0) || (subtype == 2) || (subtype == 4))
917
                z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
918
        else if ((subtype == 1) || (subtype == 3) || (subtype == 5))
919
        {
920
                z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
921
                Coords.svgClosePath();
922
        }
923
        if (z >= 0)
924
        {
925
                ite = m_Doc->Items->at(z);
926
                ite->PoLine = Coords.copy();
927
                ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
928
                ite->ClipEdited = true;
929
                ite->FrameType = 3;
930
                ite->setFillShade(CurrFillShade);
931
                ite->setLineShade(CurrStrokeShade);
932
                if (line_style > 0)
933
                        ite->setDashes(getDashValues(LineW, line_style));
934
                if ((subtype == 0) || (subtype == 2) || (subtype == 4))
935
                {
936
                        if (cap_style == 0)
937
                                ite->setLineEnd(Qt::FlatCap);
938
                        else if (cap_style == 1)
939
                                ite->setLineEnd(Qt::RoundCap);
940
                        else if (cap_style == 2)
941
                                ite->setLineEnd(Qt::SquareCap);
942
                }
943
                FPoint wh = getMaxClipF(&ite->PoLine);
944
                ite->setWidthHeight(wh.x(),wh.y());
945
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
946
                m_Doc->AdjustItemSize(ite);
947
                ite->setWidthHeight(qMax(ite->width(), 1.0), qMax(ite->height(), 1.0));
948
                depthMap.insert(999 - depth, currentItemNr);
949
                currentItemNr++;
950
                if ((ite->itemType() == PageItem::PolyLine) && ((forward_arrow == 1) || (backward_arrow == 1)))
951
                        processArrows(forward_arrow, fArrowData, backward_arrow, bArrowData, depth, ite);
952
        }
953
}
954
 
955
void XfigPlug::processArc(QDataStream &ts, QString data)
956
{
957
        QString tmp = data;
958
        QString fArrowData = "";
959
        QString bArrowData = "";
960
        int             command;
961
        int             subtype;                                // (1: open ended arc, 2: pie-wedge (closed))
962
        int             line_style;                             // (enumeration type)
963
        int             thickness;                              // (1/80 inch)
964
        int             pen_color;                              // (enumeration type, pen color)
965
        int             fill_color;                             // (enumeration type, fill color)
966
        int             depth;                                  // (enumeration type)
967
        int             pen_style;                              // (pen style, not used)
968
        int             area_fill;                              // (enumeration type, -1 = no fill)
969
        double  style_val;                              // (1/80 inch)
970
        int             cap_style;                              // (enumeration type, only used for POLYLINE)
971
        int             direction;                              // (always 1)
972
        int             forward_arrow;                  // (0: off, 1: on)
973
        int             backward_arrow;                 // (0: off, 1: on)
974
        double  center_x, center_y;             // (center of the arc)
975
        int             x1, y1;                                 // (Fig units, the 1st point the user entered)
976
        int             x2, y2;                                 // (Fig units, the 2nd point)
977
        int             x3, y3;                                 // (Fig units, the last point)
13497 jghali 978
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
13371 jghali 979
        Code >> command >> subtype >> line_style >> thickness >> pen_color >> fill_color >> depth >> pen_style;
980
        Code >> area_fill >> style_val >> cap_style >> direction >> forward_arrow >> backward_arrow;
981
        Code >> center_x >> center_y >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
982
        if (forward_arrow == 1)
983
                fArrowData = readLinefromDataStream(ts);
984
        if (backward_arrow == 1)
985
                bArrowData = readLinefromDataStream(ts);
986
        useColor(pen_color, 0, false);
987
        useColor(fill_color, area_fill, true);
988
        LineW = thickness / 80.0 * 72.0;
989
        int z = -1;
990
        PageItem *ite;
991
        if (subtype == 1)
992
                z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
993
        else if (subtype == 2)
994
                z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
995
        else
996
                z = -1;
997
        center_x = fig2Pts(center_x) - docX;
998
        center_y = fig2Pts(center_y) - docY;
999
        double x1R = fig2Pts(x1) - docX;
1000
        double y1R = fig2Pts(y1) - docY;
1001
        double x3R = fig2Pts(x3) - docX;
1002
        double y3R = fig2Pts(y3) - docY;
1003
        double r1 = distance(x1R - center_x, y1R - center_y);
1004
        double x0 = center_x - r1;
1005
        double y0 = center_y - r1;
1006
        QRectF bBox = QRectF(x0, y0, r1 * 2.0, r1 * 2.0);
1007
        double angle1 = -xy2Deg(x1R - center_x, y1R - center_y);
1008
        double angle2 = -xy2Deg(x3R - center_x, y3R - center_y);
1009
        double sweep;
1010
        if (direction == 0)
1011
        {
1012
                sweep = angle1 - angle2;
1013
                if (sweep < 0.0)
1014
                        sweep = 360.0 + sweep;
1015
        }
1016
        else
1017
        {
1018
                sweep = angle2 - angle1;
1019
                if (sweep < 0.0)
1020
                        sweep = 360.0 + sweep;
1021
                double an = angle1;
1022
                angle1 = angle2;
1023
                angle2 = an;
1024
        }
1025
        QPainterPath aPath;
1026
        if (subtype == 1)
1027
        {
1028
                aPath.arcMoveTo(bBox, angle2);
1029
                aPath.arcTo(bBox, angle2, sweep);
1030
        }
1031
        else
1032
        {
1033
                aPath.moveTo(center_x, center_y);
1034
                aPath.arcTo(bBox, angle2, sweep);
1035
                aPath.lineTo(center_x, center_y);
1036
        }
1037
        FPointArray points;
1038
        points.fromQPainterPath(aPath);
1039
 
1040
        if (z >= 0)
1041
        {
1042
                ite = m_Doc->Items->at(z);
1043
                ite->PoLine = points.copy();
1044
                ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1045
                ite->ClipEdited = true;
1046
                ite->FrameType = 3;
1047
                ite->setFillShade(CurrFillShade);
1048
                ite->setLineShade(CurrStrokeShade);
1049
                if (line_style > 0)
1050
                        ite->setDashes(getDashValues(LineW, line_style));
1051
                if (subtype == 1)
1052
                {
1053
                        if (cap_style == 0)
1054
                                ite->setLineEnd(Qt::FlatCap);
1055
                        else if (cap_style == 1)
1056
                                ite->setLineEnd(Qt::RoundCap);
1057
                        else if (cap_style == 2)
1058
                                ite->setLineEnd(Qt::SquareCap);
1059
                }
1060
                FPoint wh = getMaxClipF(&ite->PoLine);
1061
                ite->setWidthHeight(wh.x(),wh.y());
1062
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
1063
                m_Doc->AdjustItemSize(ite);
1064
                ite->setWidthHeight(qMax(ite->width(), 1.0), qMax(ite->height(), 1.0));
1065
                depthMap.insert(999 - depth, currentItemNr);
1066
                currentItemNr++;
1067
                if ((ite->itemType() == PageItem::PolyLine) && ((forward_arrow == 1) || (backward_arrow == 1)))
1068
                {
1069
                        if (direction == 1)
1070
                                processArrows(forward_arrow, fArrowData, backward_arrow, bArrowData, depth, ite);
1071
                        else
1072
                                processArrows(backward_arrow, bArrowData, forward_arrow, fArrowData, depth, ite);
1073
                }
1074
        }
1075
}
1076
 
1077
void XfigPlug::processEllipse(QString data)
1078
{
1079
        QString tmp = data;
1080
        int             command;                        // (always 1)
1081
        int             subtype;                        // (1: ellipse defined by radii
1082
                                                                //  2: ellipse defined by diameters
1083
                                                                //  3: circle defined by radius
1084
                                                                //  4: circle defined by diameter)
1085
        int             line_style;                     // (enumeration type)
1086
        int             thickness;                      // (1/80 inch)
1087
        int             pen_color;                      // (enumeration type, pen color)
1088
        int             fill_color;                     // (enumeration type, fill color)
1089
        int             depth;                          // (enumeration type)
1090
        int             pen_style;                      // (pen style, not used)
1091
        int             area_fill;                      // (enumeration type, -1 = no fill)
1092
        double  style_val;                      // (1/80 inch)
1093
        int             direction;                      // (always 1)
1094
        double  angle;                          // (radians, the angle of the x-axis)
1095
        int             center_x, center_y;     // (Fig units)
1096
        int             radius_x, radius_y;     // (Fig units)
1097
        int             start_x, start_y;       // (Fig units; the 1st point entered)
1098
        int             end_x, end_y;           // (Fig units; the last point entered)
1099
        double x, y, w, h;
13497 jghali 1100
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
13371 jghali 1101
        Code >> command >> subtype >> line_style >> thickness >> pen_color >> fill_color >> depth >> pen_style;
1102
        Code >> area_fill >> style_val >> direction >> angle >> center_x >> center_y >> radius_x >> radius_y;
1103
        Code >> start_x >> start_y >> end_x >> end_y;
1104
        useColor(pen_color, 0, false);
1105
        useColor(fill_color, area_fill, true);
1106
        LineW = thickness / 80.0 * 72.0;
1107
        w = fig2Pts(radius_x);
1108
        h = fig2Pts(radius_y);
1109
        x = fig2Pts(center_x) - w;
1110
        y = fig2Pts(center_y) - h;
1111
        w *= 2.0;
1112
        h *= 2.0;
1113
        x -= docX;
1114
        x += m_Doc->currentPage()->xOffset();
1115
        y -= docY;
1116
        y += m_Doc->currentPage()->yOffset();
1117
        int z = -1;
1118
        PageItem *ite;
1119
        z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + x, baseY + y, w, h, LineW, CurrColorFill, CurrColorStroke, true);
1120
        if (z >= 0)
1121
        {
1122
                ite = m_Doc->Items->at(z);
1123
                ite->setFillShade(CurrFillShade);
1124
                ite->setLineShade(CurrStrokeShade);
1125
                if (line_style > 0)
1126
                        ite->setDashes(getDashValues(LineW, line_style));
1127
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
1128
                int rot = m_Doc->RotMode;
1129
                m_Doc->RotMode = 2;
1130
                m_Doc->RotateItem(-angle * 180.0 / M_PI, ite);
1131
                m_Doc->RotMode = rot;
1132
                depthMap.insert(999 - depth, currentItemNr);
1133
                currentItemNr++;
1134
        }
1135
}
1136
 
1137
QString XfigPlug::cleanText(QString text)
1138
{
1139
        QString ret = "";
1140
        QString tmp = "";
1141
        bool sep = false;
1142
        int sepcount = 0;
1143
        for (int a = 1; a < text.count(); ++a)
1144
        {
1145
                QString ch = text.mid(a,1);
1146
                if (sep)
1147
                {
1148
                        if (ch == "\\")
1149
                        {
1150
                                ret += ch;
1151
                                sep = false;
1152
                        }
1153
                        else
1154
                        {
1155
                                tmp += ch;
1156
                                sepcount++;
1157
                                if (sepcount == 3)
1158
                                {
1159
                                        sep = false;
1160
                                        bool ok = false;
1161
                                        if (tmp != "001")
1162
                                        {
1163
                                                int code = tmp.toInt(&ok, 8);
1164
                                                if (ok)
1165
                                                        ret += QChar(code);
1166
                                        }
1167
                                        tmp = "";
1168
                                }
1169
                        }
1170
                }
1171
                else
1172
                {
1173
                        if (ch == "\\")
1174
                        {
1175
                                sep = true;
1176
                                sepcount = 0;
1177
                        }
1178
                        else
1179
                                ret += ch;
1180
                }
1181
        }
1182
        return ret;
1183
}
1184
 
1185
void XfigPlug::processText(QString data)
1186
{
1187
        QString tmp = data;
1188
        int             command;                        // (always 4)
1189
        int             subtype;                        // (0: Left justified
1190
                                                                //  1: Center justified
1191
                                                                //  2: Right justified)
1192
        int             color;                          // (enumeration type)
1193
        int             depth;                          // (enumeration type)
1194
        int             pen_style;                      // (enumeration , not used)
1195
        int             font;                           // (enumeration type)
1196
        float   font_size;                      // (font size in points)
1197
        float   angle;                          // (radians, the angle of the text)
1198
        int             font_flags;                     // (bit vector)
1199
        float   height;                         // (Fig units)
1200
        float   length;                         // (Fig units)
1201
        int             xT, yT;                         // (Fig units, coordinate of the origin
1202
                                                                //  of the string.  If sub_type = 0, it is
1203
                                                                //  the lower left corner of the string.
1204
                                                                //  If sub_type = 1, it is the lower
1205
                                                                //  center.  Otherwise it is the lower
1206
                                                                //  right corner of the string.)
1207
        QString text;
1208
        double x, y, w, h;
13497 jghali 1209
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
13371 jghali 1210
        Code >> command >> subtype >> color >> depth >> pen_style >> font >> font_size >> angle;
1211
        Code >> font_flags >> height >> length >> xT >> yT;
1212
        text = Code.readAll();
1213
        text = cleanText(text);
1214
        FPointArray textPath;
1215
        QPainterPath painterPath;
1216
        QString TFont = m_Doc->toolSettings.defFont;
1217
        QFont::Weight weight = QFont::Normal;
1218
        bool isItalic = false;
1219
        if (font_flags & 4)
1220
        {
1221
                switch (font)
1222
                {
1223
                        case 0:
1224
                                TFont = "Times Roman";
1225
                                weight = QFont::Normal;
1226
                                break;
1227
                        case 1:
1228
                                TFont = "Times Italic";
1229
                                weight = QFont::Normal;
1230
                                isItalic = true;
1231
                                break;
1232
                        case 2:
1233
                                TFont = "Times Bold";
1234
                                weight = QFont::Bold;
1235
                                break;
1236
                        case 3:
1237
                                TFont = "Times Bold Italic";
1238
                                weight = QFont::Bold;
1239
                                isItalic = true;
1240
                                break;
1241
                        case 4:
1242
                                TFont = "AvantGarde Book";
1243
                                weight = QFont::Normal;
1244
                                break;
1245
                        case 5:
1246
                                TFont = "AvantGarde Book Oblique";
1247
                                weight = QFont::Normal;
1248
                                break;
1249
                        case 6:
1250
                                TFont = "AvantGarde Demi";
1251
                                weight = QFont::DemiBold;
1252
                                break;
1253
                        case 7:
1254
                                TFont = "AvantGarde Demi Oblique";
1255
                                weight = QFont::DemiBold;
1256
                                break;
1257
                        case 8:
1258
                                TFont = "Bookman Light";
1259
                                weight = QFont::Light;
1260
                                break;
1261
                        case 9:
1262
                                TFont = "Bookman Light Italic";
1263
                                weight = QFont::Light;
1264
                                isItalic = true;
1265
                                break;
1266
                        case 10:
1267
                                TFont = "Bookman Demi";
1268
                                weight = QFont::DemiBold;
1269
                                break;
1270
                        case 11:
1271
                                TFont = "Bookman Demi Italic";
1272
                                weight = QFont::DemiBold;
1273
                                isItalic = true;
1274
                                break;
1275
                        case 12:
1276
                                TFont = "Courier";
1277
                                weight = QFont::Normal;
1278
                                break;
1279
                        case 13:
1280
                                TFont = "Courier Oblique";
1281
                                weight = QFont::Normal;
1282
                                break;
1283
                        case 14:
1284
                                TFont = "Courier Bold";
1285
                                weight = QFont::Bold;
1286
                                break;
1287
                        case 15:
1288
                                TFont = "Courier Bold Oblique";
1289
                                weight = QFont::Bold;
1290
                                break;
1291
                        case 16:
1292
                                TFont = "Helvetica";
1293
                                weight = QFont::Normal;
1294
                                break;
1295
                        case 17:
1296
                                TFont = "Helvetica Oblique";
1297
                                weight = QFont::Normal;
1298
                                break;
1299
                        case 18:
1300
                                TFont = "Helvetica Bold";
1301
                                weight = QFont::Bold;
1302
                                break;
1303
                        case 19:
1304
                                TFont = "Helvetica Bold Oblique";
1305
                                weight = QFont::Bold;
1306
                                break;
1307
                        case 20:
1308
                                TFont = "Helvetica Narrow";
1309
                                weight = QFont::Normal;
1310
                                break;
1311
                        case 21:
1312
                                TFont = "Helvetica Narrow Oblique";
1313
                                weight = QFont::Normal;
1314
                                break;
1315
                        case 22:
1316
                                TFont = "Helvetica Narrow Bold";
1317
                                weight = QFont::Bold;
1318
                                break;
1319
                        case 23:
1320
                                TFont = "Helvetica Narrow Bold Oblique";
1321
                                weight = QFont::Bold;
1322
                                break;
1323
                        case 24:
1324
                                TFont = "New Century Schoolbook Roman";
1325
                                weight = QFont::Normal;
1326
                                break;
1327
                        case 25:
1328
                                TFont = "New Century Schoolbook Italic";
1329
                                weight = QFont::Normal;
1330
                                isItalic = true;
1331
                                break;
1332
                        case 26:
1333
                                TFont = "New Century Schoolbook Bold";
1334
                                weight = QFont::Bold;
1335
                                break;
1336
                        case 27:
1337
                                TFont = "New Century Schoolbook Bold Italic";
1338
                                weight = QFont::Bold;
1339
                                isItalic = true;
1340
                                break;
1341
                        case 28:
1342
                                TFont = "Palatino Roman";
1343
                                weight = QFont::Normal;
1344
                                break;
1345
                        case 29:
1346
                                TFont = "Palatino Italic";
1347
                                weight = QFont::Normal;
1348
                                isItalic = true;
1349
                                break;
1350
                        case 30:
1351
                                TFont = "Palatino Bold";
1352
                                weight = QFont::Bold;
1353
                                break;
1354
                        case 31:
1355
                                TFont = "Palatino Bold Italic";
1356
                                weight = QFont::Bold;
1357
                                isItalic = true;
1358
                                break;
1359
                        case 32:
1360
                                TFont = "Symbol";
1361
                                weight = QFont::Normal;
1362
                                break;
1363
                        case 33:
1364
                                TFont = "Zapf Chancery Medium Italic";
1365
                                weight = QFont::Normal;
1366
                                isItalic = true;
1367
                                break;
1368
                        case 34:
1369
                                TFont = "Zapf Dingbats";
1370
                                weight = QFont::Normal;
1371
                                break;
1372
                        default:
1373
                                TFont = m_Doc->toolSettings.defFont;
1374
                                weight = QFont::Normal;
1375
                                break;
1376
                }
1377
        }
1378
        else
1379
        {
1380
                switch (font)
1381
                {
1382
                case 1: // Roman
1383
                                TFont = "Times";
1384
                                weight = QFont::Normal;
1385
                                break;
1386
                        case 2: // Bold
1387
                                TFont = "Times";
1388
                                weight = QFont::Bold;
1389
                                break;
1390
                        case 3: // Italic
1391
                                TFont = "Times";
1392
                                weight = QFont::Normal;
1393
                                isItalic = true;
1394
                                break;
1395
                        case 4: // Sans Serif
1396
                                TFont = "Helvetica";
1397
                                weight = QFont::Normal;
1398
                                break;
1399
                        case 5: // Typewriter
1400
                                TFont = "Courier";
1401
                                weight = QFont::Normal;
1402
                                break;
1403
                        default:
1404
                                TFont = m_Doc->toolSettings.defFont;
1405
                                weight = QFont::Normal;
1406
                                break;
1407
                }
1408
        }
1409
        w = fig2Pts(length);
1410
        h = fig2Pts(height);
1411
        x = fig2Pts(xT);
1412
        y = fig2Pts(yT);
1413
        x -= docX;
1414
        x += m_Doc->currentPage()->xOffset();
1415
        y -= docY;
1416
        y += m_Doc->currentPage()->yOffset();
1417
        QFont tf = QFont(TFont, 10, weight, isItalic);
1418
        tf.setPointSizeF(font_size / 80.0 * 72.0);
1419
        painterPath.addText( 0, 0, tf, text );
1420
        QRectF br = painterPath.boundingRect();
1421
        if ((angle == 0) && (br.width() > w))
1422
        {
1423
                QMatrix m;
1424
                m.scale(w / br.width(), w / br.width());
1425
                painterPath = m.map(painterPath);
1426
        }
1427
        textPath.fromQPainterPath(painterPath);
1428
        useColor(color, 0, false);
1429
        int z = -1;
1430
        PageItem *ite;
1431
        z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX + x, baseY + y, w, h, 0, CurrColorStroke, CommonStrings::None, true);
1432
        if (z >= 0)
1433
        {
1434
                ite = m_Doc->Items->at(z);
1435
                ite->setRotation(-angle * 180.0 / M_PI);
1436
                ite->PoLine = textPath.copy();
1437
                ite->ClipEdited = true;
1438
                ite->FrameType = 3;
1439
                FPoint wh = getMaxClipF(&ite->PoLine);
1440
                ite->setWidthHeight(wh.x(),wh.y());
1441
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
1442
                m_Doc->AdjustItemSize(ite);
1443
                ite->setWidthHeight(qMax(ite->width(), 1.0), qMax(ite->height(), 1.0));
1444
                if (subtype == 1)
1445
                        m_Doc->MoveRotated(ite, FPoint(-br.width() / 2.0, 0.0));
1446
                else if (subtype == 2)
1447
                        m_Doc->MoveRotated(ite, FPoint(-br.width(), 0.0));
1448
                depthMap.insert(999 - depth, currentItemNr);
1449
                currentItemNr++;
1450
        }
1451
}
1452
 
1453
void XfigPlug::processData(QDataStream &ts, QString data)
1454
{
1455
        QString tmp = data;
1456
        int command, subtype;
13497 jghali 1457
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
13371 jghali 1458
        Code >> command >> subtype;
1459
        switch (command)
1460
        {
1461
                case 0:
1462
                        parseColor(data);
1463
                        break;
1464
                case 1:
1465
                        processEllipse(data);
1466
                        break;
1467
                case 2:
1468
                        processPolyline(ts, data);
1469
                        break;
1470
                case 3:
1471
                        processSpline(ts, data);
1472
                        break;
1473
                case 4:
1474
                        processText(data);
1475
                        break;
1476
                case 5:
1477
                        processArc(ts, data);
1478
                        break;
1479
                case 6:
1480
//                      qDebug() << "Xfig-Import:: Unsupported Compound object";
1481
                        break;
1482
                case -6:
1483
//                      qDebug() << "Xfig-Import:: Unsupported End of Compound object";
1484
                        break;
1485
        }
1486
}
1487
 
1488
void XfigPlug::resortItems()
1489
{
1490
        int ac = m_Doc->Items->count();
1491
        QList<PageItem*> itemList;
1492
        for (int as = oldDocItemCount; as < ac; ++as)
1493
        {
1494
                itemList.append(m_Doc->Items->takeAt(oldDocItemCount));
1495
        }
1496
        QList<int> keylist = depthMap.uniqueKeys();
1497
        int keysCount = keylist.count();
1498
        int currentLayer = 0;
1499
        for (int it = 0; it < keysCount; ++it)
1500
        {
1501
                if ((importerFlags & LoadSavePlugin::lfCreateDoc) && (it > 0))
1502
                        currentLayer = m_Doc->addLayer(QString("Layer %1").arg(it), true);
1503
                QList<int> elems = depthMap.values(keylist.at(it));
1504
                qSort(elems);
1505
                int itemsCount = elems.count();
1506
                for (int i = 0; i < itemsCount; ++i)
1507
                {
1508
                        PageItem* ite = itemList.at(elems.at(i));
1509
                        Elements.append(ite);
1510
                        m_Doc->Items->append(ite);
1511
                        ite->ItemNr = m_Doc->Items->count()-1;
1512
                        if ((importerFlags & LoadSavePlugin::lfCreateDoc) && (it > 0))
1513
                                ite->LayerNr = currentLayer;
1514
                }
1515
        }
1516
}
1517
 
1518
 
1519
double XfigPlug::fig2Pts(double in)
1520
{
1521
        return in / 1200.0 * 72.0;
1522
}
1523
 
1524
bool XfigPlug::convert(QString fn)
1525
{
1526
        QString tmp;
1527
        CurrColorFill = "White";
1528
        CurrFillShade = 100.0;
1529
        CurrColorStroke = "Black";
1530
        CurrStrokeShade = 100.0;
1531
        patternMode = false;
1532
        patternX1 = 0.0;
1533
        patternY1 = 0.0;
1534
        patternX2 = 0.0;
1535
        patternY2 = 0.0;
1536
        Coords.resize(0);
1537
        Coords.svgInit();
1538
        clipCoords.resize(0);
1539
        clipCoords.svgInit();
1540
        currentPatternName = "";
1541
        currentPatternX = 0.0;
1542
        currentPatternY = 0.0;
1543
        currentPatternXScale = 1.0;
1544
        currentPatternYScale = 1.0;
1545
        currentPatternRotation = 0.0;
1546
        QList<PageItem*> gElements;
1547
        groupStack.push(gElements);
1548
        currentItemNr = 0;
1549
        if(progressDialog)
1550
        {
1551
                progressDialog->setOverallProgress(2);
1552
                progressDialog->setLabel("GI", tr("Generating Items"));
1553
                qApp->processEvents();
1554
        }
1555
        QFile f(fn);
1556
        if (f.open(QIODevice::ReadOnly))
1557
        {
1558
                oldDocItemCount = m_Doc->Items->count();
1559
                int fSize = (int) f.size();
1560
                if (progressDialog)
1561
                {
1562
                        progressDialog->setTotalSteps("GI", fSize);
1563
                        qApp->processEvents();
1564
                }
1565
                QDataStream ts(&f);
1566
                QString version = readLinefromDataStream(ts);
1567
                QString orientation = readLinefromDataStream(ts);
1568
                QString justification = readLinefromDataStream(ts);
1569
                QString units = readLinefromDataStream(ts);
1570
                QString papersize = readLinefromDataStream(ts);
1571
                QString magnification = readLinefromDataStream(ts);
1572
                QString multiple = readLinefromDataStream(ts);
1573
                QString transparent = readLinefromDataStream(ts);
1574
                tmp = readLinefromDataStream(ts);
1575
                if (tmp.startsWith("#"))
1576
                        tmp = readLinefromDataStream(ts);
1577
                QString resolution = tmp;
1578
                while (!ts.atEnd())
1579
                {
1580
                        tmp = readLinefromDataStream(ts);
1581
                        if (tmp.startsWith("#"))
1582
                                continue;
1583
                        processData(ts, tmp);
1584
                        progressDialog->setProgress("GI", ts.device()->pos());
1585
                        qApp->processEvents();
1586
                }
1587
                resortItems();
1588
        }
1589
        if (progressDialog)
1590
                progressDialog->close();
1591
        return true;
1592
}