Subversion Repositories Scribus

Rev

Rev 14710 | Rev 14721 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
13951 fschmid 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
/* Code inspired by KOffice libwmf and adapted for Scribus by Jean Ghali */
9
 
10
#include "scconfig.h"
11
#include "wmfimport.h"
12
 
13
#include <QCursor>
14
#include <QDrag>
15
#include <QBuffer>
16
#include <QDataStream>
17
#include <QFile>
18
#include <QMimeData>
19
#include <QPainterPath>
20
#include <QRegExp>
21
 
14170 jghali 22
#include "commonstrings.h"
13951 fschmid 23
#include "scribus.h"
24
#include "scribusXml.h"
14170 jghali 25
#include "fonts/scfontmetrics.h"
13951 fschmid 26
#include "fpointarray.h"
14509 cbradney 27
#include "ui/scmwmenumanager.h"
13951 fschmid 28
#include "prefsmanager.h"
29
#include "pageitem.h"
14170 jghali 30
#include "prefsfile.h"
13951 fschmid 31
#include "scmimedata.h"
32
#include "scraction.h"
33
#include "scribuscore.h"
34
#include "scribusdoc.h"
35
#include "selection.h"
14170 jghali 36
#include "ui/customfdialog.h"
37
#include "ui/propertiespalette.h"
13951 fschmid 38
#include "undomanager.h"
39
#include "loadsaveplugin.h"
40
#include "util.h"
41
#include "util_icon.h"
42
#include "util_math.h"
43
 
14170 jghali 44
 
13951 fschmid 45
using namespace std;
46
 
47
#include "wmfstruct.h"
48
#include "wmfcmd.h"
49
#include "wmfcontext.h"
50
#include "wmfhandle.h"
51
#include "metafuncs.h"
52
 
53
#define WMFIMPORT_DEBUG 0
54
#define MAX_OBJHANDLE   128
55
 
56
#define ANSI_CHARSET                    0               // ANSI charset (Windows-1252)
57
#define DEFAULT_CHARSET                 1
58
#define SYMBOL_CHARSET                  2
59
#define MAC_CHARSET                             77
60
#define SHIFTJIS_CHARSET                128             // Shift JIS charset    (Windows-932)
61
#define HANGEUL_CHARSET                 129             // Hangeul charset      (Windows-949)
62
#define JOHAB_CHARSET                   130             // Johab charset        (Windows-1361)
63
#define GB2312_CHARSET                  134             // GB2312 charset       (Windows-936)
64
#define CHINESEBIG5_CHARSET             136             // Chinese Big5 charset (Windows-950)
65
#define GREEK_CHARSET                   161             // Greek charset        (Windows-1253)
66
#define TURKISH_CHARSET                 162             // Turkish charset      (Windows-1254)
67
#define VIETNAMESE_CHARSET              163             // Vietnamese charset   (Windows-1258)
68
#define HEBREW_CHARSET                  177             // Hebrew charset       (Windows-1255)
69
#define ARABIC_CHARSET                  178             // Arabic charset       (Windows-1256)
70
#define BALTIC_CHARSET                  186             // Baltic charset       (Windows-1257)
71
#define RUSSIAN_CHARSET                 204             // Cyrillic charset     (Windows-1251)
72
#define THAI_CHARSET                    222             // Thai charset         (Windows-874)
73
#define EASTEUROPE_CHARSET              238             // Eastern european charset (Windows-1250)
74
#define OEM_CHARSET                             255
75
 
76
/* Symbol to unicode conversion table copied from http://root.cern.ch/viewvc/trunk/qt/src/TQtSymbolCodec.cxx
77
This code is placed under GPL licence (http://root.cern.ch/viewvc/trunk/LICENSE) */
78
static const ushort greek_symbol_to_unicode[64] = {
79
//
80
//  upper case letters:
81
//  ----------------
82
//   Alpha   Beta     Chi   Delta   Epsilon   Phi    Gamma    Eta
83
        0x0391, 0x0392, 0x03A7, 0x0394, 0x0395, 0x03A6, 0x0393, 0x0397,
84
//   Iota   Theta(S) Kappa  Lambda    Mu      Nu    Omicron   Pi
85
        0x0399, 0x03D1, 0x039A, 0x039B, 0x039C, 0x039D, 0x039F, 0x03A0,
86
//  Theta    Rho    Sigma    Tau    Upsilon Stigma   Omega     Xi
87
        0x0398, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03DB, 0x03A9, 0x039E,
88
//   Psi     Zeta   Sigma    Tau    Upsilon  ????   Omega     Xi
89
        0x03A8, 0x0396, 0x03EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
90
//
91
//  lower case letters:
92
//  ----------------
93
//   Alpha   Beta    Chi    Delta   Epsilon   Phi    Gamma    Eta
94
        0x03B1, 0x03B2, 0x03C7, 0x03B4, 0x03B5, 0x03D5, 0x03B3, 0x03B7,
95
//   Iota   Phi (2) Kappa   Lambda    Mu      Nu    Omicron   Pi
96
        0x03B9, 0x03C6, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BF, 0x03C0,
97
//  Theta    Rho    Sigma    Tau    Upsilon OmegaPi Omega     Xi
98
        0x03B8, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03D6, 0x03B9, 0x03BE,
99
//   Psi     Zeta   Sigma    Tau    Upsilon  ????   Omega     Xi
100
        0x03C8, 0x03B6, 0x03EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD
101
};
102
 
103
/* Symbol to unicode conversion table copied from http://root.cern.ch/viewvc/trunk/qt/src/TQtSymbolCodec.cxx
104
This code is placed under GPL licence (http://root.cern.ch/viewvc/trunk/LICENSE) */
105
static const ushort symbol_to_unicode[96] = {
106
//
107
//  upper case letters:
108
//  ----------------
109
// UPSILON  NUMBER  LessEq   Div   INFINITY ???????  CLUB   DIAMOND     
110
        0x03D2, 0x0374, 0x2264, 0x2215, 0x221E, 0x0395, 0x2663, 0x2666,
111
//   HEART  SPADE   <--->   <---             -->             RING
112
        0x2665, 0x2660, 0x2194, 0x2190, 0x2191, 0x2192, 0x2193, 0x2218,
113
//  Theta    Rho    Great    ????   Propor  diff    bullet   ????
114
        0x0398, 0x03A1, 0x2265, 0x03A4, 0x221D, 0x2202, 0x2219, 0x03A8,
115
//   NonEq  Ident    ????   ellips   div     minus  ?????   aleph
116
        0x2260, 0x2261, 0xFFFD, 0x22EF, 0x2223, 0x2212, 0xFFFD, 0xFFFD,
117
//
118
//  lower case letters:
119
//  ----------------
120
//   Alpha   Beta    Chi    Delta   Epsilon   Phi    Gamma    Eta
121
        0x03B1, 0x03B2, 0x03C7, 0x03B4, 0x03B5, 0x03D5, 0x03B3, 0x03B7,
122
//   Iota   Phi (2) Kappa   Lambda    Mu      Nu    Omicron   Pi
123
        0x03B9, 0x03C6, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BF, 0x03C0,
124
//  Theta    Rho    Sigma    Tau    Upsilon OmegaPi Omega     Xi
125
        0x03B8, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03D6, 0x03B9, 0x03BE,
126
//   Psi     Zeta   arrow    Tau    Upsilon  ????   Omega     Xi
127
        0x03C8, 0x03B6, 0x21D4, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
128
//  lower case letters:
129
//  ----------------
130
//   Alpha   Beta    Chi    Delta   Sigma     Phi    Gamma    Eta
131
        0x03B1, 0x03B2, 0x03C7, 0x03B4, 0x2211, 0x03D5, 0x03B3, 0x03B7,
132
//   Iota   Phi (2) Kappa   Lambda    Mu      Nu    Omicron   Pi
133
        0x03B9, 0x03C6, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BF, 0x03C0,
134
//  Theta   Integr  Sigma    Tau    Upsilon OmegaPi Omega     Xi
135
        0x03B8, 0x222b, 0x03C3, 0x03C4, 0x03C5, 0x03D6, 0x03B9, 0x03BE,
136
//   Psi     Zeta   Sigma    Tau    Upsilon  ????   Omega     Xi
137
        0x03C8, 0x03B6, 0x03EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD
138
};
139
 
14710 fschmid 140
WMFImport::WMFImport( ScribusDoc* doc, int flags )
13951 fschmid 141
{      
142
        m_tmpSel = new Selection(this, false);
14710 fschmid 143
        m_Doc    = doc;
13951 fschmid 144
        unsupported = false;
145
        importFailed = false;
146
        importCanceled = true;
147
        importedColors.clear();
148
        m_docDesc = "";
149
        m_docTitle = "";
150
        interactive = (flags & LoadSavePlugin::lfInteractive);
151
 
152
        m_Valid        = false;
153
        m_ObjHandleTab = NULL;
154
        m_Dpi          = 1440;
155
}
156
 
157
WMFImport::~WMFImport()
158
{
159
        qDeleteAll(m_commands);
160
        m_commands.clear();
161
        if ( m_tmpSel) delete m_tmpSel;
162
        if ( m_ObjHandleTab )
163
        {
164
                for (int i = 0; i < MAX_OBJHANDLE; ++i)
165
                {
166
                        if (m_ObjHandleTab[i])
167
                                delete m_ObjHandleTab[i];
168
                }
169
                delete[] m_ObjHandleTab;
170
        }
171
}
172
 
