00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "scconfig.h"
00011 #include "wmfimport.h"
00012
00013 #include <QCursor>
00014 #include <QDrag>
00015 #include <QBuffer>
00016 #include <QDataStream>
00017 #include <QFile>
00018 #include <QMimeData>
00019 #include <QPainterPath>
00020 #include <QRegExp>
00021
00022 #include "customfdialog.h"
00023 #include "scribus.h"
00024 #include "scribusXml.h"
00025 #include "propertiespalette.h"
00026 #include "prefsfile.h"
00027
00028 #include <cmath>
00029 #include "commonstrings.h"
00030 #include "fpointarray.h"
00031 #include "menumanager.h"
00032 #include "prefsmanager.h"
00033 #include "pageitem.h"
00034 #include "scraction.h"
00035 #include "scribuscore.h"
00036 #include "scribusdoc.h"
00037 #include "selection.h"
00038 #include "undomanager.h"
00039 #include "loadsaveplugin.h"
00040 #include "util.h"
00041 #include "util_icon.h"
00042 #include "util_math.h"
00043 #include "fonts/scfontmetrics.h"
00044
00045 using namespace std;
00046
00047 #include "wmfstruct.h"
00048 #include "wmfcmd.h"
00049 #include "wmfcontext.h"
00050 #include "wmfhandle.h"
00051 #include "metafuncs.h"
00052
00053 #define WMFIMPORT_DEBUG 1
00054 #define MAX_OBJHANDLE 128
00055
00056 #define ANSI_CHARSET 0 // ANSI charset (Windows-1252)
00057 #define DEFAULT_CHARSET 1
00058 #define SYMBOL_CHARSET 2
00059 #define MAC_CHARSET 77
00060 #define SHIFTJIS_CHARSET 128 // Shift JIS charset (Windows-932)
00061 #define HANGEUL_CHARSET 129 // Hangeul charset (Windows-949)
00062 #define JOHAB_CHARSET 130 // Johab charset (Windows-1361)
00063 #define GB2312_CHARSET 134 // GB2312 charset (Windows-936)
00064 #define CHINESEBIG5_CHARSET 136 // Chinese Big5 charset (Windows-950)
00065 #define GREEK_CHARSET 161 // Greek charset (Windows-1253)
00066 #define TURKISH_CHARSET 162 // Turkish charset (Windows-1254)
00067 #define VIETNAMESE_CHARSET 163 // Vietnamese charset (Windows-1258)
00068 #define HEBREW_CHARSET 177 // Hebrew charset (Windows-1255)
00069 #define ARABIC_CHARSET 178 // Arabic charset (Windows-1256)
00070 #define BALTIC_CHARSET 186 // Baltic charset (Windows-1257)
00071 #define RUSSIAN_CHARSET 204 // Cyrillic charset (Windows-1251)
00072 #define THAI_CHARSET 222 // Thai charset (Windows-874)
00073 #define EASTEUROPE_CHARSET 238 // Eastern european charset (Windows-1250)
00074 #define OEM_CHARSET 255
00075
00076
00077
00078 static const ushort greek_symbol_to_unicode[64] = {
00079
00080
00081
00082
00083 0x0391, 0x0392, 0x03A7, 0x0394, 0x0395, 0x03A6, 0x0393, 0x0397,
00084
00085 0x0399, 0x03D1, 0x039A, 0x039B, 0x039C, 0x039D, 0x039F, 0x03A0,
00086
00087 0x0398, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03DB, 0x03A9, 0x039E,
00088
00089 0x03A8, 0x0396, 0x03EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
00090
00091
00092
00093
00094 0x03B1, 0x03B2, 0x03C7, 0x03B4, 0x03B5, 0x03D5, 0x03B3, 0x03B7,
00095
00096 0x03B9, 0x03C6, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BF, 0x03C0,
00097
00098 0x03B8, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03D6, 0x03B9, 0x03BE,
00099
00100 0x03C8, 0x03B6, 0x03EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD
00101 };
00102
00103
00104
00105 static const ushort symbol_to_unicode[96] = {
00106
00107
00108
00109
00110 0x03D2, 0x0374, 0x2264, 0x2215, 0x221E, 0x0395, 0x2663, 0x2666,
00111
00112 0x2665, 0x2660, 0x2194, 0x2190, 0x2191, 0x2192, 0x2193, 0x2218,
00113
00114 0x0398, 0x03A1, 0x2265, 0x03A4, 0x221D, 0x2202, 0x2219, 0x03A8,
00115
00116 0x2260, 0x2261, 0xFFFD, 0x22EF, 0x2223, 0x2212, 0xFFFD, 0xFFFD,
00117
00118
00119
00120
00121 0x03B1, 0x03B2, 0x03C7, 0x03B4, 0x03B5, 0x03D5, 0x03B3, 0x03B7,
00122
00123 0x03B9, 0x03C6, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BF, 0x03C0,
00124
00125 0x03B8, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03D6, 0x03B9, 0x03BE,
00126
00127 0x03C8, 0x03B6, 0x21D4, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD,
00128
00129
00130
00131 0x03B1, 0x03B2, 0x03C7, 0x03B4, 0x2211, 0x03D5, 0x03B3, 0x03B7,
00132
00133 0x03B9, 0x03C6, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BF, 0x03C0,
00134
00135 0x03B8, 0x222b, 0x03C3, 0x03C4, 0x03C5, 0x03D6, 0x03B9, 0x03BE,
00136
00137 0x03C8, 0x03B6, 0x03EA, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD, 0xFFFD
00138 };
00139
00140 WMFImport::WMFImport( ScribusMainWindow* mw, int flags ) :
00141 QObject(mw)
00142 {
00143 m_tmpSel = new Selection(this, false);
00144 m_Doc = mw->doc;
00145 unsupported = false;
00146 importFailed = false;
00147 importCanceled = true;
00148 importedColors.clear();
00149 m_docDesc = "";
00150 m_docTitle = "";
00151 interactive = (flags & LoadSavePlugin::lfInteractive);
00152
00153 m_Valid = false;
00154 m_ObjHandleTab = NULL;
00155 m_Dpi = 1440;
00156 }
00157
00158 WMFImport::~WMFImport()
00159 {
00160 qDeleteAll(m_commands);
00161 m_commands.clear();
00162 if ( m_tmpSel) delete m_tmpSel;
00163 if ( m_ObjHandleTab )
00164 {
00165 for (int i = 0; i < MAX_OBJHANDLE; ++i)
00166 {
00167 if (m_ObjHandleTab[i])
00168 delete m_ObjHandleTab[i];
00169 }
00170 delete[] m_ObjHandleTab;
00171 }
00172 }
00173
00174 QString WMFImport::importColor(const QColor& color)
00175 {
00176 bool found = false;
00177 int r, g, b;
00178 QColor tmpColor;
00179 QString retColorName;
00180 ColorList::Iterator it;
00181 for (it = m_Doc->PageColors.begin(); it != m_Doc->PageColors.end(); ++it)
00182 {
00183 if (it.value().getColorModel() == colorModelRGB)
00184 {
00185 it.value().getRGB(&r, &g, &b);
00186 tmpColor.setRgb(r, g, b);
00187 if (color == tmpColor)
00188 {
00189 retColorName = it.key();
00190 found = true;
00191 }
00192 }
00193 }
00194 if (!found)
00195 {
00196 ScColor tmp;
00197 tmp.fromQColor(color);
00198 tmp.setSpotColor(false);
00199 tmp.setRegistrationColor(false);
00200 m_Doc->PageColors.insert("FromWMF"+color.name(), tmp);
00201 importedColors.append("FromWMF"+color.name());
00202 retColorName = "FromWMF"+color.name();
00203 }
00204 return retColorName;
00205 }
00206
00207 QColor WMFImport::colorFromParam( short* params )
00208 {
00209 unsigned int colorRef;
00210 int red, green, blue;
00211
00212 colorRef = toDWord( params ) & 0xffffff;
00213 red = colorRef & 255;
00214 green = ( colorRef>>8 ) & 255;
00215 blue = ( colorRef>>16 ) & 255;
00216
00217 return QColor( red, green, blue );
00218 }
00219
00220 QTextCodec* WMFImport::codecFromCharset( int charset )
00221 {
00222 QTextCodec* codec = NULL;
00223 if (charset == DEFAULT_CHARSET || charset == OEM_CHARSET)
00224 codec = QTextCodec::codecForLocale();
00225 else if (charset == ANSI_CHARSET)
00226 codec = QTextCodec::codecForName("windows-1252");
00227
00228
00229 else if (charset == MAC_CHARSET)
00230 codec = QTextCodec::codecForName("Apple Roman");
00231 else if (charset == SHIFTJIS_CHARSET)
00232 codec = QTextCodec::codecForName("Shift-JIS");
00233 else if (charset == HANGEUL_CHARSET)
00234 codec = QTextCodec::codecForName("CP949");
00235 else if (charset == GB2312_CHARSET)
00236 codec = QTextCodec::codecForName("CP936");
00237 else if (charset == CHINESEBIG5_CHARSET)
00238 codec = QTextCodec::codecForName("Big5");
00239 else if (charset == GREEK_CHARSET)
00240 codec = QTextCodec::codecForName("windows-1253");
00241 else if (charset == TURKISH_CHARSET)
00242 codec = QTextCodec::codecForName("windows-1254");
00243 else if (charset == VIETNAMESE_CHARSET)
00244 codec = QTextCodec::codecForName("windows-1258");
00245 else if (charset == HEBREW_CHARSET)
00246 codec = QTextCodec::codecForName("windows-1255");
00247 else if (charset == ARABIC_CHARSET)
00248 codec = QTextCodec::codecForName("windows-1256");
00249 else if (charset == BALTIC_CHARSET)
00250 codec = QTextCodec::codecForName("windows-1257");
00251 else if (charset == RUSSIAN_CHARSET)
00252 codec = QTextCodec::codecForName("windows-1251");
00253 else if (charset == THAI_CHARSET)
00254 codec = QTextCodec::codecForName("CP874");
00255 else if (charset == EASTEUROPE_CHARSET)
00256 codec = QTextCodec::codecForName("windows-1250");
00257 return codec;
00258 }
00259
00260 QString WMFImport::symbolToUnicode ( const QByteArray& chars )
00261 {
00262
00263
00264 QString r;
00265 const unsigned char * c = (const unsigned char *) chars.data();
00266
00267 if( chars.size() == 0 ) return r;
00268
00269 for (int i = 0; i < chars.size(); ++i)
00270 {
00271 if ( 64 < c[i] && c[i] <= 64+32 )
00272 r.append( QChar(greek_symbol_to_unicode[c[i]-65]) );
00273 else if (64+32+1 <= c[i] && c[i] < 64+32+32+1)
00274 r.append( QChar(greek_symbol_to_unicode[c[i]-65-32]+32) );
00275 else if (161 <= c[i] )
00276 r.append( QChar(symbol_to_unicode[c[i]-161]) );
00277 else
00278 r.append( QChar(c[i]) );
00279 }
00280 return r;
00281 }
00282
00283 FPointArray WMFImport::pointsFromParam( short num, short* params )
00284 {
00285 FPointArray points;
00286 points.resize( num );
00287
00288 for ( int i = 0; i < num; i++, params += 2 )
00289 points.setPoint( i, params[ 0 ], params[ 1 ] );
00290
00291 return points;
00292 }
00293
00294 FPointArray WMFImport::pointsToPolyline( const FPointArray& points, bool closePath )
00295 {
00296 bool bFirst = true;
00297 double x = 0.0, y = 0.0;
00298 FPointArray polyline;
00299 polyline.svgInit();
00300 for( uint i = 0; i < points.size(); ++i )
00301 {
00302 FPoint point = points.point(i);
00303 if( bFirst )
00304 {
00305 x = point.x();
00306 y = point.y();
00307 polyline.svgMoveTo(x, y);
00308 bFirst = false;
00309 }
00310 else
00311 {
00312 x = point.x();
00313 y = point.y();
00314 polyline.svgLineTo(x, y);
00315 }
00316 }
00317 if (closePath && (points.size() > 4))
00318 polyline.svgClosePath();
00319 return polyline;
00320 }
00321
00322 void WMFImport::pointsToAngle( double xStart, double yStart, double xEnd, double yEnd, double& angleStart, double& angleLength )
00323 {
00324 double aStart = atan2( yStart, xStart );
00325 double aLength = atan2( yEnd, xEnd ) - aStart;
00326
00327 angleStart = (int)(aStart * 180.0 / 3.14166);
00328 angleLength = (int)(aLength * 180.0 / 3.14166);
00329 if ( angleLength < 0 ) angleLength = 360.0 + angleLength;
00330 }
00331
00332 bool WMFImport::import(QString fname, int flags)
00333 {
00334 if (!loadWMF(fname))
00335 {
00336 importFailed = true;
00337 return false;
00338 }
00339 QString CurDirP = QDir::currentPath();
00340 QFileInfo efp(fname);
00341 QDir::setCurrent(efp.path());
00342 importWMF(flags);
00343 QDir::setCurrent(CurDirP);
00344 return true;
00345 }
00346
00347 bool WMFImport::loadWMF( const QString &fileName )
00348 {
00349 QFile file( fileName );
00350
00351 if ( !file.exists() )
00352 {
00353 cerr << "File " << QFile::encodeName(fileName).data() << " does not exist" << endl;
00354 return false;
00355 }
00356
00357 if ( !file.open( QIODevice::ReadOnly ) )
00358 {
00359 cerr << "Cannot open file " << QFile::encodeName(fileName).data() << endl;
00360 return false;
00361 }
00362
00363 QByteArray ba = file.readAll();
00364 file.close();
00365
00366 QBuffer buffer( &ba );
00367 buffer.open( QIODevice::ReadOnly );
00368 return loadWMF( buffer );
00369 }
00370
00371 bool WMFImport::loadWMF( QBuffer &buffer )
00372 {
00373 QDataStream st;
00374 WmfEnhMetaHeader eheader;
00375 WmfMetaHeader header;
00376 WmfPlaceableHeader pheader;
00377 WORD16 checksum;
00378 int filePos, idx, i;
00379 WmfCmd *cmd;
00380 WORD32 rdSize;
00381 WORD16 rdFunc;
00382
00383 header.mtSize = 0;
00384 header.mtHeaderSize = 0;
00385 header.mtNoParameters = 0;
00386
00387 qDeleteAll(m_commands);
00388 m_commands.clear();
00389
00390 st.setDevice( &buffer );
00391 st.setByteOrder( QDataStream::LittleEndian );
00392
00393
00394 st >> pheader.key;
00395 m_IsPlaceable = ( pheader.key==( DWORD )APMHEADER_KEY );
00396 if ( m_IsPlaceable )
00397 {
00398 st >> pheader.hmf;
00399 st >> pheader.bbox.left;
00400 st >> pheader.bbox.top;
00401 st >> pheader.bbox.right;
00402 st >> pheader.bbox.bottom;
00403 st >> pheader.inch;
00404 st >> pheader.reserved;
00405 st >> pheader.checksum;
00406 checksum = calcCheckSum( &pheader );
00407 if ( pheader.checksum!=checksum ) m_IsPlaceable = false;
00408
00409 m_Dpi = pheader.inch;
00410 m_BBox.setLeft( pheader.bbox.left );
00411 m_BBox.setTop( pheader.bbox.top );
00412 m_BBox.setRight( pheader.bbox.right );
00413 m_BBox.setBottom( pheader.bbox.bottom );
00414 m_HeaderBoundingBox = m_BBox;
00415 if ( WMFIMPORT_DEBUG )
00416 {
00417 cerr << endl << "-------------------------------------------------" << endl;
00418 cerr << "WMF Placeable Header ( " << static_cast<int>(sizeof( pheader ) ) << "):" << endl;
00419 cerr << " bbox=( " << m_BBox.left() << "; " << m_BBox.top() << "; " << m_BBox.width() << "; " << m_BBox.height() << ")" << endl;
00420 cerr << " inch=" << pheader.inch << endl;
00421 cerr << " checksum=" << pheader.checksum << "( " << (pheader.checksum==checksum?"ok":"wrong") << " )" << endl;
00422 }
00423 }
00424 else buffer.seek( 0 );
00425
00426
00427 filePos = buffer.pos();
00428 st >> eheader.iType;
00429 st >> eheader.nSize;
00430 st >> eheader.rclBounds.left;
00431 st >> eheader.rclBounds.top;
00432 st >> eheader.rclBounds.right;
00433 st >> eheader.rclBounds.bottom;
00434 st >> eheader.rclFrame.left;
00435 st >> eheader.rclFrame.top;
00436 st >> eheader.rclFrame.right;
00437 st >> eheader.rclFrame.bottom;
00438 st >> eheader.dSignature;
00439 m_IsEnhanced = ( eheader.dSignature==ENHMETA_SIGNATURE );
00440 if ( m_IsEnhanced )
00441 {
00442 st >> eheader.nVersion;
00443 st >> eheader.nBytes;
00444 st >> eheader.nRecords;
00445 st >> eheader.nHandles;
00446 st >> eheader.sReserved;
00447 st >> eheader.nDescription;
00448 st >> eheader.offDescription;
00449 st >> eheader.nPalEntries;
00450 st >> eheader.szlDevice.width;
00451 st >> eheader.szlDevice.height;
00452 st >> eheader.szlMillimeters.width;
00453 st >> eheader.szlMillimeters.height;
00454
00455 if ( WMFIMPORT_DEBUG )
00456 {
00457 cerr << endl << "-------------------------------------------------" << endl;
00458 cerr << "WMF Extended Header:" << endl;
00459 cerr << " iType=" << eheader.iType << endl;
00460 cerr << " nSize=" << eheader.nSize << endl;
00461 cerr << " rclBounds=( " << eheader.rclBounds.left << "; " << eheader.rclBounds.top << "; "
00462 << eheader.rclBounds.right << "; " << eheader.rclBounds.bottom << ")" << endl;
00463 cerr << " rclFrame=( " << eheader.rclFrame.left << "; " << eheader.rclFrame.top << "; "
00464 << eheader.rclFrame.right << "; " << eheader.rclFrame.bottom << ")" << endl;
00465 cerr << " nBytes=" << eheader.nBytes << endl;
00466 cerr << "\nNOT YET IMPLEMENTED, SORRY." << endl;
00467 }
00468 }
00469 else
00470 {
00471
00472 buffer.seek( filePos );
00473 st >> header.mtType;
00474 st >> header.mtHeaderSize;
00475 st >> header.mtVersion;
00476 st >> header.mtSize;
00477 st >> header.mtNoObjects;
00478 st >> header.mtMaxRecord;
00479 st >> header.mtNoParameters;
00480 if ( WMFIMPORT_DEBUG ) {
00481 cerr << "WMF Header: " << "mtSize=" << header.mtSize << endl;
00482 }
00483 }
00484
00485
00486 m_Valid = ((header.mtHeaderSize == 9) && (header.mtNoParameters == 0)) || m_IsEnhanced || m_IsPlaceable;
00487 if ( m_Valid )
00488 {
00489
00490 rdFunc = -1;
00491 while ( !st.atEnd() && (rdFunc != 0) )
00492 {
00493 st >> rdSize;
00494 st >> rdFunc;
00495 idx = findFunc( rdFunc );
00496 rdSize -= 3;
00497
00498 cmd = new WmfCmd;
00499 m_commands.append(cmd);
00500
00501 cmd->funcIndex = idx;
00502 cmd->numParam = rdSize;
00503 cmd->params = new WORD16[ rdSize ];
00504
00505 for ( i=0; i<rdSize && !st.atEnd(); i++ )
00506 st >> cmd->params[ i ];
00507
00508
00509 if ( rdFunc == 0x020B && !m_IsPlaceable) {
00510 m_BBox.setLeft( qMin((int) cmd->params[ 1 ], m_BBox.left()) );
00511 m_BBox.setTop ( qMin((int) cmd->params[ 0 ], m_BBox.top()) );
00512 }
00513 if ( rdFunc == 0x020C && !m_IsPlaceable ) {
00514 m_BBox.setWidth ( qMax((int) cmd->params[ 1 ], m_BBox.width()) );
00515 m_BBox.setHeight( qMax((int) cmd->params[ 0 ], m_BBox.height()));
00516 }
00517
00518 if ( i<rdSize )
00519 {
00520 cerr << "WMF : file truncated !" << endl;
00521 return false;
00522 }
00523 }
00524
00525 m_Valid = (rdFunc == 0) && (m_BBox.width() != 0) && (m_BBox.height() != 0);
00526 if ( !m_Valid ) {
00527 cerr << "WMF : incorrect file format !" << endl;
00528 }
00529 }
00530 else {
00531 cerr << "WMF Header : incorrect header !" << endl;
00532 }
00533
00534 buffer.close();
00535 return m_Valid;
00536 }
00537
00538 bool WMFImport::importWMF(int flags)
00539 {
00540 bool ret = false;
00541
00542 double scale = (m_Dpi > 0) ? 72.0 / m_Dpi : 0.05;
00543 double width = m_BBox.width() * scale;
00544 double height = m_BBox.height() * scale;
00545 if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
00546 {
00547 m_Doc->setPage(fabs(width), fabs(height), 0, 0, 0, 0, 0, 0, false, false);
00548 m_Doc->addPage(0);
00549 m_Doc->view()->addPage(0);
00550 }
00551 else
00552 {
00553 if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
00554 {
00555 m_Doc=ScCore->primaryMainWindow()->doFileNew(fabs(width), fabs(height), 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
00556 ScCore->primaryMainWindow()->HaveNewDoc();
00557 ret = true;
00558 }
00559 }
00560 if ((ret) || (!interactive))
00561 {
00562 if (width > height)
00563 m_Doc->PageOri = 1;
00564 else
00565 m_Doc->PageOri = 0;
00566 m_Doc->m_pageSize = "Custom";
00567 }
00568 FPoint minSize = m_Doc->minCanvasCoordinate;
00569 FPoint maxSize = m_Doc->maxCanvasCoordinate;
00570 FPoint cOrigin = m_Doc->view()->canvasOrigin();
00571 m_Doc->view()->Deselect();
00572 m_Doc->setLoading(true);
00573 m_Doc->DoDrawing = false;
00574 m_Doc->view()->updatesOn(false);
00575 m_Doc->scMW()->ScriptRunning = true;
00576 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
00577
00578 m_Doc->PageColors.ensureBlackAndWhite();
00579
00580 QList<PageItem*> Elements = parseWmfCommands();
00581 if (flags & LoadSavePlugin::lfCreateDoc)
00582 {
00583 m_Doc->documentInfo.setTitle(m_docTitle);
00584 m_Doc->documentInfo.setComments(m_docDesc);
00585 }
00586 m_tmpSel->clear();
00587 if (Elements.count() == 0)
00588 {
00589 importFailed = true;
00590 if (importedColors.count() != 0)
00591 {
00592 for (int cd = 0; cd < importedColors.count(); cd++)
00593 {
00594 m_Doc->PageColors.remove(importedColors[cd]);
00595 }
00596 }
00597 }
00598 if (Elements.count() > 1)
00599 {
00600 bool isGroup = true;
00601 int firstElem = -1;
00602 if (Elements.at(0)->Groups.count() != 0)
00603 firstElem = Elements.at(0)->Groups.top();
00604 for (int bx = 0; bx < Elements.count(); ++bx)
00605 {
00606 PageItem* bxi = Elements.at(bx);
00607 if (bxi->Groups.count() != 0)
00608 {
00609 if (bxi->Groups.top() != firstElem)
00610 isGroup = false;
00611 }
00612 else
00613 isGroup = false;
00614 }
00615 if (!isGroup)
00616 {
00617 double minx = 99999.9;
00618 double miny = 99999.9;
00619 double maxx = -99999.9;
00620 double maxy = -99999.9;
00621 uint lowestItem = 999999;
00622 uint highestItem = 0;
00623 for (int a = 0; a < Elements.count(); ++a)
00624 {
00625 Elements.at(a)->Groups.push(m_Doc->GroupCounter);
00626 PageItem* currItem = Elements.at(a);
00627 lowestItem = qMin(lowestItem, currItem->ItemNr);
00628 highestItem = qMax(highestItem, currItem->ItemNr);
00629 double lw = currItem->lineWidth() / 2.0;
00630 if (currItem->rotation() != 0)
00631 {
00632 FPointArray pb;
00633 pb.resize(0);
00634 pb.addPoint(FPoint(currItem->xPos()-lw, currItem->yPos()-lw));
00635 pb.addPoint(FPoint(currItem->width()+lw*2.0, -lw, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00636 pb.addPoint(FPoint(currItem->width()+lw*2.0, currItem->height()+lw*2.0, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00637 pb.addPoint(FPoint(-lw, currItem->height()+lw*2.0, currItem->xPos()-lw, currItem->yPos()-lw, currItem->rotation(), 1.0, 1.0));
00638 for (uint pc = 0; pc < 4; ++pc)
00639 {
00640 minx = qMin(minx, pb.point(pc).x());
00641 miny = qMin(miny, pb.point(pc).y());
00642 maxx = qMax(maxx, pb.point(pc).x());
00643 maxy = qMax(maxy, pb.point(pc).y());
00644 }
00645 }
00646 else
00647 {
00648 minx = qMin(minx, currItem->xPos()-lw);
00649 miny = qMin(miny, currItem->yPos()-lw);
00650 maxx = qMax(maxx, currItem->xPos()-lw + currItem->width()+lw*2.0);
00651 maxy = qMax(maxy, currItem->yPos()-lw + currItem->height()+lw*2.0);
00652 }
00653 }
00654 double gx = minx;
00655 double gy = miny;
00656 double gw = maxx - minx;
00657 double gh = maxy - miny;
00658 PageItem *high = m_Doc->Items->at(highestItem);
00659 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, gx, gy, gw, gh, 0, m_Doc->toolSettings.dBrush, m_Doc->toolSettings.dPen, true);
00660 PageItem *neu = m_Doc->Items->takeAt(z);
00661 m_Doc->Items->insert(lowestItem, neu);
00662 neu->Groups.push(m_Doc->GroupCounter);
00663 neu->setItemName( tr("Group%1").arg(neu->Groups.top()));
00664 neu->isGroupControl = true;
00665 neu->groupsLastItem = high;
00666 for (int a = 0; a < m_Doc->Items->count(); ++a)
00667 {
00668 m_Doc->Items->at(a)->ItemNr = a;
00669 }
00670 neu->setRedrawBounding();
00671 neu->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
00672 Elements.prepend(neu);
00673 m_Doc->GroupCounter++;
00674 }
00675 }
00676 m_Doc->DoDrawing = true;
00677 m_Doc->scMW()->ScriptRunning = false;
00678 if (interactive)
00679 m_Doc->setLoading(false);
00680 qApp->setOverrideCursor(QCursor(Qt::ArrowCursor));
00681 if ((Elements.count() > 0) && (!ret) && (interactive))
00682 {
00683 if (flags & LoadSavePlugin::lfScripted)
00684 {
00685 bool loadF = m_Doc->isLoading();
00686 m_Doc->setLoading(false);
00687 m_Doc->changed();
00688 m_Doc->setLoading(loadF);
00689 for (int dre=0; dre<Elements.count(); ++dre)
00690 {
00691 m_Doc->m_Selection->addItem(Elements.at(dre), true);
00692 }
00693 m_Doc->m_Selection->setGroupRect();
00694 m_Doc->view()->updatesOn(true);
00695 importCanceled = false;
00696 }
00697 else
00698 {
00699 m_Doc->DragP = true;
00700 m_Doc->DraggedElem = 0;
00701 m_Doc->DragElements.clear();
00702 for (int dre=0; dre<Elements.count(); ++dre)
00703 {
00704 m_Doc->DragElements.append(Elements.at(dre)->ItemNr);
00705 m_tmpSel->addItem(Elements.at(dre), true);
00706 }
00707 ScriXmlDoc *ss = new ScriXmlDoc();
00708 m_tmpSel->setGroupRect();
00709 QMimeData* md = new QMimeData();
00710 md->setText(ss->WriteElem(m_Doc, m_Doc->view(), m_tmpSel));
00711 QDrag* dr = new QDrag(m_Doc->view()->viewport());
00712 dr->setMimeData(md);
00713 #ifndef QT_MAC
00714
00715 m_Doc->itemSelection_DeleteItem(m_tmpSel);
00716 #endif
00717
00718
00719 m_Doc->minCanvasCoordinate = minSize;
00720 m_Doc->maxCanvasCoordinate = maxSize;
00721 m_Doc->view()->adjustCanvas(qRound((maxSize.x() - minSize.x()) * m_Doc->view()->scale()), qRound((maxSize.y() - minSize.y()) * m_Doc->view()->scale()), 0, 0);
00722 m_Doc->view()->setCanvasOrigin(cOrigin.x(), cOrigin.y());
00723 m_Doc->view()->updatesOn(true);
00724
00725 const QPixmap& dragCursor = loadIcon("DragPix.xpm");
00726 dr->setDragCursor(dragCursor, Qt::CopyAction);
00727 dr->setDragCursor(dragCursor, Qt::MoveAction);
00728 dr->setDragCursor(dragCursor, Qt::LinkAction);
00729 dr->exec();
00730 delete ss;
00731 m_Doc->DragP = false;
00732 m_Doc->DraggedElem = 0;
00733 m_Doc->DragElements.clear();
00734 }
00735 }
00736 else
00737 {
00738 bool loadF = m_Doc->isLoading();
00739 m_Doc->setLoading(false);
00740 m_Doc->changed();
00741 m_Doc->reformPages();
00742 m_Doc->view()->updatesOn(true);
00743 m_Doc->setLoading(loadF);
00744 }
00745 return true;
00746 }
00747
00748 QList<PageItem*> WMFImport::parseWmfCommands(void)
00749 {
00750 int idx, i;
00751 const WmfCmd* cmd;
00752 QList<PageItem*> elements;
00753
00754 m_context.reset();
00755
00756 if ( !m_Valid ) return elements;
00757
00758 if ( m_ObjHandleTab ) delete[] m_ObjHandleTab;
00759 m_ObjHandleTab = new WmfObjHandle* [ MAX_OBJHANDLE ];
00760 for ( i = MAX_OBJHANDLE-1; i >= 0; i-- )
00761 m_ObjHandleTab[ i ] = NULL;
00762
00763 if ( WMFIMPORT_DEBUG ) {
00764 cerr << "Bounding box : " << m_BBox.left() << " " << m_BBox.top() << " " << m_BBox.right() << " " << m_BBox.bottom() << endl;
00765 }
00766
00767 double scale = (m_Dpi > 0) ? 72.0 / m_Dpi : 0.05;
00768 m_context.setViewportOrg( 0, 0 );
00769 m_context.setViewportExt( m_BBox.width() * scale, m_BBox.height() * scale );
00770 m_context.setWindowOrg( m_BBox.left(), m_BBox.bottom() );
00771 m_context.setWindowExt( m_BBox.width(), m_BBox.height() );
00772
00773 for (int index = 0; index < m_commands.count(); ++index)
00774 {
00775 cmd = m_commands.at(index);
00776 idx = cmd->funcIndex;
00777 ( this->*metaFuncTab[ idx ].method )( elements, cmd->numParam, cmd->params );
00778
00779 if ( WMFIMPORT_DEBUG ) {
00780 QString str = "", param;
00781 if ( metaFuncTab[ idx ].name == NULL ) {
00782 str += "UNKNOWN ";
00783 }
00784 if ( metaFuncTab[ idx ].method == &WMFImport::noop ) {
00785 str += "UNIMPLEMENTED ";
00786 }
00787 str += metaFuncTab[ idx ].name;
00788 str += " : ";
00789
00790 for ( i=0 ; i < cmd->numParam ; i++ ) {
00791 param.setNum( cmd->params[ i ] );
00792 str += param;
00793 str += " ";
00794 }
00795 cerr << str.toAscii().data() << endl;
00796 }
00797 }
00798 return elements;
00799 }
00800
00801 void WMFImport::finishCmdParsing( PageItem* item )
00802 {
00803 QMatrix gcm = m_context.worldMatrix();
00804 double coeff1 = sqrt(gcm.m11() * gcm.m11() + gcm.m12() * gcm.m12());
00805 double coeff2 = sqrt(gcm.m21() * gcm.m21() + gcm.m22() * gcm.m22());
00806 if( item->asImageFrame() )
00807 {
00808 item->moveBy(gcm.dx(), gcm.dy());
00809 item->setWidthHeight(item->width() * gcm.m11(), item->height() * gcm.m22());
00810 item->setLineWidth(qMax(item->lineWidth() * (coeff1 + coeff2) / 2.0, 0.25));
00811 if (item->PicAvail)
00812 item->setImageXYScale(item->width() / item->pixm.width(), item->height() / item->pixm.height());
00813 }
00814 else if( item->asTextFrame() )
00815 {
00816 item->setLineWidth(qMax(item->lineWidth() * (coeff1 + coeff2) / 2.0, 0.25));
00817 }
00818 else
00819 {
00820 item->ClipEdited = true;
00821 item->FrameType = 3;
00822 item->PoLine.map(gcm);
00823 item->setLineWidth(qMax(item->lineWidth() * (coeff1 + coeff2) / 2.0, 0.25));
00824 FPoint wh = getMaxClipF(&item->PoLine);
00825 item->setWidthHeight(wh.x(), wh.y());
00826 m_Doc->AdjustItemSize(item);
00827 }
00828 item->setRedrawBounding();
00829 item->OwnPage = m_Doc->OnPage(item);
00830 item->PLineEnd = m_context.pen().capStyle();
00831 item->PLineJoin = m_context.pen().joinStyle();
00832 item->setTextFlowMode(PageItem::TextFlowDisabled);
00833
00834
00835 }
00836
00837 void WMFImport::setWindowOrg( QList<PageItem*>& , long, short* params )
00838 {
00839 m_context.setWindowOrg( params[ 1 ], params[ 0 ] );
00840 }
00841
00842 void WMFImport::setWindowExt( QList<PageItem*>& , long, short* params )
00843 {
00844 m_context.setWindowExt( params[ 1 ], params[ 0 ] );
00845 }
00846
00847 void WMFImport::lineTo( QList<PageItem*>& items, long, short* params )
00848 {
00849 double BaseX = m_Doc->currentPage()->xOffset();
00850 double BaseY = m_Doc->currentPage()->yOffset();
00851 QPoint currentPos = m_context.position();
00852 bool doStroke = (m_context.pen().style() != Qt::NoPen);
00853 if (doStroke)
00854 {
00855 double