173
QString WMFImport::importColor(const QColor& color)
174
{
175
        bool found = false;
176
        int r, g, b;
177
        QColor  tmpColor;
178
        QString retColorName;
179
        ColorList::Iterator it;
180
        for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it)
181
        {
182
                if (it.value().getColorModel() == colorModelRGB)
183
                {
184
                        it.value().getRGB(&r, &g, &b);
185
                        tmpColor.setRgb(r, g, b);
186
                        if (color == tmpColor)
187
                        {
188
                                retColorName = it.key();
189
                                found = true;
190
                                break;
191
                        }
192
                }
193
        }
194
        if (!found)
195
        {
196
                ScColor tmp;
197
                tmp.fromQColor(color);
198
                tmp.setSpotColor(false);
199
                tmp.setRegistrationColor(false);
200
                m_Doc->PageColors.insert("FromWMF"+color.name(), tmp);
201
                importedColors.append("FromWMF"+color.name());
202
                retColorName = "FromWMF"+color.name();
203
        }
204
        return retColorName;
205
}
206
 
207
QColor WMFImport::colorFromParam( short* params )
208
{
209
        unsigned int colorRef;
210
        int red, green, blue;
211
 
212
        colorRef = toDWord( params ) & 0xffffff;
213
        red      = colorRef & 255;
214
        green    = ( colorRef>>8 ) & 255;
215
        blue     = ( colorRef>>16 ) & 255;
216
 
217
        return QColor( red, green, blue );
218
}
219
 
220
QTextCodec* WMFImport::codecFromCharset( int charset )
221
{
222
        QTextCodec* codec = NULL;
223
        if (charset == DEFAULT_CHARSET || charset == OEM_CHARSET)
224
                codec = QTextCodec::codecForLocale();
225
        else if (charset == ANSI_CHARSET)
226
                codec = QTextCodec::codecForName("windows-1252");
227
        /*else if (charset == SYMBOL_CHARSET)
228
                codec = QTextCodec::codecForLocale();// Not supported yet*/
229
        else if (charset == MAC_CHARSET)
230
                codec = QTextCodec::codecForName("Apple Roman");
231
        else if (charset == SHIFTJIS_CHARSET)
232
                codec = QTextCodec::codecForName("Shift-JIS");
233
        else if (charset == HANGEUL_CHARSET)
234
                codec = QTextCodec::codecForName("CP949");
235
        else if (charset == GB2312_CHARSET)
236
                codec = QTextCodec::codecForName("CP936");
237
        else if (charset == CHINESEBIG5_CHARSET)
238
                codec = QTextCodec::codecForName("Big5");
239
        else if (charset == GREEK_CHARSET)
240
                codec = QTextCodec::codecForName("windows-1253");
241
        else if (charset == TURKISH_CHARSET)
242
                codec = QTextCodec::codecForName("windows-1254");
243
        else if (charset == VIETNAMESE_CHARSET)
244
                codec = QTextCodec::codecForName("windows-1258");
245
        else if (charset == HEBREW_CHARSET)
246
                codec = QTextCodec::codecForName("windows-1255");
247
        else if (charset == ARABIC_CHARSET)
248
                codec = QTextCodec::codecForName("windows-1256");
249
        else if (charset == BALTIC_CHARSET)
250
                codec = QTextCodec::codecForName("windows-1257");
251
        else if (charset == RUSSIAN_CHARSET)
252
                codec = QTextCodec::codecForName("windows-1251");
253
        else if (charset == THAI_CHARSET)
254
                codec = QTextCodec::codecForName("CP874");
255
        else if (charset == EASTEUROPE_CHARSET)
256
                codec = QTextCodec::codecForName("windows-1250");
257
        return codec;
258
}
259
 
260
QString WMFImport::symbolToUnicode ( const QByteArray& chars )
261
{
262
        /*Code under GPL licence (http://root.cern.ch/viewvc/trunk/LICENSE)
263
        taken from http://root.cern.ch/viewvc/trunk/qt/src/TQtSymbolCodec.cxx*/
264
        QString r;
265
        const unsigned char * c = (const unsigned char *) chars.data();
266
 
267
        if( chars.size() == 0 ) return r;
268
 
269
        for (int i = 0; i < chars.size(); ++i)
270
        {
271
                if ( 64 < c[i] && c[i] <= 64+32 )
272
                        r.append( QChar(greek_symbol_to_unicode[c[i]-65]) );
273
                else if (64+32+1 <= c[i] && c[i] < 64+32+32+1)
274
                        r.append( QChar(greek_symbol_to_unicode[c[i]-65-32]+32) );
275
                else if (161 <= c[i] )
276
                        r.append(  QChar(symbol_to_unicode[c[i]-161]) );
277
                else
278
                        r.append( QChar(c[i]) );
279
        }
280
        return r;
281
}
282
 
283
FPointArray WMFImport::pointsFromParam( short num, short* params )
284
{
285
        FPointArray points;
286
        points.resize( num );
287
 
288
        for ( int i = 0; i < num; i++, params += 2 )
289
                points.setPoint( i, params[ 0 ], params[ 1 ] );
290
 
291
        return points;
292
}
293
 
294
FPointArray WMFImport::pointsToPolyline( const FPointArray& points, bool closePath )
295
{
296
        bool bFirst = true;
297
        double x = 0.0, y = 0.0;
298
        FPointArray polyline;
299
        polyline.svgInit();
300
        for( uint i = 0; i < points.size(); ++i )
301
        {
302
                FPoint point = points.point(i);
303
                if( bFirst )
304
                {
305
                        x = point.x();
306
                        y = point.y();
307
                        polyline.svgMoveTo(x, y);
308
                        bFirst = false;
309
                }
310
                else
311
                {
312
                        x = point.x();
313
                        y = point.y();
314
                        polyline.svgLineTo(x, y);
315
                }
316
        }
317
        if (closePath && (points.size() > 4))
318
                polyline.svgClosePath();
319
        return polyline;
320
}
321
 
322
void WMFImport::pointsToAngle( double xStart, double yStart, double xEnd, double yEnd, double& angleStart, double& angleLength )
323
{
324
        double aStart  = atan2( yStart,  xStart );
325
        double aLength = atan2( yEnd, xEnd ) - aStart;
326
 
327
        angleStart  = (int)(aStart * 180.0 / 3.14166);
328
        angleLength = (int)(aLength * 180.0 / 3.14166);
329
        if ( angleLength < 0 ) angleLength = 360.0 + angleLength;
330
}
331
 
14710 fschmid 332
QImage WMFImport::readThumbnail(QString fname)
333
{
334
        if (!loadWMF(fname))
335
        {
336
                importFailed = true;
337
                return QImage();
338
        }
339
        QString CurDirP = QDir::currentPath();
340
        QFileInfo efp(fname);
341
        QDir::setCurrent(efp.path());
342
        double scale  = (m_Dpi > 0) ? 72.0 / m_Dpi : 0.05;
343
        double width  = m_BBox.width() * scale;
344
        double height = m_BBox.height() * scale;
345
        m_Doc = new ScribusDoc();
346
        m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
347
        m_Doc->setPage(width, height, 0, 0, 0, 0, 0, 0, false, false);
348
        m_Doc->addPage(0);
349
        m_Doc->setGUI(false, ScCore->primaryMainWindow(), 0);
350
        m_Doc->setLoading(true);
351
        m_Doc->DoDrawing = false;
352
        m_Doc->scMW()->ScriptRunning = true;
353
        m_Doc->PageColors.ensureBlackAndWhite();
354
        QList<PageItem*> Elements = parseWmfCommands();
355
        m_tmpSel->clear();
14720 fschmid 356
        QImage tmpImage = QImage();
14710 fschmid 357
        if (Elements.count() > 0)
358
        {
359
                bool isGroup = true;
360
                int firstElem = -1;
361
                if (Elements.at(0)->Groups.count() != 0)
362
                        firstElem = Elements.at(0)->Groups.top();
363
                for (int bx = 0; bx < Elements.count(); ++bx)
364
                {
365
                        PageItem* bxi = Elements.at(bx);
366
                        if (bxi->Groups.count() != 0)
367
                        {
368
                                if (bxi->Groups.top() != firstElem)
369
                                        isGroup = false;
370
                        }
371
                        else
372
                                isGroup = false;
373
                }
374
                if (!isGroup)
375
                {
376
                        double minx = 99999.9;
377
                        double miny = 99999.9;
378
                        double maxx = -99999.9;
379
                        double maxy = -99999.9;
380
                        uint lowestItem = 999999;
381
                        uint highestItem = 0;
382
                        for (int a = 0; a < Elements.count(); ++a)
383
                        {
384
                                Elements.at(a)->Groups.push(m_Doc->GroupCounter);
385
                                PageItem* currItem = Elements.at(a);
386
                                lowestItem = qMin(lowestItem, currItem->ItemNr);
387
                                highestItem = qMax(highestItem, currItem->ItemNr);
388
                                double x1, x2, y1, y2;
389
                                currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
390
                                minx = qMin(minx, x1);
391
                                miny = qMin(miny, y1);
392
                                maxx = qMax(maxx, x2);
393
                                maxy = qMax(maxy, y2);
394
                        }
395
                        double gx = minx;
396
                        double gy = miny;
397
                        double gw = maxx - minx;
398
                        double gh = maxy - miny;
399
                        PageItem *high = m_Doc->Items->at(highestItem);
400
                        int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, gx, gy, gw, gh, 0, m_Doc->itemToolPrefs.shapeFillColor, m_Doc->itemToolPrefs.shapeLineColor, true);
401
                        PageItem *neu = m_Doc->Items->takeAt(z);
402
                        m_Doc->Items->insert(lowestItem, neu);
403
                        neu->Groups.push(m_Doc->GroupCounter);
404
                        neu->setItemName( tr("Group%1").arg(neu->Groups.top()));
405
                        neu->AutoName = false;
406
                        neu->isGroupControl = true;
407
                        neu->groupsLastItem = high;
408
                        for (int a = 0; a < m_Doc->Items->count(); ++a)
409
                        {
410
                                m_Doc->Items->at(a)->ItemNr = a;
411
                        }
412
                        neu->setRedrawBounding();
413
                        neu->setTextFlowMode(PageItem::TextFlowDisabled);
414
                        Elements.prepend(neu);
415
                        m_Doc->GroupCounter++;
416
                }
14720 fschmid 417
                m_Doc->DoDrawing = true;
418
                m_Doc->m_Selection->delaySignalsOn();
419
                for (int dre=0; dre<Elements.count(); ++dre)
420
                {
421
                        m_tmpSel->addItem(Elements.at(dre), true);
422
                }
423
                m_tmpSel->setGroupRect();
424
                double xs = m_tmpSel->width();
425
                double ys = m_tmpSel->height();
426
                double sc = 500.0 / qMax(xs, ys);
427
                m_Doc->scaleGroup(sc, sc, true, m_tmpSel);
428
                QImage tmpImage = Elements.at(0)->DrawObj_toImage();
429
                tmpImage.setText("XSize", QString("%1").arg(xs));
430
                tmpImage.setText("YSize", QString("%1").arg(ys));
431
                m_Doc->m_Selection->delaySignalsOff();
432
                m_Doc->setLoading(false);
14710 fschmid 433
        }
434
        m_Doc->scMW()->ScriptRunning = false;
435
        delete m_Doc;
436
        QDir::setCurrent(CurDirP);
437
        return tmpImage;
438
}
439
 
13951 fschmid 440
bool WMFImport::import(QString fname, const TransactionSettings& trSettings, int flags)
441
{
442
        if (!loadWMF(fname))
443
        {
444
                importFailed = true;
445
                return false;
446
        }
447
        QString CurDirP = QDir::currentPath();
448
        QFileInfo efp(fname);
449
        QDir::setCurrent(efp.path());
450
        bool success = importWMF(trSettings, flags);
451
        QDir::setCurrent(CurDirP);
452
        return success;
453
}
454
 
455
bool WMFImport::loadWMF( const QString &fileName )
456
{
457
        QFile file( fileName );
458
 
459
        if ( !file.exists() )
460
        {
461
                cerr << "File " << QFile::encodeName(fileName).data() << " does not exist" << endl;
462
                return false;
463
        }
464
 
465
        if ( !file.open( QIODevice::ReadOnly ) )
466
        {
467
                cerr << "Cannot open file " << QFile::encodeName(fileName).data() << endl;
468
                return false;
469
        }
470
 
471
        QByteArray ba = file.readAll();
472
        file.close();
473
 
474
        QBuffer buffer( &ba );
475
        buffer.open( QIODevice::ReadOnly );
476
        return loadWMF( buffer );
477
}
478
 
479
bool WMFImport::loadWMF( QBuffer &buffer )
480
{
481
        QDataStream st;
482
        WmfEnhMetaHeader eheader;
483
        WmfMetaHeader header;
484
        WmfPlaceableHeader pheader;
485
        WORD16 checksum;
486
        int filePos, idx, i;
487
        WmfCmd *cmd;
488
        WORD32 rdSize;
489
        WORD16 rdFunc;
490
 
491
        header.mtSize = 0;
492
        header.mtHeaderSize = 0;
493
        header.mtNoParameters = 0;
494
 
495
        qDeleteAll(m_commands);
496
        m_commands.clear();
497
 
498
        st.setDevice( &buffer );
499
        st.setByteOrder( QDataStream::LittleEndian ); // Great, I love Qt !
500
 
501
        //----- Read placeable metafile header
502
        st >> pheader.key;
503
        m_IsPlaceable = (pheader.key == (WORD32) APMHEADER_KEY);
504
        if ( m_IsPlaceable )
505
        {
506
                st >> pheader.hmf;
507
                st >> pheader.bbox.left;
508
                st >> pheader.bbox.top;
509
                st >> pheader.bbox.right;
510
                st >> pheader.bbox.bottom;
511
                st >> pheader.inch;
512
                st >> pheader.reserved;
513
                st >> pheader.checksum;
514
                checksum = calcCheckSum( &pheader );
515
                if ( pheader.checksum!=checksum ) m_IsPlaceable = false;
516
 
517
                m_Dpi = pheader.inch;
518
                m_BBox.setLeft( pheader.bbox.left );
519
                m_BBox.setTop( pheader.bbox.top );
520
                m_BBox.setRight( pheader.bbox.right );
521
                m_BBox.setBottom( pheader.bbox.bottom );
522
                m_HeaderBoundingBox = m_BBox;
523
                if ( WMFIMPORT_DEBUG )
524
                {
525
                        cerr << endl << "-------------------------------------------------" << endl;
526
                        cerr << "WMF Placeable Header ( " << static_cast<int>(sizeof( pheader ) ) << "):" << endl;
527
                        cerr << "  bbox=( " << m_BBox.left() << "; " << m_BBox.top() << "; " << m_BBox.width() << "; " << m_BBox.height() << ")" << endl;
528
                        cerr << "  inch=" << pheader.inch << endl;
529
                        cerr << "  checksum=" << pheader.checksum << "( " << (pheader.checksum==checksum?"ok":"wrong") << " )" << endl;
530
                }
531
        }
532
        else buffer.seek( 0 );
533
 
534
        //----- Read as enhanced metafile header
535
        filePos = buffer.pos();
536
        st >> eheader.iType;
537
        st >> eheader.nSize;
538
        st >> eheader.rclBounds.left;
539
        st >> eheader.rclBounds.top;
540
        st >> eheader.rclBounds.right;
541
        st >> eheader.rclBounds.bottom;
542
        st >> eheader.rclFrame.left;
543
        st >> eheader.rclFrame.top;
544
        st >> eheader.rclFrame.right;
545
        st >> eheader.rclFrame.bottom;
546
        st >> eheader.dSignature;
547
        m_IsEnhanced = ( eheader.dSignature==ENHMETA_SIGNATURE );
548
        if ( m_IsEnhanced ) // is it really enhanced ?
549
        {
550
                st >> eheader.nVersion;
551
                st >> eheader.nBytes;
552
                st >> eheader.nRecords;
553
                st >> eheader.nHandles;
554
                st >> eheader.sReserved;
555
                st >> eheader.nDescription;
556
                st >> eheader.offDescription;
557
                st >> eheader.nPalEntries;
558
                st >> eheader.szlDevice.width;
559
                st >> eheader.szlDevice.height;
560
                st >> eheader.szlMillimeters.width;
561
                st >> eheader.szlMillimeters.height;
562
 
563
                if ( WMFIMPORT_DEBUG )
564
                {
565
                        cerr << endl << "-------------------------------------------------" << endl;
566
                        cerr << "WMF Extended Header:" << endl;
567
                        cerr << "  iType=" << eheader.iType << endl;
568
                        cerr << "  nSize=" << eheader.nSize << endl;
569
                        cerr << "  rclBounds=( " << eheader.rclBounds.left << "; " << eheader.rclBounds.top << "; "
570
                                          << eheader.rclBounds.right << "; " << eheader.rclBounds.bottom << ")" << endl;
571
                        cerr << "  rclFrame=( " << eheader.rclFrame.left << "; " << eheader.rclFrame.top << "; "
572
                                          << eheader.rclFrame.right << "; " << eheader.rclFrame.bottom << ")" << endl;
573
                        cerr << "  nBytes=" << eheader.nBytes << endl;
574
                        cerr << "\nNOT YET IMPLEMENTED, SORRY." << endl;
575
                }
576
        }
577
        else // no, not enhanced
578
        {
579
                //----- Read as standard metafile header
580
                buffer.seek( filePos );
581
                st >> header.mtType;
582
                st >> header.mtHeaderSize;
583
                st >> header.mtVersion;
584
                st >> header.mtSize;
585
                st >> header.mtNoObjects;
586
                st >> header.mtMaxRecord;
587
                st >> header.mtNoParameters;
588
                if ( WMFIMPORT_DEBUG ) {
589
                        cerr << "WMF Header: " <<  "mtSize=" << header.mtSize << endl;
590
                }
591
        }
592
 
593
        //----- Test header validity
594
        m_Valid = ((header.mtHeaderSize == 9) && (header.mtNoParameters == 0)) || m_IsEnhanced || m_IsPlaceable;
595
        if ( m_Valid )
596
        {
597
                //----- Read Metafile Records
598
                rdFunc = -1;
599
                while ( !st.atEnd() && (rdFunc != 0) )
600
                {
601
                        st >> rdSize;
602
                        st >> rdFunc;
603
                        idx = findFunc( rdFunc );
604
                        rdSize -= 3;
605
 
606
                        cmd = new WmfCmd;
607
                        m_commands.append(cmd);
608
 
609
                        cmd->funcIndex = idx;
610
                        cmd->numParam = rdSize;
611
                        cmd->params = new WORD16[ rdSize ];
612
 
613
                        for ( i=0; i<rdSize && !st.atEnd(); i++ )
614
                                st >> cmd->params[ i ];
615
 
616
 
617
                        if ( rdFunc == 0x020B && !m_IsPlaceable) {         // SETWINDOWORG: dimensions
618
                                m_BBox.setLeft( qMin((int) cmd->params[ 1 ], m_BBox.left()) );
619
                                m_BBox.setTop ( qMin((int) cmd->params[ 0 ], m_BBox.top()) );
620
                        }
621
                        if ( rdFunc == 0x020C && !m_IsPlaceable ) {         // SETWINDOWEXT: dimensions
622
                                m_BBox.setWidth ( qMax((int) cmd->params[ 1 ], m_BBox.width()) );
623
                                m_BBox.setHeight( qMax((int) cmd->params[ 0 ], m_BBox.height()));
624
                        }
625
 
626
                        if ( i<rdSize )
627
                        {
628
                                cerr << "WMF : file truncated !" << endl;
629
                                return false;
630
                        }
631
                }
632
                //----- Test records validities
633
                m_Valid = (rdFunc == 0) && (m_BBox.width() != 0) && (m_BBox.height() != 0);
634
                if ( !m_Valid ) {
635
                        cerr << "WMF : incorrect file format !" << endl;
636
                }
637
        }
638
        else {
639
                cerr << "WMF Header : incorrect header !" << endl;
640
        }
641
 
642
        buffer.close();
643
        return m_Valid;
644
}
645
 
646
bool WMFImport::importWMF(const TransactionSettings& trSettings, int flags)
647
{
648
        bool ret = false;
649
        //double scale = (m_Dpi > 288) ? 288.0 / m_Dpi : 1.0;
650
        double scale  = (m_Dpi > 0) ? 72.0 / m_Dpi : 0.05;
651
        double width  = m_BBox.width() * scale;
652
        double height = m_BBox.height() * scale;
653
        if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
654
        {
655
                m_Doc->setPage(fabs(width), fabs(height), 0, 0, 0, 0, 0, 0, false, false);
656
                m_Doc->addPage(0);
657
                m_Doc->view()->addPage(0);
658
        }
659
        else
660
        {
661
                if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
662
                {
663
                        m_Doc=ScCore->primaryMainWindow()->doFileNew(fabs(width), fabs(height), 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
664
                        ScCore->primaryMainWindow()->HaveNewDoc();
665
                        ret = true;
666
                }
667
        }
668
        if ((ret) || (!interactive))
669
        {
670
                if (width > height)
671
                        m_Doc->PageOri = 1;
672
                else
673
                        m_Doc->PageOri = 0;
674
                m_Doc->m_pageSize = "Custom";
675
        }
676
        FPoint minSize = m_Doc->minCanvasCoordinate;
677
        FPoint maxSize = m_Doc->maxCanvasCoordinate;
678
        FPoint cOrigin = m_Doc->view()->canvasOrigin();
679
        m_Doc->view()->Deselect();
680
        m_Doc->setLoading(true);
681
        m_Doc->DoDrawing = false;
682
        m_Doc->view()->updatesOn(false);
683
        m_Doc->scMW()->ScriptRunning = true;
684
        qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
13996 cbradney 685
        //gc->Family = m_Doc->toolSettings.textFont;
13951 fschmid 686
        m_Doc->PageColors.ensureBlackAndWhite();
687
        //m_gc.push( gc );
688
        QList<PageItem*> Elements = parseWmfCommands();
689
        if (flags & LoadSavePlugin::lfCreateDoc)
690
        {
691
                m_Doc->documentInfo.setTitle(m_docTitle);
692
                m_Doc->documentInfo.setComments(m_docDesc);
693
        }
694
        m_tmpSel->clear();
695
        if (Elements.count() == 0)
696
        {
697
                importFailed = true;
698
                if (importedColors.count() != 0)
699
                {
700
                        for (int cd = 0; cd < importedColors.count(); cd++)
701
                        {
702
                                m_Doc->PageColors.remove(importedColors[cd]);
703
                        }
704
                }
705
        }
706
        if (Elements.count() > 1)
707
        {
708
                bool isGroup = true;
709
                int firstElem = -1;
710
                if (Elements.at(0)->Groups.count() != 0)
711
                        firstElem = Elements.at(0)->Groups.top();
712
                for (int bx = 0; bx < Elements.count(); ++bx)
713
                {
714
                        PageItem* bxi = Elements.at(bx);
715
                        if (bxi->Groups.count() != 0)
716
                        {
717
                                if (bxi->Groups.top() != firstElem)
718
                                        isGroup = false;
719
                        }
720
                        else
721
                                isGroup = false;
722
                }
723
                if (!isGroup)
724
                {
725
                        double minx = 99999.9;
726
                        double miny = 99999.9;
727
                        double maxx = -99999.9;
728
                        double maxy = -99999.9;
729
                        uint lowestItem = 999999;
730
                        uint highestItem = 0;
731
                        for (int a = 0; a < Elements.count(); ++a)
732
                        {
733
                                Elements.at(a)->Groups.push(m_Doc->GroupCounter);
734
                                PageItem* currItem = Elements.at(a);
735
                                lowestItem = qMin(lowestItem, currItem->ItemNr);
736
                                highestItem = qMax(highestItem, currItem->ItemNr);
737
                                double x1, x2, y1, y2;
738
                                currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
739
                                minx = qMin(minx, x1);
740
                                miny = qMin(miny, y1);
741
                                maxx = qMax(maxx, x2);
742
                                maxy = qMax(maxy, y2);
743
                        }
744
                        double gx = minx;
745
                        double gy = miny;
746
                        double gw = maxx - minx;
747
                        double gh = maxy - miny;
748
                        PageItem *high = m_Doc->Items->at(highestItem);
14014 cbradney 749
                        int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, gx, gy, gw, gh, 0, m_Doc->itemToolPrefs.shapeFillColor, m_Doc->itemToolPrefs.shapeLineColor, true);
13951 fschmid 750
                        PageItem *neu = m_Doc->Items->takeAt(z);
751
                        m_Doc->Items->insert(lowestItem, neu);
752
                        neu->Groups.push(m_Doc->GroupCounter);
753
                        neu->setItemName( tr("Group%1").arg(neu->Groups.top()));
754
                        neu->AutoName = false;
755
                        neu->isGroupControl = true;
756
                        neu->groupsLastItem = high;
757
                        for (int a = 0; a < m_Doc->Items->count(); ++a)
758
                        {
759
                                m_Doc->Items->at(a)->ItemNr = a;
760
                        }
761
                        neu->setRedrawBounding();
762
                        neu->setTextFlowMode(PageItem::TextFlowDisabled);
763
                        Elements.prepend(neu);
764
                        m_Doc->GroupCounter++;
765
                }
766
        }
767
        m_Doc->DoDrawing = true;
768
        m_Doc->scMW()->ScriptRunning = false;
769
        if (interactive)
770
                m_Doc->setLoading(false);
771
        qApp->setOverrideCursor(QCursor(Qt::ArrowCursor));
772
        if ((Elements.count() > 0) && (!ret) && (interactive))
773
        {
774
                if (flags & LoadSavePlugin::lfScripted)
775
                {
776
                        bool loadF = m_Doc->isLoading();
777
                        m_Doc->setLoading(false);
778
                        m_Doc->changed();
779
                        m_Doc->setLoading(loadF);
780
                        m_Doc->m_Selection->delaySignalsOn();
781
                        for (int dre=0; dre<Elements.count(); ++dre)
782
                        {
783
                                m_Doc->m_Selection->addItem(Elements.at(dre), true);
784
                        }
785
                        m_Doc->m_Selection->delaySignalsOff();
786
                        m_Doc->m_Selection->setGroupRect();
787
                        m_Doc->view()->updatesOn(true);
788
                        importCanceled = false;
789
                }
790
                else
791
                {
792
                        m_Doc->DragP = true;
793
                        m_Doc->DraggedElem = 0;
794
                        m_Doc->DragElements.clear();
795
                        m_Doc->m_Selection->delaySignalsOn();
796
                        for (int dre=0; dre<Elements.count(); ++dre)
797
                        {
798
                                m_Doc->DragElements.append(Elements.at(dre)->ItemNr);
799
                                m_tmpSel->addItem(Elements.at(dre), true);
800
                        }
801
                        ScriXmlDoc *ss = new ScriXmlDoc();
802
                        m_tmpSel->setGroupRect();
803
                        ScElemMimeData* md = new ScElemMimeData();
804
                        md->setScribusElem(ss->WriteElem(m_Doc, m_Doc->view(), m_tmpSel));
805
                        delete ss;
806
/*#ifndef QT_MAC*/
807
// see #2526
808
                        m_Doc->itemSelection_DeleteItem(m_tmpSel);
809
/*#endif*/
810
                        m_Doc->view()->updatesOn(true);
811
                        m_Doc->m_Selection->delaySignalsOff();
812
                        // We must copy the TransationSettings object as it is owned
813
                        // by handleObjectImport method afterwards
814
                        TransactionSettings* transacSettings = new TransactionSettings(trSettings);
815
                        m_Doc->view()->handleObjectImport(md, transacSettings);
816
                        m_Doc->DragP = false;
817
                        m_Doc->DraggedElem = 0;
818
                        m_Doc->DragElements.clear();
819
                }
820
        }
821
        else
822
        {
823
                bool loadF = m_Doc->isLoading();
824
                m_Doc->setLoading(false);
825
                m_Doc->changed();
826
                m_Doc->reformPages();
827
                m_Doc->view()->updatesOn(true);
828
                m_Doc->setLoading(loadF);
829
        }
830
        return true;
831
}
832
 
833
QList<PageItem*> WMFImport::parseWmfCommands(void)
834
{
835
        int idx, i;
836
        const WmfCmd* cmd;
837
        QList<PageItem*> elements;
838
 
839
        m_context.reset();
840
 
841
        if ( !m_Valid )  return elements;
842
 
843
        if ( m_ObjHandleTab ) delete[] m_ObjHandleTab;
844
        m_ObjHandleTab = new WmfObjHandle* [ MAX_OBJHANDLE ];
845
        for ( i = MAX_OBJHANDLE-1; i >= 0; i-- )
846
                m_ObjHandleTab[ i ] = NULL;
847
 
848
        if ( WMFIMPORT_DEBUG )  {
849
                cerr << "Bounding box : " << m_BBox.left() << " " << m_BBox.top() << " " << m_BBox.right() << " " << m_BBox.bottom() << endl;
850
        }
851
 
852
        double scale  = (m_Dpi > 0) ? 72.0 / m_Dpi : 0.05;
853
        m_context.setViewportOrg( 0, 0 );
854
        m_context.setViewportExt( m_BBox.width() * scale, m_BBox.height() * scale );
855
        m_context.setWindowOrg( m_BBox.left(), m_BBox.bottom() );
856
        m_context.setWindowExt( m_BBox.width(), m_BBox.height() );
857
 
858
        for (int index = 0; index < m_commands.count(); ++index)
859
        {
860
                cmd = m_commands.at(index);
861
                idx = cmd->funcIndex;
862
                ( this->*metaFuncTab[ idx ].method )( elements, cmd->numParam, cmd->params );
863
 
864
                if ( WMFIMPORT_DEBUG )  {
865
                        QString str = "", param;
866
                        if ( metaFuncTab[ idx ].name == NULL ) {
867
                                str += "UNKNOWN ";
868
                        }
869
                        if ( metaFuncTab[ idx ].method == &WMFImport::noop ) {
870
                                str += "UNIMPLEMENTED ";
871
                        }
872
                        str += metaFuncTab[ idx ].name;
873
                        str += " : ";
874
 
875
                        for ( i=0 ; i < cmd->numParam ; i++ ) {
876
                                param.setNum( cmd->params[ i ] );
877
                                str += param;
878
                                str += " ";
879
                        }
880
                        cerr << str.toAscii().data() << endl;
881
                }
882
        }
883
        return elements;
884
}
885
 
886
void WMFImport::finishCmdParsing( PageItem* item )
887
{
888
        QTransform gcm  = m_context.worldMatrix();
889
        double coeff1 = sqrt(gcm.m11() * gcm.m11() + gcm.m12() * gcm.m12());
890
        double coeff2 = sqrt(gcm.m21() * gcm.m21() + gcm.m22() * gcm.m22());
891
        if( item->asImageFrame() )
892
        {
893
                item->moveBy(gcm.dx(), gcm.dy());
894
                item->setWidthHeight(item->width() * gcm.m11(), item->height() * gcm.m22());
895
                item->setLineWidth(qMax(item->lineWidth() * (coeff1 + coeff2) / 2.0, 0.25));
896
                if (item->PictureIsAvailable)
897
                        item->setImageXYScale(item->width() / item->pixm.width(), item->height() / item->pixm.height());
898
        }
899
        else if( item->asTextFrame() )
900
        {
901
                item->setLineWidth(qMax(item->lineWidth() * (coeff1 + coeff2) / 2.0, 0.25));
902
        }
903
        else
904
        {
905
                item->ClipEdited = true;
906
                item->FrameType = 3;
907
                item->PoLine.map(gcm);
908
                item->setLineWidth(qMax(item->lineWidth() * (coeff1 + coeff2) / 2.0, 0.25));
909
                FPoint wh = getMaxClipF(&item->PoLine);
910
                item->setWidthHeight(wh.x(), wh.y());
911
                m_Doc->AdjustItemSize(item);
912
        }
913
        item->setRedrawBounding();
914
        item->OwnPage   = m_Doc->OnPage(item);
915
        item->PLineEnd  = m_context.pen().capStyle();
916
        item->PLineJoin = m_context.pen().joinStyle();
917
        item->setTextFlowMode(PageItem::TextFlowDisabled);
918
        //item->DashOffset = gc->dashOffset;
919
        //item->DashValues = gc->dashArray;
920
}
921
 
922
void WMFImport::setWindowOrg( QList<PageItem*>& /*items*/, long, short* params )
923
{
924
        m_context.setWindowOrg( params[ 1 ], params[ 0 ] );
925
}
926
 
927
void WMFImport::setWindowExt( QList<PageItem*>& /*items*/, long, short* params )
928
{
929
        m_context.setWindowExt( params[ 1 ], params[ 0 ] );
930
}
931
 
932
void WMFImport::lineTo( QList<PageItem*>& items, long, short* params )
933
{
934
        double BaseX = m_Doc->currentPage()->xOffset();
935
        double BaseY = m_Doc->currentPage()->yOffset();
936
        QPoint currentPos = m_context.position();
937
        bool   doStroke = (m_context.pen().style() != Qt::NoPen);
938
        if (doStroke)
939
        {
940
                double x1 = currentPos.x();
941
                double y1 = currentPos.y();
942
                double x2 = params[1];
943
                double y2 = params[0];
944
                double  lineWidth = m_context.pen().width();
945
                QString lineColor = importColor(m_context.pen().color());
946
                int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, lineWidth, CommonStrings::None, lineColor, true);
947
                PageItem* ite = m_Doc->Items->at(z);
948
                ite->PoLine.resize(4);
949
                ite->PoLine.setPoint(0, FPoint(x1, y1));
950
                ite->PoLine.setPoint(1, FPoint(x1, y1));
951
                ite->PoLine.setPoint(2, FPoint(x2, y2));
952
                ite->PoLine.setPoint(3, FPoint(x2, y2));
953
                finishCmdParsing(ite);
954
                items.append(ite);
955
        }
956
        m_context.setPosition( QPoint(params[1], params[0]) );
957
}
958
 
959
void WMFImport::moveTo( QList<PageItem*>& /*items*/, long, short* params )
960
{
961
        m_context.setPosition( QPoint(params[1], params[0]) );
962
}
963
 
964
void WMFImport::ellipse( QList<PageItem*>& items, long, short* params )
965
{
966
        double BaseX = m_Doc->currentPage()->xOffset();
967
        double BaseY = m_Doc->currentPage()->yOffset();
968
        double rx = (params[ 1 ] - params[ 3 ]) / 2.0;
969
        double ry = (params[ 0 ] - params[ 2 ]) / 2.0;
970
        double px = (params[ 1 ] + params[ 3 ]) / 2.0 - rx;
971
        double py = (params[ 0 ] + params[ 2 ]) / 2.0 - ry;
972
        bool   doFill = m_context.brush().style() != Qt::NoBrush;
973
        bool   doStroke = m_context.pen().style() != Qt::NoPen;
974
        QString fillColor   = doFill ? importColor( m_context.brush().color() ) : CommonStrings::None;
975
        QString strokeColor = doStroke ? importColor( m_context.pen().color() ) : CommonStrings::None;
976
        double  lineWidth   = m_context.pen().width();
977
        int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, BaseX, BaseY, rx * 2.0, ry * 2.0, lineWidth, fillColor, strokeColor, true);
978
        PageItem* ite = m_Doc->Items->at(z);
979
        QTransform mm(1.0, 0.0, 0.0, 1.0, px, py);
980
        ite->PoLine.map(mm);
981
        finishCmdParsing(ite);
982
        items.append(ite);
983
}
984
 
985
void WMFImport::polygon( QList<PageItem*>& items, long, short* params )
986
{
987
        //cerr << "WMFImport::polygon unimplemented" << endl;
988
        double  BaseX = m_Doc->currentPage()->xOffset();
989
        double  BaseY = m_Doc->currentPage()->yOffset();
990
        bool    doFill = m_context.brush().style() != Qt::NoBrush;
991
        bool    doStroke = m_context.pen().style() != Qt::NoPen;
992
        QString fillColor   = doFill ? importColor( m_context.brush().color() ) : CommonStrings::None;
993
        QString strokeColor = doStroke ? importColor( m_context.pen().color() ) : CommonStrings::None;
994
        double  lineWidth   = m_context.pen().width();
995
        if (doStroke && lineWidth <= 0.0 )
996
                lineWidth = 1.0;
997
        FPointArray paramPoints = pointsFromParam( params[0], &params[1] );
998
        FPointArray points      = pointsToPolyline( paramPoints, true );
999
        if( paramPoints.size() > 0 )
1000
        {
1001
                int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, lineWidth, fillColor, strokeColor, true);
1002
                PageItem* ite = m_Doc->Items->at(z);
1003
                ite->PoLine = points;
1004
                ite->fillRule = !m_context.windingFill();
1005
                finishCmdParsing(ite);
1006
                items.append(ite);
1007
        }
1008
}
1009
 
1010
void WMFImport::polyPolygon( QList<PageItem*>& items, long num, short* params )
1011
{
1012
        int numPolys   = params[0];
1013
        int pointIndex = params[0] + 1;
1014
        for (int i = 0; i < numPolys; ++i)
1015
        {
1016
                short  numPoints  = params[i + 1];
1017
                short* paramArray = new short[1 + 2 * numPoints];
1018
                paramArray[0] = numPoints;
1019
                memcpy(&paramArray[1], &params[pointIndex], 2 * numPoints * sizeof(short));
1020
                polygon(items, num, paramArray);
1021
                delete[] paramArray;
1022
                pointIndex += (2 * numPoints);
1023
        }
1024
}
1025
 
1026
void WMFImport::polyline( QList<PageItem*>& items, long, short* params )
1027
{
1028
        //cerr << "WMFImport::polyline unimplemented" << endl;
1029
        double  BaseX = m_Doc->currentPage()->xOffset();
1030
        double  BaseY = m_Doc->currentPage()->yOffset();
1031
        bool    doStroke = m_context.pen().style() != Qt::NoPen;
1032
        QString fillColor   = CommonStrings::None;
1033
        QString strokeColor = doStroke ? importColor( m_context.pen().color() ) : CommonStrings::None;
1034
        double  lineWidth   = m_context.pen().width();
1035
        if (doStroke && lineWidth <= 0.0 )
1036
                lineWidth = 1.0;
1037
        FPointArray paramPoints = pointsFromParam( params[0], &params[1] );
1038
        FPointArray points      = pointsToPolyline( paramPoints, false );
1039
        if( paramPoints.size() > 0 )
1040
        {
1041
                int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, lineWidth, fillColor, strokeColor, true);
1042
                PageItem* ite = m_Doc->Items->at(z);
1043
                ite->PoLine = points;
1044
                finishCmdParsing(ite);
1045
                items.append(ite);
1046
        }
1047
}
1048
 
1049
void WMFImport::rectangle( QList<PageItem*>& items, long, short* params )
1050
{
1051
        //cerr << "WMFImport::rectangle unimplemented" << endl;
1052
        double  BaseX = m_Doc->currentPage()->xOffset();
1053
        double  BaseY = m_Doc->currentPage()->yOffset();
1054
        bool    doFill = m_context.brush().style() != Qt::NoBrush;
1055
        bool    doStroke = m_context.pen().style() != Qt::NoPen;
1056
        QString fillColor   = doFill ? importColor( m_context.brush().color() ) : CommonStrings::None;
1057
        QString strokeColor = doStroke ? importColor( m_context.pen().color() ) : CommonStrings::None;
1058
        double  lineWidth   = m_context.pen().width();
1059
        if (doStroke && lineWidth <= 0.0 )
1060
                lineWidth = 1.0;
1061
        double x = ((params[3] - params[1]) > 0) ? params[1] : params[3];
1062
        double y = ((params[2] - params[0]) > 0) ? params[0] : params[2];
1063
        double width  = fabs((double) params[3] - params[1]);
1064
        double height = fabs((double) params[2] - params[0]);
1065
        int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX, BaseY, width, height, lineWidth, fillColor, strokeColor, true);
1066
        PageItem* ite = m_Doc->Items->at(z);
1067
        QTransform mm(1.0, 0.0, 0.0, 1.0, x, y);
1068
        ite->PoLine.map(mm);
1069
        finishCmdParsing(ite);
1070
        items.append(ite);
1071
}
1072
 
1073
void WMFImport::roundRect( QList<PageItem*>& items, long, short* params )
1074
{
1075
        //cerr << "WMFImport::roundRect unimplemented" << endl;
1076
        double  BaseX = m_Doc->currentPage()->xOffset();
1077
        double  BaseY = m_Doc->currentPage()->yOffset();
1078
        bool    doFill = m_context.brush().style() != Qt::NoBrush;
1079
        bool    doStroke = m_context.pen().style() != Qt::NoPen;
1080
        QString fillColor   = doFill ? importColor( m_context.brush().color() ) : CommonStrings::None;
1081
        QString strokeColor = doStroke ? importColor( m_context.pen().color() ) : CommonStrings::None;
1082
        double  lineWidth   = m_context.pen().width();
1083
        if (doStroke && lineWidth <= 0.0 )
1084
                lineWidth = 1.0;
1085
        double x = ((params[5] - params[3]) > 0) ? params[3] : params[5];
1086
        double y = ((params[4] - params[2]) > 0) ? params[2] : params[4];
1087
        double width  = fabs((double) params[5] - params[3]);
1088
        double height = fabs((double) params[4] - params[2]);
1089
        double rx     = params[1] / 2.0;
1090
        double ry     = params[0] / 2.0;
1091
        int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX, BaseY, width, height, lineWidth, fillColor, strokeColor, true);
1092
        PageItem* ite = m_Doc->Items->at(z);
1093
        if ((rx != 0.0) || (ry != 0.0))
1094
        {
1095
                ite->setCornerRadius(qMax(rx, ry));
1096
                ite->SetFrameRound();
1097
                m_Doc->setRedrawBounding(ite);
1098
        }
1099
        QTransform mm(1.0, 0.0, 0.0, 1.0, x, y);
1100
        ite->PoLine.map(mm);
1101
        finishCmdParsing(ite);
1102
        items.append(ite);
1103
}
1104
 
1105
void WMFImport::arc( QList<PageItem*>& items, long, short* params )
1106
{
1107
        FPointArray  pointArray;
1108
        QPainterPath painterPath;
1109
        double  BaseX = m_Doc->currentPage()->xOffset();
1110
        double  BaseY = m_Doc->currentPage()->yOffset();
1111
        bool    doStroke = m_context.pen().style() != Qt::NoPen;
1112
        QString fillColor   = CommonStrings::None;
1113
        QString strokeColor = doStroke ? importColor( m_context.pen().color() ) : CommonStrings::None;
1114
        double  lineWidth   = m_context.pen().width();
1115
        if (doStroke && lineWidth <= 0.0 )
1116
                lineWidth = 1.0;
1117
        double  angleStart, angleLength;
1118
        double  x = ((params[7] - params[5]) > 0) ? params[5] : params[7];
1119
        double  y = ((params[6] - params[4]) > 0) ? params[4] : params[6];
1120
        double  xCenter = (params[5] + params[7]) / 2.0;
1121
        double  yCenter = (params[4] + params[6]) / 2.0;
1122
        double  xWidth  =  fabs((double) params[5] - params[7]);
1123
        double  yHeight =  fabs((double) params[4] - params[6]);
1124
        pointsToAngle(params[3] - xCenter, yCenter - params[2], params[1] - xCenter, yCenter - params[0], angleStart, angleLength);
1125
        painterPath.arcMoveTo(x, y, xWidth, yHeight, angleStart);
1126
        painterPath.arcTo(x, y, xWidth, yHeight, angleStart, angleLength);
1127
        pointArray.fromQPainterPath(painterPath);
1128
        if( pointArray.size() > 0 )
1129
        {
1130
                int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, lineWidth, fillColor, strokeColor, true);
1131
                PageItem* ite = m_Doc->Items->at(z);
1132
                ite->PoLine = pointArray;
1133
                finishCmdParsing(ite);
1134
                items.append(ite);
1135
        }
1136
}
1137
 
1138
void WMFImport::chord( QList<PageItem*>& items, long, short* params )
1139
{
1140
        QPointF      firstPoint;
1141
        FPointArray  pointArray;
1142
        QPainterPath painterPath;
1143
        double  BaseX = m_Doc->currentPage()->xOffset();
1144
        double  BaseY = m_Doc->currentPage()->yOffset();
1145
        bool    doFill   = m_context.brush().style() != Qt::NoBrush;
1146
        bool    doStroke = m_context.pen().style() != Qt::NoPen;
1147
        QString fillColor   = doFill ? importColor( m_context.brush().color() ) : CommonStrings::None;
1148
        QString strokeColor = doStroke ? importColor( m_context.pen().color() ) : CommonStrings::None;
1149
        double  lineWidth   = m_context.pen().width();
1150
        if (doStroke && lineWidth <= 0.0 )
1151
                lineWidth = 1.0;
1152
        double  angleStart, angleLength;
1153
        double  x = ((params[7] - params[5]) > 0) ? params[5] : params[7];
1154
        double  y = ((params[6] - params[4]) > 0) ? params[4] : params[6];
1155
        double  xCenter = (params[5] + params[7]) / 2.0;
1156
        double  yCenter = (params[4] + params[6]) / 2.0;
1157
        double  xWidth  =  fabs((double) params[5] - params[7]);
1158
        double  yHeight =  fabs((double) params[4] - params[6]);
1159
        pointsToAngle(params[3] - xCenter, yCenter - params[2], params[1] - xCenter, yCenter - params[0], angleStart, angleLength);
1160
        painterPath.arcMoveTo(x, y, xWidth, yHeight, angleStart);
1161
        firstPoint = painterPath.currentPosition();
1162
        painterPath.arcTo (x, y, xWidth, yHeight, angleStart, angleLength);
1163
        painterPath.lineTo(firstPoint);
1164
        pointArray.fromQPainterPath(painterPath);
1165
        if( pointArray.size() > 0 )
1166
        {
1167
                int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, lineWidth, fillColor, strokeColor, true);
1168
                PageItem* ite = m_Doc->Items->at(z);
1169
                ite->PoLine = pointArray;
1170
                finishCmdParsing(ite);
1171
                items.append(ite);
1172
        }
1173
}
1174
 
1175
void WMFImport::pie( QList<PageItem*>& items, long, short* params )
1176
{
1177
        QPointF      firstPoint;
1178
        FPointArray  pointArray;
1179
        QPainterPath painterPath;
1180
        double  BaseX = m_Doc->currentPage()->xOffset();
1181
        double  BaseY = m_Doc->currentPage()->yOffset();
1182
        bool    doFill   = m_context.brush().style() != Qt::NoBrush;
1183
        bool    doStroke = m_context.pen().style() != Qt::NoPen;
1184
        QString fillColor   = doFill ? importColor( m_context.brush().color() ) : CommonStrings::None;
1185
        QString strokeColor = doStroke ? importColor( m_context.pen().color() ) : CommonStrings::None;
1186
        double  lineWidth   = m_context.pen().width();
1187
        if (doStroke && lineWidth <= 0.0 )
1188
                lineWidth = 1.0;
1189
        double  angleStart, angleLength;
1190
        double  x = ((params[7] - params[5]) > 0) ? params[5] : params[7];
1191
        double  y = ((params[6] - params[4]) > 0) ? params[4] : params[6];
1192
        double  xCenter = (params[5] + params[7]) / 2.0;
1193
        double  yCenter = (params[4] + params[6]) / 2.0;
1194
        double  xWidth  =  fabs((double) params[5] - params[7]);
1195
        double  yHeight =  fabs((double) params[4] - params[6]);
1196
        pointsToAngle(params[3] - xCenter, yCenter - params[2], params[1] - xCenter, yCenter - params[0], angleStart, angleLength);
1197
        painterPath.arcMoveTo(x,y, xWidth, yHeight, angleStart);
1198
        firstPoint = painterPath.currentPosition();
1199
        painterPath.arcTo (x, y, xWidth, yHeight, angleStart, angleLength);
1200
        painterPath.lineTo(xCenter, yCenter);
1201
        painterPath.lineTo(firstPoint);
1202
        pointArray.fromQPainterPath(painterPath);
1203
        if( pointArray.size() > 0 )
1204
        {
1205
                int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, lineWidth, fillColor, strokeColor, true);
1206
                PageItem* ite = m_Doc->Items->at(z);
1207
                ite->PoLine = pointArray;
1208
                finishCmdParsing(ite);
1209
                items.append(ite);
1210
        }
1211
}
1212
 
1213
void WMFImport::setPolyFillMode( QList<PageItem*>& /*items*/, long, short* params )
1214
{
1215
        m_context.setWindingFill( params[0] );
1216
}
1217
 
1218
void WMFImport::setBkColor( QList<PageItem*>& /*items*/, long, short* params )
1219
{
1220
        m_context.setBackgroundColor( colorFromParam( params ) );
1221
}
1222
 
1223
void WMFImport::setBkMode( QList<PageItem*>& /*items*/, long, short* params )
1224
{
1225
        if ( params[ 0 ]==1 )
1226
                m_context.setBackgroundMode( Qt::TransparentMode );
1227
        else
1228
                m_context.setBackgroundMode( Qt::OpaqueMode );
1229
}
1230
 
1231
void WMFImport::saveDC( QList<PageItem*>& /*items*/, long, short* )
1232
{
1233
        m_context.save();
1234
}
1235
 
1236
void WMFImport::restoreDC( QList<PageItem*>& /*items*/, long, short *params )
1237
{
1238
        for ( int i=0; i > params[ 0 ] ; i-- )
1239
                m_context.restore();
1240
}
1241
 
1242
void WMFImport::intersectClipRect( QList<PageItem*>& /*items*/, long, short* /*params*/ )
1243
{
1244
        cerr << "WMFImport::intersectClipRect unimplemented" << endl;
1245
}
1246
 
1247
void WMFImport::excludeClipRect( QList<PageItem*>& /*items*/, long, short* /*params*/ )
1248
{
1249
        cerr << "WMFImport::excludeClipRect unimplemented" << endl;
1250
}
1251
 
1252
void WMFImport::setTextColor( QList<PageItem*>& /*items*/, long, short* params )
1253
{
1254
        m_context.setTextColor( colorFromParam(params) );
1255
}
1256
 
1257
void WMFImport::setTextAlign( QList<PageItem*>& /*items*/, long, short* params )
1258
{
1259
        m_context.setTextAlign(params[ 0 ]);
1260
}
1261
 
1262
void WMFImport::textOut( QList<PageItem*>& items, long num, short* params )
1263
{
1264
        short *copyParm = new short[num + 1];
1265
 
1266
        // re-order parameters
1267
        int idxOffset = (params[0] / 2) + 1 + (params[0] & 1);
1268
        copyParm[0] = params[idxOffset];
1269
        copyParm[1] = params[idxOffset + 1];
1270
        copyParm[2] = params[0];
1271
        copyParm[3] = 0;
1272
        memcpy( &copyParm[4], &params[1], params[0] );
1273
 
1274
        extTextOut(items, num + 1, copyParm );
1275
        delete [] copyParm;
1276
}
1277
 
1278
void WMFImport::extTextOut( QList<PageItem*>& items, long num, short* params )
1279
{
1280
        QString    textString;
1281
        double  BaseX = m_Doc->currentPage()->xOffset();
1282
        double  BaseY = m_Doc->currentPage()->yOffset();
1283
 
1284
        if (params[3] & 0x0010) // ETO_GLYPH_INDEX
1285
        {
1286
                cerr << "WMFImport::extTextOut: ETO_GLYPH_INDEX option not supported " << endl;
1287
                unsupported = true;
1288
                return;
1289
        }
1290
 
1291
        // ETO_CLIPPED flag add 4 parameters
1292
        char* ptStr = (params[3] & 0x0004) ? ((char*)&params[8]) : ((char*)&params[4]);
1293
        QByteArray textArray( ptStr, params[2] );
1294
 
1295
        QTextCodec* codec = codecFromCharset( m_context.textCharSet() );
1296
        if (codec)
1297
                textString = codec->toUnicode(textArray);
1298
        else if ( m_context.textCharSet() == SYMBOL_CHARSET )
1299
                textString = symbolToUnicode(textArray);
1300
        else
1301
                textString = QString::fromLocal8Bit(textArray.data());
1302
 
1303
        QFontMetrics fm( m_context.font() );
1304
        int width  = fm.width(textString) + fm.descent();  // because fm.width(text) isn't rigth with Italic text
1305
        /*int height = fm.height();
1306
        int ascent = fm.ascent();*/
1307
 
1308
        double startX = params[1], startY = params[0];
1309
        int    textAlign    = m_context.textAlign();
1310
        double textRotation = m_context.textRotation();
1311
        if ( textAlign & 0x01 ) {       // (left, top) position = current logical position
1312
                QPoint pos = m_context.position();
1313
                startX = pos.x();
1314
                startY = pos.y();
1315
        }
1316
 
1317
        m_context.save();
1318
        // A bit hacky but should be sufficient to have text not flipped
1319
        // top down in some wmfs (see cell.wmf sample from libwmf)
1320
        if ( m_context.worldMatrix().m22() < 0.0)
1321
        {
1322
                m_context.translate(startX, startY);
1323
                m_context.scale (1.0, -1.0);
1324
                m_context.translate( -startX, -startY);
1325
        }
1326
        if ( textRotation != 0.0) {
1327
                m_context.translate(startX, startY);
1328
                m_context.rotate ( textRotation );
1329
                m_context.translate( -startX, -startY);
1330
        }
1331
 
1332
        if ( (textAlign & 0x04) && (textAlign & 0x02) ) // TA_CENTER 0x06
1333
                startX -= (width / 2);
1334
        else if ( textAlign & 0x02 ) // TA_RIGHT 0x02
1335
                startX -= width;
1336
        if ( textAlign == 0 ) // TA_TOP                       
1337
                startY += fm.ascent();
1338
 
1339
        bool eto_empty = (params[3] == 0);
1340
        bool eto_clipped_set = (params[3] & 0x0004);
1341
        bool eto_pdy_set     = (params[3] & 0x2000);
1342
 
1343
        int  idxOffset = (params[ 2 ] / 2) + 4 + (params[ 2 ] & 1) + (eto_clipped_set ? 4 : 0);
1344
        int  minParams = eto_pdy_set ? (idxOffset + 2 * (params[2] - 1)) : (idxOffset + params[2]);
1345
        bool useCharInterdistances = (num >= minParams) && (eto_empty || eto_pdy_set);
1346
        if ((params[2] > 1) && useCharInterdistances)
1347
        {
1348
                double xpos  = startX;
1349
                double ypos  = startY;
1350
                double lineWidth = 0.0;
1351
                FPointArray textPath;
1352
                QString textColor = importColor( m_context.textColor() );
1353
                for (int index = 0; (index < params[2] && index < textString.length()); ++index)
1354
                {
1355
                        QPainterPath painterPath;
1356
                        if (index > 0 && eto_pdy_set)
1357
                        {
1358
                                xpos += params[idxOffset + index * 2 - 1];
1359
                                ypos += params[idxOffset + index * 2];
1360
                        }
1361
                        else if (index > 0)
1362
                                xpos += params[idxOffset + index - 1];
1363
                        painterPath.addText(xpos, ypos, m_context.font(), textString.at(index));
1364
                        textPath.fromQPainterPath(painterPath);
1365
                        if (textPath.size() > 0)
1366
                        {
1367
                                int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, lineWidth, textColor, CommonStrings::None, true);
1368
                                PageItem* ite = m_Doc->Items->at(z);
1369
                                ite->PoLine = textPath;
1370
                                finishCmdParsing(ite);
1371
                                items.append(ite);
1372
                        }
1373
                }
1374
        }
1375
        else
1376
        {
1377
                FPointArray textPath;
1378
                QString textColor = importColor( m_context.textColor() );
1379
                QPainterPath painterPath;
1380
                painterPath.addText( startX, startY, m_context.font(), textString );
1381
                textPath.fromQPainterPath(painterPath);
1382
                if (textPath.size() > 0)
1383
                {
1384
                        double  lineWidth = 0.0;
1385
                        int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, lineWidth, textColor, CommonStrings::None, true);
1386
                        PageItem* ite = m_Doc->Items->at(z);
1387
                        ite->PoLine = textPath;
1388
                        finishCmdParsing(ite);
1389
                        items.append(ite);
1390
                }
1391
        }
1392
        m_context.restore();
1393
}
1394
 
1395
void WMFImport::selectObject( QList<PageItem*>& /*items*/, long, short* params )
1396
{
1397
        int idx = params[ 0 ];
1398
        if ( idx >= 0 && idx < MAX_OBJHANDLE && m_ObjHandleTab[ idx ] )
1399
                m_ObjHandleTab[ idx ]->apply( m_context );
1400
}
1401
 
1402
void WMFImport::deleteObject( QList<PageItem*>& /*items*/, long, short* params )
1403
{
1404
        deleteHandle( params[ 0 ] );
1405
}
1406
 
1407
void WMFImport::createEmptyObject( QList<PageItem*>& /*items*/, long, short* )
1408
{
1409
        // allocation of an empty object (to keep object counting in sync)
1410
        WmfObjPenHandle* handle = new WmfObjPenHandle();
1411
        addHandle( handle );
1412
        cerr << "WMFImport: unimplemented createObject " << endl;
1413
}
1414
 
1415
void WMFImport::createBrushIndirect( QList<PageItem*>& /*items*/, long, short* params )
1416
{
1417
        static Qt::BrushStyle hatchedStyleTab[] =
1418
        {
1419
                Qt::HorPattern,
1420
                Qt::FDiagPattern,
1421
                Qt::BDiagPattern,
1422
                Qt::CrossPattern,
1423
                Qt::DiagCrossPattern
1424
        };
1425
        static Qt::BrushStyle styleTab[] =
1426
        { Qt::SolidPattern,
1427
          Qt::NoBrush,
1428
          Qt::FDiagPattern,   /* hatched */
1429
          Qt::Dense4Pattern,  /* should be custom bitmap pattern */
1430
          Qt::HorPattern,     /* should be BS_INDEXED (?) */
1431
          Qt::VerPattern,     /* should be device-independent bitmap */
1432
          Qt::Dense6Pattern,  /* should be device-independent packed-bitmap */
1433
          Qt::Dense2Pattern,  /* should be BS_PATTERN8x8 */
1434
          Qt::Dense3Pattern   /* should be device-independent BS_DIBPATTERN8x8 */
1435
        };
1436
        Qt::BrushStyle style;
1437
        short arg;
1438
        WmfObjBrushHandle* handle = new WmfObjBrushHandle();
1439
        addHandle( handle );
1440
 
1441
        arg = params[0];
1442
        if ( arg == 2 )
1443
        {
1444
                arg = params[3];
1445
                if ( arg >= 0 && arg < 5 )
1446
                        style = hatchedStyleTab[ arg ];
1447
                else
1448
                {
1449
                        cerr << "WMFImport::createBrushIndirect: invalid hatched brush " << arg << endl;
1450
                        style = Qt::SolidPattern;
1451
                }
1452
        }
1453
        else if ( arg >= 0 && arg < 9 )
1454
                style = styleTab[arg];
1455
        else
1456
        {
1457
                cerr << "WMFImport::createBrushIndirect: invalid brush " << arg << endl;
1458
                style = Qt::SolidPattern;
1459
        }
1460
        handle->brush.setStyle( style );
1461
        handle->brush.setColor( colorFromParam( params+1 ) );
1462
}
1463
 
1464
void WMFImport::createPenIndirect( QList<PageItem*>& /*items*/, long, short* params )
1465
{
1466
        static Qt::PenStyle styleTab[] = { Qt::SolidLine, Qt::DashLine, Qt::DotLine, Qt::DashDotLine, Qt::DashDotDotLine,
1467
          Qt::NoPen, Qt::SolidLine };
1468
        Qt::PenStyle style;
1469
        WmfObjPenHandle* handle = new WmfObjPenHandle();
1470
        addHandle( handle );
1471
 
1472
        if ( params[0] >= 0 && params[0] < 6 )
1473
                style = styleTab[ params[0] ];
1474
        else
1475
        {
1476
                cerr << "WMFImport::createPenIndirect: invalid pen " << params[ 0 ] << endl;
1477
                style = Qt::SolidLine;
1478
        }
1479
 
1480
        handle->pen.setStyle( style );
1481
        handle->pen.setWidth( params[1] );
1482
        handle->pen.setColor( colorFromParam( params+3 ) );
1483
        handle->pen.setCapStyle( Qt::RoundCap );
1484
}
1485
 
1486
void WMFImport::createFontIndirect( QList<PageItem*>& /*items*/, long , short* params)
1487
{
1488
        WmfObjFontHandle* handle = new WmfObjFontHandle();
1489
        addHandle( handle );
1490
 
1491
        QString family( (const char*)&params[ 9 ] );
1492
 
1493
        handle->rotation = -params[ 2 ]  / 10; // text rotation (in 1/10 degree)
1494
        handle->font.setFamily( family );
1495
        handle->font.setStyleStrategy( QFont::PreferOutline );
1496
        handle->font.setFixedPitch( ((params[ 8 ] & 0x01) == 0) );
1497
        // TODO: investigation why some test case need -2. (size of font in logical point)
1498
        int fontSize = (params[0] != 0) ? (qAbs(params[0]) - 2) : 12;
1499
        handle->font.setPixelSize( fontSize );
1500
        handle->font.setWeight( (params[ 4 ] >> 3) );
1501
        handle->font.setItalic( (params[ 5 ] & 0x01) );
1502
        handle->font.setUnderline( (params[ 5 ] & 0x100) );
1503
        handle->font.setStrikeOut( (params[ 6 ] & 0x01) );
1504
        handle->charset = (params[ 6 ] & 0xFF00) >> 8;
1505
}
1506
 
1507
void WMFImport::noop( QList<PageItem*>& /*items*/, long, short* )
1508
{
1509
}
1510
 
1511
void WMFImport::end( QList<PageItem*>& /*items*/, long, short* )
1512
{
1513
        //cerr << "WMFImport::end unimplemented" << endl;
1514
}
1515
 
1516
void WMFImport::addHandle( WmfObjHandle* handle )
1517
{
1518
        int idx;
1519
 
1520
        for ( idx =0; idx < MAX_OBJHANDLE ; idx++ )
1521
                if ( m_ObjHandleTab[ idx ] == NULL )  break;
1522
 
1523
        if ( idx < MAX_OBJHANDLE )
1524
                m_ObjHandleTab[ idx ] = handle;
1525
        else
1526
                cerr << "WMFImport error: handle table full !" << endl;
1527
}
1528
 
1529
void WMFImport::deleteHandle( int idx )
1530
{
1531
        if ( idx >= 0 && idx < MAX_OBJHANDLE && m_ObjHandleTab[ idx ] )
1532
        {
1533
                delete m_ObjHandleTab[ idx ];
1534
                m_ObjHandleTab[ idx ] = NULL;
1535
        }
1536
}
1537
 
1538
unsigned short WMFImport::calcCheckSum( WmfPlaceableHeader* apmfh )
1539
{
1540
        WORD16*  lpWord;
1541
        WORD16   wResult, i;
1542
 
1543
        // Start with the first word
1544
        wResult = *( lpWord = ( WORD16* )( apmfh ) );
1545
        // XOR in each of the other 9 words
1546
        for( i=1; i<=9; i++ )
1547
        {
1548
                wResult ^= lpWord[ i ];
1549
        }
1550
        return wResult;
1551
}
1552
 
1553
int WMFImport::findFunc( unsigned short aFunc ) const
1554
{
1555
        int i = 0;
1556
 
1557
        for ( i=0; metaFuncTab[ i ].name; i++ )
1558
                if ( metaFuncTab[ i ].func == aFunc ) return i;
1559
 
1560
        // here : unknown function
1561
        return i;
1562
}
1563
 
1564
unsigned int WMFImport::toDWord( short* params )
1565
{
1566
        unsigned int l;
1567
#if !defined( WORDS_BIGENDIAN )
1568
        l = *( unsigned int* )( params );
1569
#else
1570
        char *bytes;
1571
        char swap[ 4 ];
1572
        bytes = ( char* )params;
1573
        swap[ 0 ] = bytes[ 2 ];
1574
        swap[ 1 ] = bytes[ 3 ];
1575
        swap[ 2 ] = bytes[ 0 ];
1576
        swap[ 3 ] = bytes[ 1 ];
1577
        l = *( unsigned int* )( swap );
1578
#endif
1579
        return l;
1580
}