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 importcgm.cpp - description
9 -------------------
10 begin : Wed Dez 23 2009
11 copyright : (C) 2009 by Franz Schmid
12 email : Franz.Schmid@altmuehlnet.de
13 ***************************************************************************/
14
15 #include <QByteArray>
16 #include <QCursor>
17 #include <QDrag>
18 #include <QFile>
19 #include <QList>
20 #include <QMimeData>
21 #include <QRegExp>
22 #include <QStack>
23 #include <QDebug>
24
25 #include <cstdlib>
26
27
28 #include "commonstrings.h"
29 #include "importcgm.h"
30 #include "loadsaveplugin.h"
31 #include "pagesize.h"
32 #include "prefscontext.h"
33 #include "prefsfile.h"
34 #include "prefsmanager.h"
35 #include "prefstable.h"
36 #include "rawimage.h"
37 #include "scclocale.h"
38 #include "sccolorengine.h"
39 #include "scconfig.h"
40 #include "scmimedata.h"
41 #include "scpaths.h"
42 #include "scribusXml.h"
43 #include "scribuscore.h"
44 #include "scribusview.h"
45 #include "sctextstream.h"
46 #include "selection.h"
47 #include "ui/customfdialog.h"
48 #include "ui/missing.h"
49 #include "ui/multiprogressdialog.h"
50 #include "ui/propertiespalette.h"
51 #include "undomanager.h"
52 #include "util.h"
53 #include "util_formats.h"
54 #include "util_math.h"
55
ScBitReader(QByteArray & data)56 ScBitReader::ScBitReader(QByteArray &data)
57 {
58 buffer = data;
59 actBit = 7;
60 actByte = 0;
61 }
62
~ScBitReader()63 ScBitReader::~ScBitReader()
64 {
65 }
66
getUInt(uint size)67 quint32 ScBitReader::getUInt(uint size)
68 {
69 quint32 ret = 0;
70 if (size > 32)
71 return 0;
72 quint8 dat = buffer[actByte];
73 for (uint c = 0; c < size; c++)
74 {
75 ret = (ret << 1) | ((dat & (0x01 << actBit)) >> actBit);
76 actBit--;
77 if (actBit < 0)
78 {
79 actBit = 7;
80 actByte++;
81 if (actByte >= buffer.count())
82 break;
83 dat = buffer[actByte];
84 }
85 }
86 return ret;
87 }
88
alignToWord()89 void ScBitReader::alignToWord()
90 {
91 if (actByte < buffer.count() - 1)
92 {
93 actByte++;
94 actByte += actByte % 2;
95 actBit = 7;
96 }
97 }
98
CgmPlug(ScribusDoc * doc,int flags)99 CgmPlug::CgmPlug(ScribusDoc* doc, int flags)
100 {
101 tmpSel = new Selection(this, false);
102 m_Doc = doc;
103 importerFlags = flags;
104 interactive = (flags & LoadSavePlugin::lfInteractive);
105 progressDialog = nullptr;
106 }
107
readThumbnail(const QString & fName)108 QImage CgmPlug::readThumbnail(const QString& fName)
109 {
110 QFileInfo fi = QFileInfo(fName);
111 baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
112 double b, h;
113 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
114 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
115 docWidth = b;
116 docHeight = h;
117 progressDialog = nullptr;
118 m_Doc = new ScribusDoc();
119 m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
120 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
121 m_Doc->addPage(0);
122 m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
123 baseX = m_Doc->currentPage()->xOffset();
124 baseY = m_Doc->currentPage()->yOffset();
125 Elements.clear();
126 m_Doc->setLoading(true);
127 m_Doc->DoDrawing = false;
128 m_Doc->scMW()->setScriptRunning(true);
129 QString CurDirP = QDir::currentPath();
130 QDir::setCurrent(fi.path());
131 if (convert(fName))
132 {
133 tmpSel->clear();
134 QDir::setCurrent(CurDirP);
135 if (Elements.count() > 1)
136 m_Doc->groupObjectsList(Elements);
137 m_Doc->DoDrawing = true;
138 m_Doc->m_Selection->delaySignalsOn();
139 QImage tmpImage;
140 if (Elements.count() > 0)
141 {
142 for (int dre =0; dre < Elements.count(); ++dre)
143 {
144 tmpSel->addItem(Elements.at(dre), true);
145 }
146 tmpSel->setGroupRect();
147 double xs = tmpSel->width();
148 double ys = tmpSel->height();
149 tmpImage = Elements.at(0)->DrawObj_toImage(500);
150 tmpImage.setText("XSize", QString("%1").arg(xs));
151 tmpImage.setText("YSize", QString("%1").arg(ys));
152 }
153 m_Doc->scMW()->setScriptRunning(false);
154 m_Doc->setLoading(false);
155 m_Doc->m_Selection->delaySignalsOff();
156 delete m_Doc;
157 return tmpImage;
158 }
159 QDir::setCurrent(CurDirP);
160 m_Doc->DoDrawing = true;
161 m_Doc->scMW()->setScriptRunning(false);
162 delete m_Doc;
163 return QImage();
164 }
165
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)166 bool CgmPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
167 {
168 bool success = false;
169 interactive = (flags & LoadSavePlugin::lfInteractive);
170 importerFlags = flags;
171 cancel = false;
172 double b, h;
173 bool ret = false;
174 CustColors.clear();
175 QFileInfo fi = QFileInfo(fNameIn);
176 if (!ScCore->usingGUI())
177 {
178 interactive = false;
179 showProgress = false;
180 }
181 baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
182 if (showProgress)
183 {
184 ScribusMainWindow* mw = (m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
185 progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
186 QStringList barNames, barTexts;
187 barNames << "GI";
188 barTexts << tr("Analyzing File:");
189 QList<bool> barsNumeric;
190 barsNumeric << false;
191 progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
192 progressDialog->setOverallTotalSteps(3);
193 progressDialog->setOverallProgress(0);
194 progressDialog->setProgress("GI", 0);
195 progressDialog->show();
196 connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
197 qApp->processEvents();
198 }
199 else
200 progressDialog = nullptr;
201 /* Set default Page to size defined in Preferences */
202 b = 0.0;
203 h = 0.0;
204 if (progressDialog)
205 {
206 progressDialog->setOverallProgress(1);
207 qApp->processEvents();
208 }
209 b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
210 h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
211 docWidth = b;
212 docHeight = h;
213 baseX = 0;
214 baseY = 0;
215 if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
216 {
217 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
218 m_Doc->addPage(0);
219 m_Doc->view()->addPage(0, true);
220 baseX = 0;
221 baseY = 0;
222 }
223 else
224 {
225 if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
226 {
227 m_Doc = ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
228 ScCore->primaryMainWindow()->HaveNewDoc();
229 ret = true;
230 baseX = 0;
231 baseY = 0;
232 baseX = m_Doc->currentPage()->xOffset();
233 baseY = m_Doc->currentPage()->yOffset();
234 }
235 }
236 if ((!ret) && (interactive))
237 {
238 baseX = m_Doc->currentPage()->xOffset();
239 baseY = m_Doc->currentPage()->yOffset();
240 }
241 if ((ret) || (!interactive))
242 {
243 if (docWidth > docHeight)
244 m_Doc->setPageOrientation(1);
245 else
246 m_Doc->setPageOrientation(0);
247 m_Doc->setPageSize("Custom");
248 }
249 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
250 m_Doc->view()->deselectItems();
251 Elements.clear();
252 m_Doc->setLoading(true);
253 m_Doc->DoDrawing = false;
254 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
255 m_Doc->view()->updatesOn(false);
256 m_Doc->scMW()->setScriptRunning(true);
257 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
258 QString CurDirP = QDir::currentPath();
259 QDir::setCurrent(fi.path());
260 if (convert(fNameIn))
261 {
262 tmpSel->clear();
263 QDir::setCurrent(CurDirP);
264 if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
265 {
266 PageItem* group = m_Doc->groupObjectsList(Elements);
267 if (!pictName.isEmpty())
268 group->setItemName(group->generateUniqueCopyName(pictName, false).replace( QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%\\.]"), "_" ));
269 }
270 m_Doc->DoDrawing = true;
271 m_Doc->scMW()->setScriptRunning(false);
272 m_Doc->setLoading(false);
273 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
274 if ((Elements.count() > 0) && (!ret) && (interactive))
275 {
276 if (flags & LoadSavePlugin::lfScripted)
277 {
278 bool loadF = m_Doc->isLoading();
279 m_Doc->setLoading(false);
280 m_Doc->changed();
281 m_Doc->setLoading(loadF);
282 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
283 {
284 m_Doc->m_Selection->delaySignalsOn();
285 for (int dre = 0; dre < Elements.count(); ++dre)
286 {
287 m_Doc->m_Selection->addItem(Elements.at(dre), true);
288 }
289 m_Doc->m_Selection->delaySignalsOff();
290 m_Doc->m_Selection->setGroupRect();
291 if (m_Doc->view() != nullptr)
292 m_Doc->view()->updatesOn(true);
293 }
294 }
295 else
296 {
297 m_Doc->DragP = true;
298 m_Doc->DraggedElem = nullptr;
299 m_Doc->DragElements.clear();
300 m_Doc->m_Selection->delaySignalsOn();
301 for (int dre = 0; dre < Elements.count(); ++dre)
302 {
303 tmpSel->addItem(Elements.at(dre), true);
304 }
305 tmpSel->setGroupRect();
306 ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
307 m_Doc->itemSelection_DeleteItem(tmpSel);
308 m_Doc->view()->updatesOn(true);
309 m_Doc->m_Selection->delaySignalsOff();
310 // We must copy the TransationSettings object as it is owned
311 // by handleObjectImport method afterwards
312 TransactionSettings* transacSettings = new TransactionSettings(trSettings);
313 m_Doc->view()->handleObjectImport(md, transacSettings);
314 m_Doc->DragP = false;
315 m_Doc->DraggedElem = nullptr;
316 m_Doc->DragElements.clear();
317 }
318 }
319 else
320 {
321 m_Doc->changed();
322 m_Doc->reformPages();
323 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
324 m_Doc->view()->updatesOn(true);
325 }
326 success = true;
327 }
328 else
329 {
330 QDir::setCurrent(CurDirP);
331 m_Doc->DoDrawing = true;
332 m_Doc->scMW()->setScriptRunning(false);
333 m_Doc->view()->updatesOn(true);
334 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
335 }
336 if (interactive)
337 m_Doc->setLoading(false);
338 //CB If we have a gui we must refresh it if we have used the progressbar
339 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
340 {
341 if ((showProgress) && (!interactive))
342 m_Doc->view()->DrawNew();
343 }
344 qApp->restoreOverrideCursor();
345 return success;
346 }
347
~CgmPlug()348 CgmPlug::~CgmPlug()
349 {
350 delete progressDialog;
351 delete tmpSel;
352 }
353
parseHeader(const QString & fName,double & b,double & h)354 void CgmPlug::parseHeader(const QString& fName, double &b, double &h)
355 {
356 }
357
convert(const QString & fn)358 bool CgmPlug::convert(const QString& fn)
359 {
360 Coords.resize(0);
361 Coords.svgInit();
362 importedColors.clear();
363 QList<PageItem*> gElements;
364 groupStack.push(gElements);
365 currentItemNr = 0;
366 importRunning = true;
367 firstPage = true;
368 vcdSet = false;
369 metaFileVersion = 1;
370 vdcType = 0;
371 vdcInt = 16;
372 vdcReal = 1;
373 vdcMantissa = 16;
374 vcdFlippedH = false;
375 vcdFlippedV = true;
376 intPrecision = 16;
377 realPrecision = 1;
378 realMantissa = 16;
379 realFraction = 16;
380 realPrecisionSet = false;
381 indexPrecision = 16;
382 colorPrecision = 8;
383 colorIndexPrecision = 8;
384 maxColorIndex = 63;
385 m_colorModel = 1;
386 colorMode = 0;
387 namePrecision = 16;
388 metaFileScaleMode = 0;
389 metaFileScale = 1.0;
390 metaScale = 400.0 / 32768.0;
391 lineWidthMode = 1;
392 edgeWidthMode = 1;
393 markerSizeMode = 1;
394 viewPortScale = 1.0;
395 viewPortScaleMode = 0;
396 lineType = Qt::SolidLine;
397 lineCap = Qt::FlatCap;
398 lineJoin = Qt::MiterJoin;
399 lineWidth = 1.0;
400 lineColor = "Black";
401 edgeType = Qt::SolidLine;
402 edgeCap = Qt::FlatCap;
403 edgeJoin = Qt::MiterJoin;
404 edgeWidth = 0.0;
405 edgeColor = "Black";
406 fillColor = "Black";
407 backgroundColor = "White";
408 patternIndex = 1;
409 patternTable.clear();
410 patternScaleX = -1;
411 patternScaleY = -1;
412 backgroundSet = false;
413 fillType = 1;
414 minColor = 0;
415 maxColor = 255;
416 clipRect = QRectF();
417 useClipRect = true;
418 clipSet = false;
419 lineVisible = true;
420 recordRegion = false;
421 wasEndPic = false;
422 recordFigure = false;
423 fontID_Map.clear();
424 m_fontIndex = 1;
425 textSize = 12;
426 textColor = "Black";
427 textAlignH = 0;
428 textScaleMode = 1;
429 currentRegion = 0;
430 pictName = "";
431 if (progressDialog)
432 {
433 progressDialog->setOverallProgress(2);
434 progressDialog->setLabel("GI", tr("Generating Items"));
435 qApp->processEvents();
436 }
437 QFile f(fn);
438 if (f.open(QIODevice::ReadOnly))
439 {
440 oldDocItemCount = m_Doc->Items->count();
441 int fSize = (int) f.size();
442 if (progressDialog)
443 {
444 progressDialog->setTotalSteps("GI", fSize);
445 qApp->processEvents();
446 }
447 QDataStream ts(&f);
448 ts.setByteOrder(QDataStream::BigEndian);
449 quint32 magic;
450 ts >> magic;
451 ts.device()->seek(0);
452 if (magic == 0x4265674D)
453 decodeText(f);
454 else
455 {
456 while (!ts.atEnd() && (importRunning))
457 {
458 quint16 data, elemClass, elemID, paramLen;
459 ts >> data;
460 elemClass = (data & 0xF000) >> 12;
461 elemID = (data & 0x0FE0) >> 5;
462 paramLen = data & 0x001F;
463 if (paramLen == 31)
464 ts >> paramLen;
465 // qDebug() << "CGM Command Class" << elemClass << "ID" << elemID << "ParamLen" << paramLen;
466 decodeBinary(ts, elemClass, elemID, paramLen);
467 if (progressDialog)
468 {
469 progressDialog->setProgress("GI", ts.device()->pos());
470 qApp->processEvents();
471 }
472 }
473 }
474 f.close();
475 if (Elements.count() == 0)
476 {
477 if (importedColors.count() != 0)
478 {
479 for (int cd = 0; cd < importedColors.count(); cd++)
480 {
481 m_Doc->PageColors.remove(importedColors[cd]);
482 }
483 }
484 }
485 else
486 {
487 if (backgroundSet)
488 {
489 tmpSel->clear();
490 tmpSel->delaySignalsOn();
491 for (int dre = 0; dre < Elements.count(); ++dre)
492 {
493 tmpSel->addItem(Elements.at(dre), true);
494 }
495 tmpSel->setGroupRect();
496 double gx, gy, gw, gh;
497 tmpSel->getVisualGroupRect(&gx, &gy, &gw, &gh);
498 tmpSel->clear();
499 tmpSel->delaySignalsOff();
500 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, gx, gy, gw, gh, 0, backgroundColor, CommonStrings::None);
501 PageItem *ite = m_Doc->Items->takeAt(z);
502 Elements.prepend(ite);
503 m_Doc->Items->insert(oldDocItemCount, ite);
504 }
505 }
506 }
507 if (progressDialog)
508 progressDialog->close();
509 return true;
510 }
511
decodeText(QFile & f)512 void CgmPlug::decodeText(QFile &f)
513 {
514 qDebug() << "Parsing Text Data not supported yet";
515 }
516
517 /* Start binary Decoder */
decodeBinary(QDataStream & ts,quint16 elemClass,quint16 elemID,quint16 paramLen)518 void CgmPlug::decodeBinary(QDataStream &ts, quint16 elemClass, quint16 elemID, quint16 paramLen)
519 {
520 qint64 pos = ts.device()->pos();
521 if (elemClass == 0)
522 decodeClass0(ts, elemID, paramLen);
523 else if (elemClass == 1)
524 decodeClass1(ts, elemID, paramLen);
525 else if (elemClass == 2)
526 decodeClass2(ts, elemID, paramLen);
527 else if (elemClass == 3)
528 decodeClass3(ts, elemID, paramLen);
529 else if (elemClass == 4)
530 decodeClass4(ts, elemID, paramLen);
531 else if (elemClass == 5)
532 decodeClass5(ts, elemID, paramLen);
533 else if (elemClass == 6)
534 decodeClass6(ts, elemID, paramLen);
535 else if (elemClass == 7)
536 decodeClass7(ts, elemID, paramLen);
537 else if (elemClass == 8)
538 decodeClass8(ts, elemID, paramLen);
539 else if (elemClass == 9)
540 decodeClass9(ts, elemID, paramLen);
541 else
542 {
543 importRunning = false;
544 qDebug() << "Class" << elemClass << "ID" << elemID << "Len" << paramLen << "at" << ts.device()->pos();
545 }
546 ts.device()->seek(pos);
547 alignStreamToWord(ts, paramLen);
548 alignStreamToWord(ts, 0);
549 }
550
decodeClass0(QDataStream & ts,quint16 elemID,quint16 paramLen)551 void CgmPlug::decodeClass0(QDataStream &ts, quint16 elemID, quint16 paramLen)
552 {
553 if (elemID == 0)
554 {
555 qDebug() << "NO OP";
556 }
557 else if (elemID == 1)
558 handleStartMetaFile(getBinaryText(ts));
559 else if (elemID == 2)
560 {
561 importRunning = false;
562 // qDebug() << "END METAFILE";
563 }
564 else if (elemID == 3)
565 handleStartPicture(getBinaryText(ts));
566 else if (elemID == 4)
567 {
568 if (vcdSet)
569 {
570 double w = vdcWidth * metaScale;
571 double h = vdcHeight * metaScale;
572 handleStartPictureBody(w, h);
573 }
574 else
575 {
576 handleStartPictureBody(docWidth, docHeight);
577 firstPage = true;
578 }
579 // qDebug() << "BEGIN PICTURE BODY";
580 }
581 else if (elemID == 5)
582 {
583 if (vcdSet)
584 {
585 if (firstPage)
586 {
587 double w = vdcWidth * metaScale;
588 double h = vdcHeight * metaScale;
589 handleStartPictureBody(w, h);
590 }
591 }
592 else
593 {
594 if (firstPage)
595 handleStartPictureBody(docWidth, docHeight);
596 }
597 wasEndPic = true;
598 // qDebug() << "END PICTURE";
599 }
600 else if (elemID == 6)
601 {
602 qDebug() << "BEGIN SEGMENT";
603 }
604 else if (elemID == 7)
605 {
606 qDebug() << "END SEGMENT";
607 }
608 else if (elemID == 8)
609 {
610 recordFigure = true;
611 figurePath = QPainterPath();
612 figClose = false;
613 figDocIndex = m_Doc->Items->count();
614 figElemIndex = Elements.count();
615 figGstIndex = 0;
616 figFillColor = fillColor;
617 if (groupStack.count() != 0)
618 figGstIndex = groupStack.top().count();
619 // qDebug() << "BEGIN FIGURE";
620 }
621 else if (elemID == 9)
622 {
623 recordFigure = false;
624 if (!figurePath.isEmpty())
625 {
626 figurePath.closeSubpath();
627 Coords.fromQPainterPath(figurePath);
628 PageItem *ite = itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, figFillColor, CommonStrings::None);
629 ite->PoLine = Coords.copy();
630 ite->ClipEdited = true;
631 ite->FrameType = 3;
632 FPoint wh = getMaxClipF(&ite->PoLine);
633 ite->setWidthHeight(wh.x(),wh.y());
634 ite->setTextFlowMode(PageItem::TextFlowDisabled);
635 m_Doc->adjustItemSize(ite);
636 ite->OldB2 = ite->width();
637 ite->OldH2 = ite->height();
638 ite->updateClip();
639 m_Doc->Items->takeLast();
640 m_Doc->Items->insert(figDocIndex, ite);
641 Elements.insert(figElemIndex, ite);
642 if (groupStack.count() != 0)
643 groupStack.top().insert(figGstIndex, ite);
644 }
645 figurePath = QPainterPath();
646 // qDebug() << "END FIGURE";
647 }
648 else if (elemID == 13)
649 {
650 uint type = getBinaryUInt(ts, indexPrecision);
651 currentRegion = type;
652 recordRegion = true;
653 regionPath = QPainterPath();
654 // qDebug() << "BEGIN PROTECTION REGION" << type;
655 }
656 else if (elemID == 14)
657 {
658 recordRegion = false;
659 regionMap.insert(currentRegion, regionPath);
660 // qDebug() << "END PROTECTION REGION";
661 }
662 else if (elemID == 15)
663 {
664 qDebug() << "BEGIN COMPOUND LINE";
665 }
666 else if (elemID == 16)
667 {
668 qDebug() << "END COMPOUND LINE";
669 }
670 else if (elemID == 17)
671 {
672 qDebug() << "BEGIN COMPOUND TEXT PATH";
673 }
674 else if (elemID == 18)
675 {
676 qDebug() << "END COMPOUND TEXT PATH";
677 }
678 else if (elemID == 19)
679 {
680 qDebug() << "BEGIN TILE ARRAY";
681 }
682 else if (elemID == 20)
683 {
684 qDebug() << "END TILE ARRAY";
685 }
686 else if (elemID == 21)
687 {
688 qDebug() << "BEGIN APPLICATION STRUCTURE";
689 }
690 else if (elemID == 22)
691 {
692 qDebug() << "BEGIN APPLICATION STRUCTURE BODY";
693 }
694 else if (elemID == 23)
695 {
696 qDebug() << "END APPLICATION STRUCTURE";
697 }
698 else
699 {
700 importRunning = false;
701 qDebug() << "Class 0 ID" << elemID << "Len" << paramLen;
702 }
703 }
704
decodeClass1(QDataStream & ts,quint16 elemID,quint16 paramLen)705 void CgmPlug::decodeClass1(QDataStream &ts, quint16 elemID, quint16 paramLen)
706 {
707 quint16 data;
708 if (elemID == 1)
709 {
710 ts >> data;
711 metaFileVersion = data;
712 //qDebug() << "METAFILE VERSION" << data;
713 }
714 else if (elemID == 2)
715 handleMetaFileDescription(getBinaryText(ts));
716 else if (elemID == 3)
717 {
718 ts >> data;
719 vdcType = data;
720 //qDebug() << "VDC TYPE" << data;
721 }
722 else if (elemID == 4)
723 {
724 ts >> data;
725 intPrecision = data;
726 // qDebug() << "INTEGER PRECISION" << data;
727 }
728 else if (elemID == 5)
729 {
730 ts >> data;
731 realPrecision = data;
732 ts >> data;
733 realMantissa = data;
734 ts >> data;
735 realFraction = data;
736 if (realPrecision == 0)
737 realPrecisionSet = true;
738 // qDebug() << "REAL PRECISION" << realPrecision << realMantissa << realFraction;
739 }
740 else if (elemID == 6)
741 {
742 ts >> data;
743 indexPrecision = data;
744 // qDebug() << "INDEX PRECISION" << indexPrecision;
745 }
746 else if (elemID == 7)
747 {
748 ts >> data;
749 colorPrecision = data;
750 // qDebug() << "COLOUR PRECISION" << colorPrecision;
751 }
752 else if (elemID == 8)
753 {
754 ts >> data;
755 colorIndexPrecision = data;
756 //qDebug() << "COLOUR INDEX PRECISION" << colorIndexPrecision;
757 }
758 else if (elemID == 9)
759 {
760 ts >> data;
761 maxColorIndex = data;
762 // qDebug() << "MAXIMUM COLOUR INDEX" << maxColorIndex;
763 }
764 else if (elemID == 10)
765 {
766 if (m_colorModel == 1) // RGB
767 {
768 if (colorPrecision == 8)
769 {
770 quint8 r, g, b;
771 ts >> r >> g >> b;
772 minColor = r;
773 ts >> r >> g >> b;
774 maxColor = r;
775 }
776 else if (colorPrecision == 16)
777 {
778 quint16 r, g, b;
779 ts >> r >> g >> b;
780 minColor = r;
781 ts >> r >> g >> b;
782 maxColor = r;
783 }
784 }
785 else if (m_colorModel == 4) // CMYK
786 {
787 if (colorPrecision == 8)
788 {
789 quint8 c, m, y, k;
790 ts >> c >> m >> y >> k;
791 minColor = c;
792 ts >> c >> m >> y >> k;
793 maxColor = c;
794 }
795 else if (colorPrecision == 16)
796 {
797 quint16 c, m, y, k;
798 ts >> c >> m >> y >> k;
799 minColor = c;
800 ts >> c >> m >> y >> k;
801 maxColor = c;
802 }
803 }
804 // qDebug() << "COLOUR VALUE EXTENT" << minColor << maxColor;
805 }
806 else if (elemID == 11)
807 {
808 // qDebug() << "METAFILE ELEMENT LIST";
809 }
810 else if (elemID == 12)
811 {
812 qDebug() << "METAFILE DEFAULTS REPLACEMENT" << paramLen;
813 /* quint16 data, elemClass, elemID, paramLenN;
814 ts >> data;
815 elemClass = (data & 0xF000) >> 12;
816 elemID = (data & 0x0FE0) >> 5;
817 paramLenN = data & 0x001F;
818 if (paramLenN == 31)
819 ts >> paramLenN;
820 qDebug() << "CGM Command Class" << elemClass << "ID" << elemID << "ParamLen" << paramLenN;
821 decodeBinary(ts, elemClass, elemID, paramLenN);*/
822 }
823 else if (elemID == 13)
824 {
825 quint16 bytesRead = 0;
826 int fontID = 1;
827 while (bytesRead < paramLen)
828 {
829 int posA = ts.device()->pos();
830 QString p = getBinaryText(ts);
831 int posN = ts.device()->pos();
832 bytesRead += posN - posA;
833 fontID_Map.insert(fontID, p);
834 }
835 // qDebug() << "FONT LIST" << fontID_Map;
836 }
837 else if (elemID == 14)
838 {
839 qDebug() << "CHARACTER SET LIST";
840 }
841 else if (elemID == 15)
842 {
843 qDebug() << "CHARACTER CODING ANNOUNCER";
844 }
845 else if (elemID == 16)
846 {
847 ts >> data;
848 namePrecision = data;
849 // qDebug() << "NAME PRECISION" << namePrecision;
850 }
851 else if (elemID == 17)
852 {
853 QPointF max, min;
854 max = getBinaryCoords(ts);
855 min = getBinaryCoords(ts);
856 // qDebug() << "MAXIMUM VDC EXTENT" << min.x() << min.y() << max.x() << max.y();
857 }
858 else if (elemID == 18)
859 {
860 qDebug() << "SEGMENT PRIORITY EXTENT";
861 }
862 else if (elemID == 19)
863 {
864 ts >> data;
865 m_colorModel = data;
866 // qDebug() << "COLOUR MODEL" << colorModel;
867 }
868 else if (elemID == 20)
869 {
870 qDebug() << "COLOUR CALIBRATION";
871 }
872 else if (elemID == 21)
873 {
874 qDebug() << "FONT PROPERTIES";
875 }
876 else if (elemID == 22)
877 {
878 qDebug() << "GLYPH MAPPING";
879 }
880 else if (elemID == 23)
881 {
882 qDebug() << "SYMBOL LIBRARY LIST";
883 }
884 else if (elemID == 24)
885 {
886 qDebug() << "PICTURE DIRECTORY";
887 }
888 else
889 {
890 importRunning = false;
891 qDebug() << "Class 1 ID" << elemID << "Len" << paramLen;
892 }
893 }
894
decodeClass2(QDataStream & ts,quint16 elemID,quint16 paramLen)895 void CgmPlug::decodeClass2(QDataStream &ts, quint16 elemID, quint16 paramLen)
896 {
897 quint16 data;
898 if (elemID == 1)
899 {
900 ts >> data;
901 metaFileScaleMode = data;
902 double sc = 1.0;
903 if (realPrecisionSet)
904 sc = getBinaryReal(ts, 0, realMantissa);
905 else
906 sc = getBinaryReal(ts, 0, 9);
907 if (metaFileScaleMode != 0)
908 metaFileScale = sc;
909 // qDebug() << "SCALING MODE" << metaFileScaleMode << metaFileScale;
910 }
911 else if (elemID == 2)
912 {
913 ts >> data;
914 colorMode = data;
915 // qDebug() << "COLOUR SELECTION MODE" << colorMode;
916 }
917 else if (elemID == 3)
918 {
919 ts >> data;
920 lineWidthMode = data;
921 if (lineWidthMode == 0)
922 lineWidth = 0; // qMax(vdcWidth, vdcHeight) / 1000;
923 else if (lineWidthMode == 1)
924 lineWidth = 1.0;
925 else if (lineWidthMode == 2)
926 lineWidth = 0.001;
927 else if (lineWidthMode == 3)
928 lineWidth = 0.35;
929 // qDebug() << "LINE WIDTH SPECIFICATION MODE" << lineWidthMode;
930 }
931 else if (elemID == 4)
932 {
933 ts >> data;
934 markerSizeMode = data;
935 // qDebug() << "MARKER SIZE SPECIFICATION MODE" << markerSizeMode;
936 }
937 else if (elemID == 5)
938 {
939 ts >> data;
940 edgeWidthMode = data;
941 if (edgeWidthMode == 0)
942 edgeWidth = 0; // qMax(vdcWidth, vdcHeight) / 1000;
943 else if (edgeWidthMode == 1)
944 edgeWidth = 1.0;
945 else if (edgeWidthMode == 2)
946 edgeWidth = 0.001;
947 else if (edgeWidthMode == 3)
948 edgeWidth = 0.35;
949 // qDebug() << "EDGE WIDTH SPECIFICATION MODE" << edgeWidthMode;
950 }
951 else if (elemID == 6)
952 {
953 QPointF max, min;
954 max = getBinaryCoords(ts, true);
955 min = getBinaryCoords(ts, true);
956 QRectF vd = QRectF(max, min);
957 vcdFlippedV = (vd.height() > 0);
958 vcdFlippedH = (vd.width() < 0);
959 vd = vd.normalized();
960 vdcWidth = vd.width();
961 vdcHeight = vd.height();
962 metaScale = 400.0 / qMax(vdcWidth, vdcHeight);
963 if (lineWidthMode == 0)
964 lineWidth = 0; // qMax(vdcWidth, vdcHeight) / 1000;
965 else if (lineWidthMode == 1)
966 lineWidth = 1.0;
967 else if (lineWidthMode == 2)
968 lineWidth = 0.001;
969 else if (lineWidthMode == 3)
970 lineWidth = 0.35;
971 baseX = -vd.left() * metaScale;
972 baseY = vd.top() * metaScale;
973 vcdSet = true;
974 if (!clipSet)
975 {
976 clipRect = QRectF(vd.left() * metaScale, vd.top() * metaScale, vdcWidth * metaScale, vdcHeight * metaScale);
977 clipSet = true;
978 }
979 // qDebug() << "VDC EXTENT" << vd.left() << vd.top() << vdcWidth << vdcHeight << vcdFlippedV;
980 }
981 else if (elemID == 7)
982 {
983 ScColor color = getBinaryDirectColor(ts);
984 backgroundColor = handleColor(color, "FromCGM"+color.name());
985 if (colorMode == 1)
986 backgroundSet = true;
987 else
988 ColorTableMap.insert(0, backgroundColor);
989 // qDebug() << "BACKGROUND COLOUR" << backgroundColor;
990 }
991 else if (elemID == 8)
992 {
993 QPointF max, min;
994 max = getBinaryCoords(ts);
995 min = getBinaryCoords(ts);
996 // qDebug() << "DEVICE VIEWPORT" << min.x() << min.y() << max.x() << max.y();
997 }
998 else if (elemID == 9)
999 {
1000 ts >> data;
1001 viewPortScaleMode = data;
1002 if (realPrecisionSet)
1003 viewPortScale = getBinaryReal(ts, 0, realMantissa);
1004 else
1005 viewPortScale = getBinaryReal(ts, 0, 9);
1006 // qDebug() << "DEVICE VIEWPORT SPECIFICATION MODE" << viewPortScaleMode << viewPortScale;
1007 }
1008 else if (elemID == 10)
1009 {
1010 qDebug() << "DEVICE VIEWPORT MAPPING";
1011 }
1012 else if (elemID == 11)
1013 {
1014 qDebug() << "LINE REPRESENTATION";
1015 }
1016 else if (elemID == 12)
1017 {
1018 qDebug() << "MARKER REPRESENTATION";
1019 }
1020 else if (elemID == 13)
1021 {
1022 qDebug() << "TEXT REPRESENTATION";
1023 }
1024 else if (elemID == 14)
1025 {
1026 qDebug() << "FILL REPRESENTATION";
1027 }
1028 else if (elemID == 15)
1029 {
1030 qDebug() << "EDGE REPRESENTATION";
1031 }
1032 else if (elemID == 16)
1033 {
1034 qDebug() << "INTERIOR STYLE SPECIFICATION MODE";
1035 }
1036 else if (elemID == 17)
1037 {
1038 qDebug() << "LINE AND EDGE TYPE DEFINITION";
1039 }
1040 else if (elemID == 18)
1041 {
1042 qDebug() << "HATCH STYLE DEFINITION";
1043 }
1044 else if (elemID == 19)
1045 {
1046 qDebug() << "GEOMETRIC PATTERN DEFINITION";
1047 }
1048 else if (elemID == 20)
1049 {
1050 qDebug() << "APPLICATION STRUCTURE DIRECTORY";
1051 }
1052 else
1053 {
1054 importRunning = false;
1055 qDebug() << "Class 2 ID" << elemID << "Len" << paramLen;
1056 }
1057 }
1058
decodeClass3(QDataStream & ts,quint16 elemID,quint16 paramLen)1059 void CgmPlug::decodeClass3(QDataStream &ts, quint16 elemID, quint16 paramLen)
1060 {
1061 quint16 data;
1062 if (elemID == 1)
1063 {
1064 ts >> data;
1065 vdcInt = data;
1066 // qDebug() << "VDC INTEGER PRECISION" << vdcInt;
1067 }
1068 else if (elemID == 2)
1069 {
1070 ts >> data;
1071 vdcReal = data;
1072 ts >> data;
1073 vdcMantissa = data;
1074 ts >> data;
1075 // qDebug() << "VDC REAL PRECISION" << vdcReal << vdcMantissa;
1076 }
1077 else if (elemID == 3)
1078 {
1079 qDebug() << "AUXILIARY COLOUR";
1080 }
1081 else if (elemID == 4)
1082 {
1083 qDebug() << "TRANSPARENCY";
1084 }
1085 else if (elemID == 5)
1086 {
1087 QPointF max, min;
1088 max = getBinaryCoords(ts);
1089 min = getBinaryCoords(ts);
1090 QRectF vd = QRectF(max, min);
1091 vd = vd.normalized();
1092 double w = convertCoords(vd.width());
1093 double h = convertCoords(vd.height());
1094 double x = convertCoords(vd.left());
1095 double y = convertCoords(vd.top());
1096 x += m_Doc->currentPage()->xOffset();
1097 y += m_Doc->currentPage()->yOffset();
1098 clipRect = QRectF(x, y, w, h);
1099 clipSet = true;
1100 // qDebug() << "CLIP RECTANGLE" << clipRect;
1101 }
1102 else if (elemID == 6)
1103 {
1104 ts >> data;
1105 useClipRect = (data != 0);
1106 // qDebug() << "CLIP INDICATOR" << useClipRect;
1107 }
1108 else if (elemID == 7)
1109 {
1110 qDebug() << "LINE CLIPPING MODE";
1111 }
1112 else if (elemID == 8)
1113 {
1114 qDebug() << "MARKER CLIPPING MODE";
1115 }
1116 else if (elemID == 9)
1117 {
1118 qDebug() << "EDGE CLIPPING MODE";
1119 }
1120 else if (elemID == 10)
1121 {
1122 if (recordRegion)
1123 regionPath.closeSubpath();
1124 if (recordFigure)
1125 figurePath.closeSubpath();
1126 figClose = true;
1127 // qDebug() << "NEW REGION";
1128 }
1129 else if (elemID == 11)
1130 {
1131 qDebug() << "SAVE PRIMITIVE CONTEXT";
1132 }
1133 else if (elemID == 12)
1134 {
1135 qDebug() << "RESTORE PRIMITIVE CONTEXT";
1136 }
1137 else if (elemID == 17)
1138 {
1139 uint index = getBinaryUInt(ts, indexPrecision);
1140 uint type = getBinaryUInt(ts, indexPrecision);
1141 if (type == 1)
1142 {
1143 if (groupStack.count() != 0)
1144 {
1145 QList<PageItem*> gElements = groupStack.pop();
1146 tmpSel->clear();
1147 if (gElements.count() > 0)
1148 {
1149 for (int dre = 0; dre < gElements.count(); ++dre)
1150 {
1151 tmpSel->addItem(gElements.at(dre), true);
1152 Elements.removeAll(gElements.at(dre));
1153 }
1154 PageItem *ite = m_Doc->itemSelection_GroupObjects(false, false, tmpSel);
1155 QPainterPath clip = regionMap[index];
1156 if (!clip.isEmpty())
1157 {
1158 ite->PoLine.fromQPainterPath(clip);
1159 ite->PoLine.translate(-ite->xPos(), -ite->yPos());
1160 ite->PoLine.translate(baseX, baseY);
1161 }
1162 tmpSel->clear();
1163 tmpSel->addItem(ite, true);
1164 Elements.append(ite);
1165 }
1166 if (groupStack.count() != 0)
1167 {
1168 for (int as = 0; as < tmpSel->count(); ++as)
1169 {
1170 groupStack.top().append(tmpSel->itemAt(as));
1171 }
1172 }
1173 tmpSel->clear();
1174 }
1175 }
1176 else if ((type == 2) || (type == 3))
1177 {
1178 QList<PageItem*> gElements;
1179 groupStack.push(gElements);
1180 }
1181 // qDebug() << "PROTECTION REGION INDICATOR" << index << type;
1182 }
1183 else if (elemID == 18)
1184 {
1185 qDebug() << "GENERALIZED TEXT PATH MODE";
1186 }
1187 else if (elemID == 19)
1188 {
1189 qDebug() << "MITRE LIMIT";
1190 }
1191 else if (elemID == 20)
1192 {
1193 qDebug() << "TRANSPARENT CELL COLOUR";
1194 }
1195 else
1196 {
1197 importRunning = false;
1198 qDebug() << "Class 3 ID" << elemID << "Len" << paramLen;
1199 }
1200 }
1201
decodeClass4(QDataStream & ts,quint16 elemID,quint16 paramLen)1202 void CgmPlug::decodeClass4(QDataStream &ts, quint16 elemID, quint16 paramLen)
1203 {
1204 if (elemID == 1)
1205 {
1206 getBinaryPath(ts, paramLen);
1207 if (Coords.size() > 3)
1208 {
1209 Coords.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1210 if (recordRegion)
1211 regionPath.connectPath(Coords.toQPainterPath(false));
1212 else
1213 {
1214 if (recordFigure)
1215 {
1216 if (figClose)
1217 {
1218 QPainterPath ell = Coords.toQPainterPath(false);
1219 appendPath(figurePath, ell);
1220 figClose = false;
1221 }
1222 else
1223 figurePath.connectPath(Coords.toQPainterPath(false));
1224 }
1225 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, CommonStrings::None, lineColor);
1226 PageItem *ite = m_Doc->Items->at(z);
1227 ite->PoLine = Coords.copy();
1228 finishItem(ite);
1229 }
1230 }
1231 // qDebug() << "POLYLINE";
1232 }
1233 else if (elemID == 2)
1234 {
1235 getBinaryPath(ts, paramLen, true);
1236 if (Coords.size() > 3)
1237 {
1238 Coords.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1239 if (recordRegion)
1240 regionPath.connectPath(Coords.toQPainterPath(false));
1241 else
1242 {
1243 if (recordFigure)
1244 {
1245 if (figClose)
1246 {
1247 QPainterPath ell = Coords.toQPainterPath(false);
1248 appendPath(figurePath, ell);
1249 figClose = false;
1250 }
1251 else
1252 figurePath.connectPath(Coords.toQPainterPath(false));
1253 }
1254 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, CommonStrings::None, lineColor);
1255 PageItem *ite = m_Doc->Items->at(z);
1256 ite->PoLine = Coords.copy();
1257 finishItem(ite);
1258 }
1259 }
1260 // qDebug() << "DISJOINT POLYLINE";
1261 }
1262 else if (elemID == 3)
1263 {
1264 qDebug() << "POLYMARKER";
1265 }
1266 else if (elemID == 4)
1267 {
1268 QPointF center = getBinaryCoords(ts);
1269 double txX = convertCoords(center.x());
1270 double txY = convertCoords(center.y());
1271 quint16 flag;
1272 ts >> flag;
1273 QString txt = getBinaryText(ts);
1274 QPainterPath ell;
1275 ell.addText(0, 0, QFont(fontID_Map[m_fontIndex], textSize), txt);
1276 ell.translate(txX, txY);
1277 if (textAlignH == 2)
1278 ell.translate(-ell.boundingRect().width() / 2.0, 0);
1279 else if (textAlignH == 3)
1280 ell.translate(-ell.boundingRect().width(), 0);
1281 ell.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1282 if (recordRegion)
1283 regionPath.addPath(ell);
1284 else
1285 {
1286 if (recordFigure)
1287 figurePath.addPath(ell);
1288 Coords.fromQPainterPath(ell, true);
1289 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, textColor, CommonStrings::None);
1290 PageItem *ite = m_Doc->Items->at(z);
1291 ite->PoLine = Coords.copy();
1292 finishItem(ite, false);
1293 }
1294 // qDebug() << "TEXT Len" << textAlignH;
1295 }
1296 else if (elemID == 5)
1297 {
1298 double sx = convertCoords(getBinaryDistance(ts));
1299 double sy = convertCoords(getBinaryDistance(ts));
1300 QPointF center = getBinaryCoords(ts);
1301 double txX = convertCoords(center.x());
1302 double txY = convertCoords(center.y());
1303 quint16 flag;
1304 ts >> flag;
1305 QString txt = getBinaryText(ts);
1306 QPainterPath ell;
1307 ell.addText(0, 0, QFont(fontID_Map[m_fontIndex], textSize), txt);
1308 double scx = sx / ell.boundingRect().width();
1309 double scy = sy / ell.boundingRect().height();
1310 if ((textScaleMode > 1) || ((ell.boundingRect().width() > sx) || (ell.boundingRect().height() > sy)))
1311 {
1312 QTransform mm;
1313 mm.scale(scx, scy);
1314 ell = mm.map(ell);
1315 }
1316 ell.translate(txX, txY);
1317 if (textAlignH == 2)
1318 ell.translate(-ell.boundingRect().width() / 2.0, 0);
1319 else if (textAlignH == 3)
1320 ell.translate(-ell.boundingRect().width(), 0);
1321 ell.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1322 if (recordRegion)
1323 regionPath.addPath(ell);
1324 else
1325 {
1326 if (recordFigure)
1327 figurePath.addPath(ell);
1328 Coords.fromQPainterPath(ell, true);
1329 int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, textColor, CommonStrings::None);
1330 PageItem *ite = m_Doc->Items->at(z);
1331 ite->PoLine = Coords.copy();
1332 finishItem(ite, false);
1333 }
1334 // qDebug() << "RESTRICTED TEXT";
1335 }
1336 else if (elemID == 6)
1337 {
1338 qDebug() << "APPEND TEXT";
1339 }
1340 else if (elemID == 7)
1341 {
1342 getBinaryPath(ts, paramLen);
1343 if (Coords.size() > 3)
1344 {
1345 Coords.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1346 if (recordRegion)
1347 regionPath.addPath(Coords.toQPainterPath(true));
1348 else
1349 {
1350 if (recordFigure)
1351 figurePath.addPath(Coords.toQPainterPath(true));
1352 PageItem *ite = itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, edgeWidth, fillColor, edgeColor);
1353 ite->PoLine = Coords.copy();
1354 finishItem(ite, false);
1355 }
1356 }
1357 // qDebug() << "POLYGON";
1358 }
1359 else if (elemID == 8)
1360 {
1361 // qDebug() << "POLYGON SET" << "Fill Type" << fillType;
1362 quint16 bytesRead = 0;
1363 bool first = true;
1364 Coords.resize(0);
1365 Coords.svgInit();
1366 quint16 flag;
1367 paramLen = paramLen & 0x7FFF;
1368 QPainterPath polySetPath;
1369 QPointF startPoint;
1370 while (bytesRead < paramLen)
1371 {
1372 int posA = ts.device()->pos();
1373 QPointF p = getBinaryCoords(ts);
1374 ts >> flag;
1375 int posN = ts.device()->pos();
1376 bytesRead += posN - posA;
1377 if (first)
1378 {
1379 polySetPath.moveTo(convertCoords(p.x()), convertCoords(p.y()));
1380 startPoint = p;
1381 first = false;
1382 }
1383 else
1384 polySetPath.lineTo(convertCoords(p.x()), convertCoords(p.y()));
1385 if ((flag == 2) || (flag == 3))
1386 {
1387 polySetPath.lineTo(convertCoords(startPoint.x()), convertCoords(startPoint.y()));
1388 polySetPath.closeSubpath();
1389 first = true;
1390 }
1391 }
1392 polySetPath.lineTo(convertCoords(startPoint.x()), convertCoords(startPoint.y()));
1393 polySetPath.closeSubpath();
1394 if (recordFigure)
1395 {
1396 polySetPath.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1397 figurePath.addPath(polySetPath);
1398 }
1399 else
1400 {
1401 // qDebug() << "POLYGON SET" << "Fill Color" << fillColor;
1402 Coords.fromQPainterPath(polySetPath, true);
1403 PageItem *ite = itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, edgeWidth, fillColor, edgeColor);
1404 ite->PoLine = Coords.copy();
1405 ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1406 finishItem(ite, false);
1407 }
1408 }
1409 else if (elemID == 9)
1410 {
1411 int pos = ts.device()->pos();
1412 QPointF p, q, r;
1413 int nx, ny;
1414 quint16 mode;
1415 p = convertCoords(getBinaryCoords(ts));
1416 q = convertCoords(getBinaryCoords(ts));
1417 r = convertCoords(getBinaryCoords(ts));
1418 nx = getBinaryUInt(ts, intPrecision);
1419 ny = getBinaryUInt(ts, intPrecision);
1420 int t_colorPrecision = colorPrecision;
1421 int t_colorIndexPrecision = colorIndexPrecision;
1422 colorPrecision = getBinaryUInt(ts, intPrecision);
1423 colorIndexPrecision = colorPrecision;
1424 // qDebug() << "CELL ARRAY at" << pos << "Size" << nx << ny << "Compression" << mode << "Color Prec" << colorPrecision;
1425 if (colorPrecision == 0)
1426 {
1427 colorPrecision = t_colorPrecision;
1428 colorIndexPrecision = t_colorIndexPrecision;
1429 }
1430 ts >> mode;
1431 int bytesRead = ts.device()->pos() - pos;
1432 QLineF pr = QLineF(p, r);
1433 QLineF rq = QLineF(r, q);
1434 double originX = p.x();
1435 double originY = p.y();
1436 bool flipX = false;
1437 bool flipY = false;
1438 if (p.x() > r.x())
1439 {
1440 flipX = true;
1441 originX = r.x();
1442 }
1443 if (p.y() > q.y())
1444 {
1445 flipY = true;
1446 originY = q.y();
1447 }
1448 int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Rectangle, baseX + originX, baseY + originY, pr.length(), rq.length(), edgeWidth, CommonStrings::None, CommonStrings::None);
1449 PageItem *ite = m_Doc->Items->at(z);
1450 ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1451 finishItem(ite, false);
1452 QImage image = QImage(nx, ny, QImage::Format_ARGB32);
1453 quint16 flag = paramLen & 0x8000;
1454 quint16 pLen = (paramLen & 0x7FFF) - bytesRead;
1455 QByteArray imageData;
1456 imageData.resize(0);
1457 QByteArray rD = ts.device()->read(pLen);
1458 imageData.append(rD);
1459 while (flag)
1460 {
1461 ts >> pLen;
1462 flag = pLen & 0x8000;
1463 pLen = pLen & 0x7FFF;
1464 QByteArray rD = ts.device()->read(pLen);
1465 imageData.append(rD);
1466 }
1467 if (colorPrecision < 8)
1468 {
1469 ScBitReader *breader = new ScBitReader(imageData);
1470 for (int yy = 0; yy < ny; yy++)
1471 {
1472 ScColor color;
1473 QRgb *s = (QRgb*)(image.scanLine(yy));
1474 if (mode == 1)
1475 {
1476 for (int xx = 0; xx < nx; xx++)
1477 {
1478 if (colorMode == 0)
1479 color = m_Doc->PageColors[getBinaryIndexedColor(breader)];
1480 else
1481 color = getBinaryDirectColor(breader);
1482 QColor co = color.getRawRGBColor();
1483 *s++ = qRgba(co.red(), co.green(), co.blue(), 255);
1484 }
1485 }
1486 else
1487 {
1488 int xx = 0;
1489 while (xx < nx)
1490 {
1491 int counter = breader->getUInt(intPrecision);
1492 if ((counter > nx) || (counter == 0))
1493 {
1494 importRunning = false;
1495 return;
1496 }
1497 if (colorMode == 0)
1498 color = m_Doc->PageColors[getBinaryIndexedColor(breader)];
1499 else
1500 color = getBinaryDirectColor(breader);
1501 QColor co = color.getRawRGBColor();
1502 for (int xc = 0; xc < counter; xc++)
1503 {
1504 *s++ = qRgba(co.red(), co.green(), co.blue(), 255);
1505 xx++;
1506 if (xx >= nx)
1507 break;
1508 }
1509 }
1510 }
1511 breader->alignToWord();
1512 }
1513 }
1514 else
1515 {
1516 QDataStream istr(imageData);
1517 istr.setByteOrder(QDataStream::BigEndian);
1518 for (int yy = 0; yy < ny; yy++)
1519 {
1520 ScColor color;
1521 QRgb *s = (QRgb*)(image.scanLine(yy));
1522 if (mode == 1)
1523 {
1524 for (int xx = 0; xx < nx; xx++)
1525 {
1526 if (colorMode == 0)
1527 color = m_Doc->PageColors[getBinaryIndexedColor(istr)];
1528 else
1529 color = getBinaryDirectColor(istr);
1530 QColor co = color.getRawRGBColor();
1531 *s++ = qRgba(co.red(), co.green(), co.blue(), 255);
1532 }
1533 }
1534 else
1535 {
1536 int xx = 0;
1537 while (xx < nx)
1538 {
1539 int counter = getBinaryUInt(istr, intPrecision);
1540 if ((counter > nx) || (counter == 0))
1541 {
1542 importRunning = false;
1543 return;
1544 }
1545 if (colorMode == 0)
1546 color = m_Doc->PageColors[getBinaryIndexedColor(istr)];
1547 else
1548 color = getBinaryDirectColor(istr);
1549 QColor co = color.getRawRGBColor();
1550 for (int xc = 0; xc < counter; xc++)
1551 {
1552 *s++ = qRgba(co.red(), co.green(), co.blue(), 255);
1553 xx++;
1554 if (xx >= nx)
1555 break;
1556 }
1557 }
1558 }
1559 uint adj = istr.device()->pos() % 2;
1560 if (adj != 0)
1561 istr.skipRawData(1);
1562 }
1563 }
1564 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_cgm_XXXXXX.png");
1565 tempFile->setAutoRemove(false);
1566 tempFile->open();
1567 QString fileName = getLongPathName(tempFile->fileName());
1568 tempFile->close();
1569 ite->isInlineImage = true;
1570 ite->isTempFile = true;
1571 image.save(fileName, "PNG");
1572 if ((image.width() < 20) || image.height() < 20)
1573 ite->pixm.imgInfo.lowResType = 0;
1574 m_Doc->loadPict(fileName, ite);
1575 delete tempFile;
1576 ite->setImageFlippedH(flipX);
1577 ite->setImageFlippedV(flipY);
1578 ite->setImageScalingMode(false, false);
1579 ite->adjustPictScale();
1580 colorPrecision = t_colorPrecision;
1581 colorIndexPrecision = t_colorIndexPrecision;
1582 }
1583 else if (elemID == 10)
1584 {
1585 qDebug() << "GENERALIZED DRAWING PRIMITIVE";
1586 }
1587 else if (elemID == 11)
1588 {
1589 QPointF max, min;
1590 max = getBinaryCoords(ts);
1591 min = getBinaryCoords(ts);
1592 QRectF vd = QRectF(max, min);
1593 vd = vd.normalized();
1594 double w = convertCoords(vd.width());
1595 double h = convertCoords(vd.height());
1596 double x = convertCoords(vd.left());
1597 double y = convertCoords(vd.top());
1598 if (recordRegion)
1599 regionPath.addRect(QRectF(x + m_Doc->currentPage()->xOffset(), y + m_Doc->currentPage()->yOffset(), w, h));
1600 else
1601 {
1602 if (recordFigure)
1603 figurePath.addRect(QRectF(x + m_Doc->currentPage()->xOffset(), y + m_Doc->currentPage()->yOffset(), w, h));
1604 PageItem *ite = itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + x, baseY + y, w, h, edgeWidth, fillColor, edgeColor);
1605 ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1606 finishItem(ite, false);
1607 }
1608 // qDebug() << "RECTANGLE";
1609 }
1610 else if (elemID == 12)
1611 {
1612 QPointF max = getBinaryCoords(ts);
1613 double x = convertCoords(max.x());
1614 double y = convertCoords(max.y());
1615 double r = convertCoords(getBinaryDistance(ts));
1616 x = x - r;
1617 y = y - r;
1618 if (recordRegion)
1619 regionPath.addEllipse(QPointF(x + m_Doc->currentPage()->xOffset(), y + m_Doc->currentPage()->yOffset()), r * 2.0, r * 2.0);
1620 else
1621 {
1622 if (recordFigure)
1623 figurePath.addEllipse(QRectF(x + m_Doc->currentPage()->xOffset(), y + m_Doc->currentPage()->yOffset(), r * 2.0, r * 2.0));
1624 PageItem *ite = itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + x, baseY + y, r * 2.0, r * 2.0, edgeWidth, fillColor, edgeColor);
1625 ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1626 finishItem(ite, false);
1627 }
1628 // qDebug() << "CIRCLE";
1629 }
1630 else if (elemID == 13)
1631 {
1632 QPointF pStart = convertCoords(getBinaryCoords(ts));
1633 QPointF pInter = convertCoords(getBinaryCoords(ts));
1634 QPointF pEnd = convertCoords(getBinaryCoords(ts));
1635 QLineF s_e = QLineF(pStart, pEnd);
1636 QLineF n_s = s_e.normalVector();
1637 n_s.translate(s_e.pointAt(0.5) - s_e.p1());
1638 QLineF s_i = QLineF(pStart, pInter);
1639 QLineF n_i = s_i.normalVector();
1640 n_i.translate(s_i.pointAt(0.5) - s_i.p1());
1641 QPointF center;
1642 if (n_s.intersects(n_i, ¢er) != QLineF::NoIntersection)
1643 {
1644 QLineF rad1 = QLineF(center, pStart);
1645 QLineF rad3 = QLineF(center, pInter);
1646 double radius = rad1.length();
1647 Coords.resize(0);
1648 Coords.svgInit();
1649 Coords.svgMoveTo(pStart.x(), pStart.y());
1650 Coords.svgArcTo(radius, radius, 0, false, rad1.angle() >= rad3.angle(), pInter.x(), pInter.y());
1651 Coords.svgArcTo(radius, radius, 0, false, rad1.angle() >= rad3.angle(), pEnd.x(), pEnd.y());
1652 Coords.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1653 if (recordRegion)
1654 regionPath.connectPath(Coords.toQPainterPath(false));
1655 else
1656 {
1657 if (recordFigure)
1658 {
1659 if (figClose)
1660 {
1661 QPainterPath ell = Coords.toQPainterPath(false);
1662 appendPath(figurePath, ell);
1663 figClose = false;
1664 }
1665 else
1666 figurePath.connectPath(Coords.toQPainterPath(false));
1667 }
1668 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, CommonStrings::None, lineColor);
1669 PageItem *ite = m_Doc->Items->at(z);
1670 ite->PoLine = Coords.copy();
1671 finishItem(ite);
1672 }
1673 }
1674 // qDebug() << "CIRCULAR ARC 3 POINT";
1675 }
1676 else if (elemID == 14)
1677 {
1678 QPointF pStart = convertCoords(getBinaryCoords(ts));
1679 QPointF pInter = convertCoords(getBinaryCoords(ts));
1680 QPointF pEnd = convertCoords(getBinaryCoords(ts));
1681 quint16 mode;
1682 ts >> mode;
1683 QLineF s_e = QLineF(pStart, pEnd);
1684 QLineF n_s = s_e.normalVector();
1685 n_s.translate(s_e.pointAt(0.5) - s_e.p1());
1686 QLineF s_i = QLineF(pStart, pInter);
1687 QLineF n_i = s_i.normalVector();
1688 n_i.translate(s_i.pointAt(0.5) - s_i.p1());
1689 QPointF center;
1690 if (n_s.intersects(n_i, ¢er) != QLineF::NoIntersection)
1691 {
1692 QLineF rad1 = QLineF(center, pStart);
1693 QLineF rad3 = QLineF(center, pInter);
1694 double radius = rad1.length();
1695 Coords.resize(0);
1696 Coords.svgInit();
1697 if (mode == 0)
1698 {
1699 Coords.svgMoveTo(center.x(), center.y());
1700 Coords.svgLineTo(pStart.x(), pStart.y());
1701 }
1702 else
1703 Coords.svgMoveTo(pStart.x(), pStart.y());
1704 Coords.svgArcTo(radius, radius, 0, false, rad1.angle() >= rad3.angle(), pInter.x(), pInter.y());
1705 Coords.svgArcTo(radius, radius, 0, false, rad1.angle() >= rad3.angle(), pEnd.x(), pEnd.y());
1706 if (mode == 0)
1707 Coords.svgLineTo(center.x(), center.y());
1708 else
1709 Coords.svgLineTo(pStart.x(), pStart.y());
1710 Coords.svgClosePath();
1711 Coords.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1712 if (recordRegion)
1713 regionPath.addPath(Coords.toQPainterPath(false));
1714 else
1715 {
1716 if (recordFigure)
1717 figurePath.addPath(Coords.toQPainterPath(false));
1718 PageItem *ite = itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, edgeWidth, fillColor, edgeColor);
1719 ite->PoLine = Coords.copy();
1720 finishItem(ite, false);
1721 }
1722 }
1723 // qDebug() << "CIRCULAR ARC 3 POINT CLOSE";
1724 }
1725 else if (elemID == 15)
1726 {
1727 QPointF center = getBinaryCoords(ts);
1728 double sx = convertCoords(getBinaryDistance(ts));
1729 double sy = convertCoords(getBinaryDistance(ts));
1730 double ex = convertCoords(getBinaryDistance(ts));
1731 double ey = convertCoords(getBinaryDistance(ts));
1732 double r = convertCoords(getBinaryDistance(ts));
1733 double cx = convertCoords(center.x()) + m_Doc->currentPage()->xOffset();
1734 double cy = convertCoords(center.y()) + m_Doc->currentPage()->yOffset();
1735 if (vcdFlippedV)
1736 {
1737 sy *= -1;
1738 ey *= -1;
1739 }
1740 if (vcdFlippedH)
1741 {
1742 sx *= -1;
1743 ex *= -1;
1744 }
1745 QLineF stv = QLineF(cx, cy, cx + sx, cy + sy);
1746 QLineF env = QLineF(cx, cy, cx + ex, cy + ey);
1747 QPainterPath ell;
1748 if (qFuzzyCompare(sx, ex) && qFuzzyCompare(sy, ey))
1749 {
1750 ell.addEllipse(QPointF(cx, cy), r, r);
1751 }
1752 else
1753 {
1754 stv.setLength(r);
1755 ell.moveTo(stv.p2().x(), stv.p2().y());
1756 ell.arcTo(cx - r, cy - r, r * 2.0, r * 2.0, stv.angle(), stv.angleTo(env));
1757 }
1758 if (recordRegion)
1759 regionPath.connectPath(ell);
1760 else
1761 {
1762 if (recordFigure)
1763 {
1764 if (figClose)
1765 {
1766 appendPath(figurePath, ell);
1767 figClose = false;
1768 }
1769 else
1770 figurePath.connectPath(ell);
1771 }
1772 Coords.fromQPainterPath(ell, false);
1773 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, CommonStrings::None, lineColor);
1774 PageItem *ite = m_Doc->Items->at(z);
1775 ite->PoLine = Coords.copy();
1776 finishItem(ite);
1777 }
1778 // qDebug() << "CIRCULAR ARC CENTRE";
1779 }
1780 else if (elemID == 16)
1781 {
1782 quint16 mode;
1783 QPointF center = getBinaryCoords(ts);
1784 double sx = convertCoords(getBinaryDistance(ts));
1785 double sy = convertCoords(getBinaryDistance(ts));
1786 double ex = convertCoords(getBinaryDistance(ts));
1787 double ey = convertCoords(getBinaryDistance(ts));
1788 double r = convertCoords(getBinaryDistance(ts));
1789 ts >> mode;
1790 double cx = convertCoords(center.x()) + m_Doc->currentPage()->xOffset();
1791 double cy = convertCoords(center.y()) + m_Doc->currentPage()->yOffset();
1792 if (vcdFlippedV)
1793 {
1794 sy *= -1;
1795 ey *= -1;
1796 }
1797 if (vcdFlippedH)
1798 {
1799 sx *= -1;
1800 ex *= -1;
1801 }
1802 QLineF stv = QLineF(cx, cy, cx + sx, cy + sy);
1803 QLineF env = QLineF(cx, cy, cx + ex, cy + ey);
1804 QPainterPath ell;
1805 if (qFuzzyCompare(sx, ex) && qFuzzyCompare(sy, ey))
1806 {
1807 ell.addEllipse(QPointF(cx, cy), r, r);
1808 }
1809 else
1810 {
1811 stv.setLength(r);
1812 if (mode == 0)
1813 {
1814 ell.moveTo(cx, cy);
1815 ell.arcTo(cx - r, cy - r, r * 2.0, r * 2.0, stv.angle(), stv.angleTo(env));
1816 ell.lineTo(cx, cy);
1817 ell.closeSubpath();
1818 }
1819 else
1820 {
1821 ell.moveTo(stv.p2().x(), stv.p2().y());
1822 ell.arcTo(cx - r, cy - r, r * 2.0, r * 2.0, stv.angle(), stv.angleTo(env));
1823 ell.lineTo(stv.p2().x(), stv.p2().y());
1824 ell.closeSubpath();
1825 }
1826 }
1827 if (recordRegion)
1828 regionPath.addPath(ell);
1829 else
1830 {
1831 if (recordFigure)
1832 figurePath.addPath(ell);
1833 Coords.fromQPainterPath(ell, true);
1834 PageItem *ite = itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, edgeWidth, fillColor, edgeColor);
1835 ite->PoLine = Coords.copy();
1836 finishItem(ite, false);
1837 }
1838 // qDebug() << "CIRCULAR ARC CENTRE CLOSE";
1839 }
1840 else if (elemID == 17)
1841 {
1842 QPointF center, r1, r2;
1843 center = getBinaryCoords(ts);
1844 double cx = convertCoords(center.x());
1845 double cy = convertCoords(center.y());
1846 r1 = getBinaryCoords(ts);
1847 double r1x = convertCoords(r1.x());
1848 double r1y = convertCoords(r1.y());
1849 r2 = getBinaryCoords(ts);
1850 double r2x = convertCoords(r2.x());
1851 double r2y = convertCoords(r2.y());
1852 double distX = distance(r1x - cx, r1y - cy);
1853 double distY = distance(r2x - cx, r2y - cy);
1854 double rotB = xy2Deg(r1x - cx, r1y - cy);
1855 QPainterPath ell;
1856 ell.addEllipse(QPointF(0, 0), distX, distY);
1857 QTransform mm;
1858 mm.rotate(rotB);
1859 ell = mm.map(ell);
1860 ell.translate(cx, cy);
1861 if (recordRegion)
1862 {
1863 ell.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1864 regionPath.addPath(ell);
1865 }
1866 else
1867 {
1868 ell.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1869 if (recordFigure)
1870 figurePath.addPath(ell);
1871 Coords.fromQPainterPath(ell, true);
1872 PageItem *ite = itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, edgeWidth, fillColor, edgeColor);
1873 ite->PoLine = Coords.copy();
1874 finishItem(ite, false);
1875 }
1876 // qDebug() << "ELLIPSE";
1877 }
1878 else if (elemID == 18)
1879 {
1880 QPointF center = getBinaryCoords(ts);
1881 double cx = convertCoords(center.x());
1882 double cy = convertCoords(center.y());
1883 QPointF r1 = getBinaryCoords(ts);
1884 double r1x = convertCoords(r1.x());
1885 double r1y = convertCoords(r1.y());
1886 QPointF r2 = getBinaryCoords(ts);
1887 double r2x = convertCoords(r2.x());
1888 double r2y = convertCoords(r2.y());
1889 QLineF dstX = QLineF(cx, cy, r1x, r1y);
1890 QLineF dstY = QLineF(cx, cy, r2x, r2y);
1891 double distX = dstX.length();
1892 double distY = dstY.length();
1893 double rotB = dstX.angle();
1894 double sx = convertCoords(getBinaryDistance(ts));
1895 double sy = convertCoords(getBinaryDistance(ts));
1896 double ex = convertCoords(getBinaryDistance(ts));
1897 double ey = convertCoords(getBinaryDistance(ts));
1898 if (vcdFlippedV)
1899 {
1900 sy *= -1;
1901 ey *= -1;
1902 }
1903 if (vcdFlippedH)
1904 {
1905 sx *= -1;
1906 ex *= -1;
1907 }
1908 QLineF stv = QLineF(cx, cy, cx + sx, cy + sy);
1909 QLineF env = QLineF(cx, cy, cx + ex, cy + ey);
1910 QPainterPath ell;
1911 ell.addEllipse(QPointF(cx, cy), distX, distY);
1912 ell.translate(-cx, -cy);
1913 QTransform mm;
1914 mm.rotate(rotB);
1915 ell = mm.map(ell);
1916 ell.translate(cx, cy);
1917 QPolygonF elPo = ell.toFillPolygon();
1918 QPointF stP = stv.p2();
1919 QPointF enP = env.p2();
1920 if (qFuzzyCompare(sx, ex) && qFuzzyCompare(sy, ey))
1921 {
1922 ell.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1923 Coords.fromQPainterPath(ell);
1924 }
1925 else
1926 {
1927 for (int a = 0; a < elPo.size() - 1; a++)
1928 {
1929 QPointF intersect;
1930 if (QLineF(elPo[a], elPo[a+1]).intersects(stv, &intersect) == QLineF::BoundedIntersection)
1931 {
1932 stP = intersect;
1933 break;
1934 }
1935 }
1936 for (int a = 0; a < elPo.size() - 1; a++)
1937 {
1938 QPointF intersect;
1939 if (QLineF(elPo[a], elPo[a+1]).intersects(env, &intersect) == QLineF::BoundedIntersection)
1940 {
1941 enP = intersect;
1942 break;
1943 }
1944 }
1945 Coords.resize(0);
1946 Coords.svgInit();
1947 if (dstX.angleTo(dstY) > 180)
1948 {
1949 Coords.svgMoveTo(stP.x(), stP.y());
1950 Coords.svgArcTo(distX, distY, rotB, stv.angleTo(env) < 180, dstX.angleTo(dstY) > 180, enP.x(), enP.y());
1951 }
1952 else
1953 {
1954 Coords.svgMoveTo(stP.x(), stP.y());
1955 Coords.svgArcTo(distX, distY, rotB, stv.angleTo(env) > 180, dstX.angleTo(dstY) > 180, enP.x(), enP.y());
1956 }
1957 Coords.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1958 ell = Coords.toQPainterPath(false);
1959 }
1960 if (recordRegion)
1961 regionPath.connectPath(ell);
1962 else
1963 {
1964 if (recordFigure)
1965 {
1966 if (figClose)
1967 {
1968 appendPath(figurePath, ell);
1969 figClose = false;
1970 }
1971 else
1972 figurePath.connectPath(ell);
1973 }
1974 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, CommonStrings::None, lineColor);
1975 PageItem *ite = m_Doc->Items->at(z);
1976 ite->PoLine = Coords.copy();
1977 finishItem(ite);
1978 }
1979 // qDebug() << "ELLIPTICAL ARC";
1980 }
1981 else if (elemID == 19)
1982 {
1983 quint16 mode;
1984 QPointF center = getBinaryCoords(ts);
1985 double cx = convertCoords(center.x());
1986 double cy = convertCoords(center.y());
1987 QPointF r1 = getBinaryCoords(ts);
1988 double r1x = convertCoords(r1.x());
1989 double r1y = convertCoords(r1.y());
1990 QPointF r2 = getBinaryCoords(ts);
1991 double r2x = convertCoords(r2.x());
1992 double r2y = convertCoords(r2.y());
1993 QLineF dstX = QLineF(cx, cy, r1x, r1y);
1994 QLineF dstY = QLineF(cx, cy, r2x, r2y);
1995 double distX = dstX.length();
1996 double distY = dstY.length();
1997 double rotB = dstX.angle();
1998 double sx = convertCoords(getBinaryDistance(ts));
1999 double sy = convertCoords(getBinaryDistance(ts));
2000 double ex = convertCoords(getBinaryDistance(ts));
2001 double ey = convertCoords(getBinaryDistance(ts));
2002 ts >> mode;
2003 if (vcdFlippedV)
2004 {
2005 sy *= -1;
2006 ey *= -1;
2007 }
2008 if (vcdFlippedH)
2009 {
2010 sx *= -1;
2011 ex *= -1;
2012 }
2013 QLineF stv = QLineF(cx, cy, cx + sx, cy + sy);
2014 QLineF env = QLineF(cx, cy, cx + ex, cy + ey);
2015 QPainterPath ell;
2016 ell.addEllipse(QPointF(cx, cy), distX, distY);
2017 ell.translate(-cx, -cy);
2018 QTransform mm;
2019 mm.rotate(rotB);
2020 ell = mm.map(ell);
2021 ell.translate(cx, cy);
2022 QPolygonF elPo = ell.toFillPolygon();
2023 QPointF stP = stv.p2();
2024 for (int a = 0; a < elPo.size() - 1; a++)
2025 {
2026 QPointF intersect;
2027 if (QLineF(elPo[a], elPo[a+1]).intersects(stv, &intersect) == QLineF::BoundedIntersection)
2028 {
2029 stP = intersect;
2030 break;
2031 }
2032 }
2033 QPointF enP = env.p2();
2034 for (int a = 0; a < elPo.size() - 1; a++)
2035 {
2036 QPointF intersect;
2037 if (QLineF(elPo[a], elPo[a+1]).intersects(env, &intersect) == QLineF::BoundedIntersection)
2038 {
2039 enP = intersect;
2040 break;
2041 }
2042 }
2043 Coords.resize(0);
2044 Coords.svgInit();
2045 if (mode == 0)
2046 {
2047 Coords.svgMoveTo(cx, cy);
2048 if (dstX.angleTo(dstY) > 180)
2049 {
2050 Coords.svgLineTo(stP.x(), stP.y());
2051 Coords.svgArcTo(distX, distY, rotB, stv.angleTo(env) < 180, dstX.angleTo(dstY) > 180, enP.x(), enP.y());
2052 }
2053 else
2054 {
2055 Coords.svgLineTo(stP.x(), stP.y());
2056 Coords.svgArcTo(distX, distY, rotB, stv.angleTo(env) > 180, dstX.angleTo(dstY) > 180, enP.x(), enP.y());
2057 }
2058 Coords.svgLineTo(cx, cy);
2059 Coords.svgClosePath();
2060 }
2061 else
2062 {
2063 if (dstX.angleTo(dstY) > 180)
2064 {
2065 Coords.svgMoveTo(stP.x(), stP.y());
2066 Coords.svgArcTo(distX, distY, rotB, stv.angleTo(env) < 180, dstX.angleTo(dstY) > 180, enP.x(), enP.y());
2067 }
2068 else
2069 {
2070 Coords.svgMoveTo(stP.x(), stP.y());
2071 Coords.svgArcTo(distX, distY, rotB, stv.angleTo(env) > 180, dstX.angleTo(dstY) > 180, enP.x(), enP.y());
2072 }
2073 Coords.svgLineTo(stP.x(), stP.y());
2074 Coords.svgClosePath();
2075 }
2076 Coords.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
2077 if (recordRegion)
2078 regionPath.addPath(Coords.toQPainterPath(false));
2079 else
2080 {
2081 if (recordFigure)
2082 figurePath.addPath(Coords.toQPainterPath(false));
2083 PageItem *ite = itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, edgeWidth, fillColor, edgeColor);
2084 ite->PoLine = Coords.copy();
2085 finishItem(ite, false);
2086 }
2087 // qDebug() << "ELLIPTICAL ARC CLOSE";
2088 }
2089 else if (elemID == 20)
2090 {
2091 qDebug() << "CIRCULAR ARC CENTRE REVERSED";
2092 }
2093 else if (elemID == 21)
2094 {
2095 qDebug() << "CONNECTING EDGE";
2096 }
2097 else if (elemID == 22)
2098 {
2099 qDebug() << "HYPERBOLIC ARC";
2100 }
2101 else if (elemID == 23)
2102 {
2103 qDebug() << "PARABOLIC ARC";
2104 }
2105 else if (elemID == 24)
2106 {
2107 qDebug() << "NON-UNIFORM B-SPLINE";
2108 }
2109 else if (elemID == 25)
2110 {
2111 qDebug() << "NON-UNIFORM RATIONAL B-SPLINE";
2112 }
2113 else if (elemID == 26)
2114 {
2115 getBinaryBezierPath(ts, paramLen);
2116 if (Coords.size() > 3)
2117 {
2118 Coords.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
2119 if (recordRegion)
2120 regionPath.addPath(Coords.toQPainterPath(false));
2121 else
2122 {
2123 if (recordFigure)
2124 {
2125 if (figClose)
2126 {
2127 QPainterPath ell = Coords.toQPainterPath(false);
2128 appendPath(figurePath, ell);
2129 figClose = false;
2130 }
2131 else
2132 figurePath.connectPath(Coords.toQPainterPath(false));
2133 }
2134 int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, CommonStrings::None, lineColor);
2135 PageItem *ite = m_Doc->Items->at(z);
2136 ite->PoLine = Coords.copy();
2137 finishItem(ite);
2138 }
2139 }
2140 // qDebug() << "POLYBEZIER";
2141 }
2142 else if (elemID == 27)
2143 {
2144 qDebug() << "POLYSYMBOL";
2145 }
2146 else if (elemID == 28)
2147 {
2148 uint comp = getBinaryUInt(ts, indexPrecision);
2149 uint pad = getBinaryUInt(ts, intPrecision);
2150 QString backColor = getBinaryColor(ts);
2151 QString foreColor = getBinaryColor(ts);
2152 uint prec = getBinaryUInt(ts, intPrecision);
2153 qDebug() << "BITONAL TILE Compression" << comp << "Padding" << pad << "Background" << backColor << "Foreground" << foreColor << "Precision" << prec;
2154 }
2155 else if (elemID == 29)
2156 {
2157 qDebug() << "TILE";
2158 }
2159 else
2160 {
2161 importRunning = false;
2162 qDebug() << "Class 4 ID" << elemID << "Len" << paramLen;
2163 }
2164 }
2165
decodeClass5(QDataStream & ts,quint16 elemID,quint16 paramLen)2166 void CgmPlug::decodeClass5(QDataStream &ts, quint16 elemID, quint16 paramLen)
2167 {
2168 if (elemID == 1)
2169 {
2170 lineBundleIndex = getBinaryUInt(ts, indexPrecision);
2171 // qDebug() << "LINE BUNDLE INDEX" << lineBundleIndex;
2172 }
2173 else if (elemID == 2)
2174 {
2175 uint type = getBinaryUInt(ts, indexPrecision);
2176 if (type == 1)
2177 lineType = Qt::SolidLine;
2178 else if (type == 2)
2179 lineType = Qt::DashLine;
2180 else if (type == 3)
2181 lineType = Qt::DotLine;
2182 else if (type == 4)
2183 lineType = Qt::DashDotLine;
2184 else if (type == 5)
2185 lineType = Qt::DashDotDotLine;
2186 else
2187 lineType = Qt::SolidLine;
2188 // qDebug() << "LINE TYPE" << lineType;
2189 }
2190 else if (elemID == 3)
2191 {
2192 lineWidth = getBinaryDistance(ts);
2193 if (lineWidthMode == 0)
2194 lineWidth *= metaScale;
2195 else if (lineWidthMode == 1)
2196 lineWidth *= 1.0;
2197 else if (lineWidthMode == 2)
2198 lineWidth *= 0.001;
2199 else if (lineWidthMode == 3)
2200 lineWidth *= 0.35;
2201 // if (lineWidth < 1)
2202 // lineWidth = 0;
2203 // qDebug() << "LINE WIDTH" << lineWidth;
2204 }
2205 else if (elemID == 4)
2206 {
2207 lineColor = getBinaryColor(ts);
2208 // qDebug() << "LINE COLOUR" << lineColor;
2209 }
2210 else if (elemID == 5)
2211 {
2212 qDebug() << "MARKER BUNDLE INDEX";
2213 }
2214 else if (elemID == 6)
2215 {
2216 qDebug() << "MARKER TYPE";
2217 }
2218 else if (elemID == 7)
2219 {
2220 qDebug() << "MARKER SIZE";
2221 }
2222 else if (elemID == 8)
2223 {
2224 qDebug() << "MARKER COLOUR";
2225 }
2226 else if (elemID == 9)
2227 {
2228 qDebug() << "TEXT BUNDLE INDEX";
2229 }
2230 else if (elemID == 10)
2231 {
2232 m_fontIndex = getBinaryUInt(ts, indexPrecision);
2233 // qDebug() << "TEXT FONT INDEX" << m_fontIndex;
2234 }
2235 else if (elemID == 11)
2236 {
2237 qDebug() << "TEXT PRECISION";
2238 }
2239 else if (elemID == 12)
2240 {
2241 qDebug() << "CHARACTER EXPANSION FACTOR";
2242 }
2243 else if (elemID == 13)
2244 {
2245 qDebug() << "CHARACTER SPACING";
2246 }
2247 else if (elemID == 14)
2248 {
2249 textColor = getBinaryColor(ts);
2250 // qDebug() << "TEXT COLOUR" << textColor;
2251 }
2252 else if (elemID == 15)
2253 {
2254 textSize = getBinaryDistance(ts);
2255 textSize *= metaScale;
2256 // qDebug() << "CHARACTER HEIGHT" << textSize;
2257 }
2258 else if (elemID == 16)
2259 {
2260 qDebug() << "CHARACTER ORIENTATION";
2261 }
2262 else if (elemID == 17)
2263 {
2264 qDebug() << "TEXT PATH";
2265 }
2266 else if (elemID == 18)
2267 {
2268 quint16 hFlag;
2269 ts >> hFlag;
2270 textAlignH = hFlag;
2271 // qDebug() << "TEXT ALIGNMENT" << hFlag;
2272 }
2273 else if (elemID == 19)
2274 {
2275 qDebug() << "CHARACTER SET INDEX";
2276 }
2277 else if (elemID == 20)
2278 {
2279 qDebug() << "ALTERNATE CHARACTER SET INDEX";
2280 }
2281 else if (elemID == 21)
2282 {
2283 qDebug() << "FILL BUNDLE INDEX";
2284 }
2285 else if (elemID == 22)
2286 {
2287 quint16 data;
2288 ts >> data;
2289 fillType = data;
2290 // qDebug() << "INTERIOR STYLE" << fillType;
2291 }
2292 else if (elemID == 23)
2293 {
2294 fillColor = getBinaryColor(ts);
2295 // qDebug() << "Fill COLOUR" << fillColor;
2296 }
2297 else if (elemID == 24)
2298 {
2299 qDebug() << "HATCH INDEX";
2300 }
2301 else if (elemID == 25)
2302 {
2303 patternIndex = getBinaryUInt(ts, indexPrecision);
2304 // Hack to fix some broken(?) CGM files
2305 //fillType = 2;
2306 // qDebug() << "PATTERN INDEX" << patternIndex;
2307 }
2308 else if (elemID == 26)
2309 {
2310 qDebug() << "EDGE BUNDLE INDEX";
2311 }
2312 else if (elemID == 27)
2313 {
2314 uint type = getBinaryUInt(ts, indexPrecision);
2315 if (type == 1)
2316 edgeType = Qt::SolidLine;
2317 else if (type == 2)
2318 edgeType = Qt::DashLine;
2319 else if (type == 3)
2320 edgeType = Qt::DotLine;
2321 else if (type == 4)
2322 edgeType = Qt::DashDotLine;
2323 else if (type == 5)
2324 edgeType = Qt::DashDotDotLine;
2325 else
2326 edgeType = Qt::SolidLine;
2327 // qDebug() << "EDGE TYPE";
2328 }
2329 else if (elemID == 28)
2330 {
2331 edgeWidth = getBinaryDistance(ts);
2332 if (edgeWidthMode == 0)
2333 edgeWidth *= metaScale;
2334 else if (edgeWidthMode == 1)
2335 edgeWidth *= 1.0;
2336 else if (edgeWidthMode == 2)
2337 edgeWidth *= 0.001;
2338 else if (edgeWidthMode == 3)
2339 edgeWidth *= 0.35;
2340 // if (edgeWidth < 1)
2341 // edgeWidth = 0;
2342 // qDebug() << "EDGE WIDTH" << edgeWidth;
2343 }
2344 else if (elemID == 29)
2345 {
2346 edgeColor = getBinaryColor(ts);
2347 // qDebug() << "EDGE COLOUR" << edgeColor;
2348 }
2349 else if (elemID == 30)
2350 {
2351 quint16 data;
2352 ts >> data;
2353 lineVisible = data != 0;
2354 // qDebug() << "EDGE VISIBILITY";
2355 }
2356 else if (elemID == 31)
2357 {
2358 QPointF p = getBinaryCoords(ts);
2359 double x = convertCoords(p.x());
2360 double y = convertCoords(p.y());
2361 fillRefPoint = QPointF(x + m_Doc->currentPage()->xOffset(), y + m_Doc->currentPage()->yOffset());
2362 // qDebug() << "FILL REFERENCE POINT" << fillRefPoint;
2363 }
2364 else if (elemID == 32)
2365 {
2366 uint index = getBinaryUInt(ts, indexPrecision);
2367 uint nx = getBinaryUInt(ts, intPrecision);
2368 uint ny = getBinaryUInt(ts, intPrecision);
2369 int t_colorPrecision = colorPrecision;
2370 colorPrecision = getBinaryUInt(ts, intPrecision);
2371 QImage tmpImg = QImage(nx, ny, QImage::Format_ARGB32);
2372 for (uint a = 0; a < ny; a++)
2373 {
2374 QRgb *s = (QRgb*)tmpImg.scanLine(a);
2375 for (uint b = 0; b < nx; b++)
2376 {
2377 ScColor color;
2378 if (colorMode == 0)
2379 color = m_Doc->PageColors[getBinaryIndexedColor(ts)];
2380 else
2381 color = getBinaryDirectColor(ts);
2382 QColor co = color.getRawRGBColor();
2383 *s = qRgba(co.red(), co.green(), co.blue(), 255);
2384 s++;
2385 }
2386 }
2387 int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Rectangle, 0, 0, tmpImg.width(), tmpImg.height(), 0, CommonStrings::None, CommonStrings::None);
2388 PageItem* ite = m_Doc->Items->at(z);
2389 ite->SetRectFrame();
2390 ite->setTextFlowMode(PageItem::TextFlowDisabled);
2391 m_Doc->adjustItemSize(ite);
2392 ite->OldB2 = ite->width();
2393 ite->OldH2 = ite->height();
2394 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_cgm_XXXXXX.png");
2395 tempFile->setAutoRemove(false);
2396 if (tempFile->open())
2397 {
2398 QString fileName = getLongPathName(tempFile->fileName());
2399 if (!fileName.isEmpty())
2400 {
2401 tempFile->close();
2402 ite->isInlineImage = true;
2403 ite->isTempFile = true;
2404 tmpImg.save(fileName, "PNG");
2405 m_Doc->loadPict(fileName, ite);
2406 ite->setImageScalingMode(false, true);
2407 ScPattern pat = ScPattern();
2408 pat.setDoc(m_Doc);
2409 pat.pattern = tmpImg;
2410 pat.xoffset = 0;
2411 pat.yoffset = 0;
2412 pat.width = ite->width();
2413 pat.height = ite->height();
2414 ite->gXpos = 0;
2415 ite->gYpos = 0;
2416 ite->setXYPos(ite->gXpos, ite->gYpos, true);
2417 pat.items.append(ite);
2418 m_Doc->Items->removeAll(ite);
2419 QString id = QString("Pattern_from_CGM_%1").arg(m_Doc->docPatterns.count() + 1);
2420 m_Doc->addPattern(id, pat);
2421 patternTable.insert(index, id);
2422 }
2423 else
2424 {
2425 m_Doc->Items->removeAll(ite);
2426 delete ite;
2427 }
2428 }
2429 else
2430 {
2431 m_Doc->Items->removeAll(ite);
2432 delete ite;
2433 }
2434 delete tempFile;
2435 colorPrecision = t_colorPrecision;
2436 // qDebug() << "PATTERN TABLE" << "Index" << index << "NX" << nx << "NY" << ny;
2437 }
2438 else if (elemID == 33)
2439 {
2440 double phx = convertCoords(getBinaryDistance(ts));
2441 double phy = convertCoords(getBinaryDistance(ts));
2442 double pwx = convertCoords(getBinaryDistance(ts));
2443 double pwy = convertCoords(getBinaryDistance(ts));
2444 QLineF hp = QLineF(0, 0, phx, phy);
2445 QLineF wp = QLineF(0, 0, pwx, pwy);
2446 patternScaleX = wp.length();
2447 patternScaleY = hp.length();
2448 // qDebug() << "PATTERN SIZE" << wp.length() << hp.length();
2449 }
2450 else if (elemID == 34)
2451 {
2452 // qDebug() << "COLOUR TABLE" << "Starting at" << ts.device()->pos();
2453 getBinaryColorTable(ts, paramLen);
2454 }
2455 else if (elemID == 35)
2456 {
2457 qDebug() << "ASPECT SOURCE FLAGS";
2458 }
2459 else if (elemID == 36)
2460 {
2461 qDebug() << "PICK IDENTIFIER";
2462 }
2463 else if (elemID == 37)
2464 {
2465 uint type = getBinaryUInt(ts, indexPrecision);
2466 if (type == 1)
2467 lineCap = Qt::FlatCap;
2468 else if (type == 2)
2469 lineCap = Qt::RoundCap;
2470 else if (type == 3)
2471 lineCap = Qt::SquareCap;
2472 else
2473 lineCap = Qt::FlatCap;
2474 type = getBinaryUInt(ts, indexPrecision); // dummy reading unsupported parameter
2475 // qDebug() << "LINE CAP";
2476 }
2477 else if (elemID == 38)
2478 {
2479 uint type = getBinaryUInt(ts, indexPrecision);
2480 if (type == 1)
2481 lineJoin = Qt::MiterJoin;
2482 else if (type == 2)
2483 lineJoin = Qt::RoundJoin;
2484 else if (type == 3)
2485 lineJoin = Qt::BevelJoin;
2486 else
2487 lineJoin = Qt::MiterJoin;
2488 // qDebug() << "LINE JOIN";
2489 }
2490 else if (elemID == 39)
2491 {
2492 qDebug() << "LINE TYPE CONTINUATION";
2493 }
2494 else if (elemID == 40)
2495 {
2496 qDebug() << "LINE TYPE INITIAL OFFSET";
2497 }
2498 else if (elemID == 41)
2499 {
2500 qDebug() << "TEXT SCORE TYPE";
2501 }
2502 else if (elemID == 42)
2503 {
2504 textScaleMode = getBinaryUInt(ts, indexPrecision);
2505 qDebug() << "RESTRICTED TEXT TYPE" << textScaleMode;
2506 }
2507 else if (elemID == 43)
2508 {
2509 int posI = ts.device()->pos();
2510 uint type = getBinaryUInt(ts, indexPrecision);
2511 QPointF p1 = convertCoords(getBinaryCoords(ts));
2512 QPointF p2 = convertCoords(getBinaryCoords(ts));
2513 uint index = getBinaryUInt(ts, intPrecision);
2514 // qDebug() << "INTERPOLATED INTERIOR Type" << type << "from" << p1 << "to" << p2 << "Stages" << index << "at" << posI << realPrecision << realMantissa;
2515 for (uint s = 0; s < index; s++)
2516 {
2517 double s1 = getBinaryReal(ts, realPrecision, realMantissa);
2518 qDebug() << "Stages " << s1;
2519 }
2520 Q_UNUSED(posI);
2521 Q_UNUSED(type);
2522 Q_UNUSED(p1);
2523 Q_UNUSED(p2);
2524 /* int pos = ts.device()->pos();
2525 uint type = getBinaryUInt(ts, indexPrecision);
2526 QPointF p, p2;
2527 if (type == 1)
2528 {
2529 int posE = ts.device()->pos();
2530 p = QPointF(convertCoords(getBinaryDistance(ts)), convertCoords(getBinaryDistance(ts)));
2531 qDebug() << "End Point" << p << " at" << posE;
2532 }
2533 else if (type == 2)
2534 {
2535 int posE = ts.device()->pos();
2536 p = QPointF(convertCoords(getBinaryDistance(ts)), convertCoords(getBinaryDistance(ts)));
2537 p2 = QPointF(convertCoords(getBinaryDistance(ts)), convertCoords(getBinaryDistance(ts)));
2538 qDebug() << "Points" << p << p2 << " at" << posE;
2539 }
2540 int posI = ts.device()->pos();
2541 uint index = getBinaryUInt(ts, intPrecision);
2542 qDebug() << "Stages " << index << " at" << posI;
2543 for (uint s = 0; s < index; s++)
2544 {
2545 double s1 = getBinaryReal(ts, realPrecision, realMantissa);
2546 qDebug() << "first 2 Stages " << s1;
2547 }
2548 ts.device()->seek(pos); */
2549 // qDebug() << "INTERPOLATED INTERIOR Type" << type << "from" << p1 << "to" << p2 << "Stages" << index << "at" << posI;
2550 }
2551 else if (elemID == 44)
2552 {
2553 uint type = getBinaryUInt(ts, indexPrecision);
2554 if (type == 1)
2555 edgeCap = Qt::FlatCap;
2556 else if (type == 2)
2557 edgeCap = Qt::RoundCap;
2558 else if (type == 3)
2559 edgeCap = Qt::SquareCap;
2560 else
2561 edgeCap = Qt::FlatCap;
2562 type = getBinaryUInt(ts, indexPrecision); // dummy reading unsupported parameter
2563 // qDebug() << "EDGE CAP";
2564 }
2565 else if (elemID == 45)
2566 {
2567 uint type = getBinaryUInt(ts, indexPrecision);
2568 if (type == 1)
2569 edgeJoin = Qt::MiterJoin;
2570 else if (type == 2)
2571 edgeJoin = Qt::RoundJoin;
2572 else if (type == 3)
2573 edgeJoin = Qt::BevelJoin;
2574 else
2575 edgeJoin = Qt::MiterJoin;
2576 // qDebug() << "EDGE JOIN";
2577 }
2578 else if (elemID == 46)
2579 {
2580 qDebug() << "EDGE TYPE CONTINUATION";
2581 }
2582 else if (elemID == 47)
2583 {
2584 qDebug() << "EDGE TYPE INITIAL OFFSET";
2585 }
2586 else if (elemID == 48)
2587 {
2588 qDebug() << "SYMBOL LIBRARY INDEX";
2589 }
2590 else if (elemID == 49)
2591 {
2592 qDebug() << "SYMBOL COLOUR";
2593 }
2594 else if (elemID == 50)
2595 {
2596 qDebug() << "SYMBOL SIZE";
2597 }
2598 else if (elemID == 51)
2599 {
2600 qDebug() << "SYMBOL ORIENTATION";
2601 }
2602 else
2603 {
2604 importRunning = false;
2605 qDebug() << "Class 5 ID" << elemID << "Len" << paramLen;
2606 }
2607 }
2608
decodeClass6(QDataStream & ts,quint16 elemID,quint16 paramLen)2609 void CgmPlug::decodeClass6(QDataStream &ts, quint16 elemID, quint16 paramLen)
2610 {
2611 if (elemID == 1)
2612 {
2613 qDebug() << "ESCAPE";
2614 }
2615 else
2616 {
2617 importRunning = false;
2618 qDebug() << "Class 6 ID" << elemID << "Len" << paramLen;
2619 }
2620 }
2621
decodeClass7(QDataStream & ts,quint16 elemID,quint16 paramLen)2622 void CgmPlug::decodeClass7(QDataStream &ts, quint16 elemID, quint16 paramLen)
2623 {
2624 if (elemID == 1)
2625 {
2626 qDebug() << "MESSAGE";
2627 }
2628 else if (elemID == 2)
2629 {
2630 qDebug() << "APPLICATION DATA" << paramLen << "at" << ts.device()->pos();
2631 }
2632 else
2633 {
2634 importRunning = false;
2635 qDebug() << "Class 7 ID" << elemID << "Len" << paramLen;
2636 }
2637 }
2638
decodeClass8(QDataStream & ts,quint16 elemID,quint16 paramLen)2639 void CgmPlug::decodeClass8(QDataStream &ts, quint16 elemID, quint16 paramLen)
2640 {
2641 if (elemID == 1)
2642 {
2643 qDebug() << "COPY SEGMENT";
2644 }
2645 else if (elemID == 2)
2646 {
2647 qDebug() << "INHERITANCE FILTER";
2648 }
2649 else if (elemID == 3)
2650 {
2651 qDebug() << "CLIP INHERITANCE";
2652 }
2653 else if (elemID == 4)
2654 {
2655 qDebug() << "SEGMENT TRANSFORMATION";
2656 }
2657 else if (elemID == 5)
2658 {
2659 qDebug() << "SEGMENT HIGHLIGHTING";
2660 }
2661 else if (elemID == 6)
2662 {
2663 qDebug() << "SEGMENT DISPLAY PRIORITY";
2664 }
2665 else if (elemID == 7)
2666 {
2667 qDebug() << "SEGMENT PICK PRIORITY";
2668 }
2669 else
2670 {
2671 importRunning = false;
2672 qDebug() << "Class 8 ID" << elemID << "Len" << paramLen;
2673 }
2674 }
2675
decodeClass9(QDataStream & ts,quint16 elemID,quint16 paramLen)2676 void CgmPlug::decodeClass9(QDataStream &ts, quint16 elemID, quint16 paramLen)
2677 {
2678 if (elemID == 1)
2679 {
2680 qDebug() << "APPLICATION STRUCTURE ATTRIBUTE";
2681 }
2682 else
2683 {
2684 importRunning = false;
2685 qDebug() << "Class 9 ID" << elemID << "Len" << paramLen;
2686 }
2687 }
2688
getBinaryBezierPath(QDataStream & ts,quint16 paramLen)2689 void CgmPlug::getBinaryBezierPath(QDataStream &ts, quint16 paramLen)
2690 {
2691 quint16 bytesRead = 0;
2692 bool first = true;
2693 Coords.resize(0);
2694 Coords.svgInit();
2695 quint16 flag;
2696 flag = paramLen & 0x8000;
2697 paramLen = paramLen & 0x7FFF;
2698 uint type = getBinaryUInt(ts, indexPrecision);
2699 while (bytesRead < paramLen - 2)
2700 {
2701 int posA = ts.device()->pos();
2702 if ((first) || (type == 1))
2703 {
2704 QPointF p = getBinaryCoords(ts);
2705 Coords.svgMoveTo(convertCoords(p.x()), convertCoords(p.y()));
2706 first = false;
2707 }
2708 QPointF p1 = getBinaryCoords(ts);
2709 QPointF p2 = getBinaryCoords(ts);
2710 QPointF p3 = getBinaryCoords(ts);
2711 Coords.svgCurveToCubic(convertCoords(p1.x()), convertCoords(p1.y()), convertCoords(p2.x()), convertCoords(p2.y()), convertCoords(p3.x()), convertCoords(p3.y()));
2712 int posN = ts.device()->pos();
2713 bytesRead += posN - posA;
2714 }
2715 while (flag)
2716 {
2717 bytesRead = 0;
2718 ts >> paramLen;
2719 flag = paramLen & 0x8000;
2720 paramLen = paramLen & 0x7FFF;
2721 while (bytesRead < paramLen)
2722 {
2723 int posA = ts.device()->pos();
2724 if (type == 1)
2725 {
2726 QPointF p = getBinaryCoords(ts);
2727 Coords.svgMoveTo(convertCoords(p.x()), convertCoords(p.y()));
2728 }
2729 QPointF p1 = getBinaryCoords(ts);
2730 QPointF p2 = getBinaryCoords(ts);
2731 QPointF p3 = getBinaryCoords(ts);
2732 Coords.svgCurveToCubic(convertCoords(p1.x()), convertCoords(p1.y()), convertCoords(p2.x()), convertCoords(p2.y()), convertCoords(p3.x()), convertCoords(p3.y()));
2733 int posN = ts.device()->pos();
2734 bytesRead += posN - posA;
2735 }
2736 }
2737 }
2738
getBinaryPath(QDataStream & ts,quint16 paramLen,bool disjoint)2739 void CgmPlug::getBinaryPath(QDataStream &ts, quint16 paramLen, bool disjoint)
2740 {
2741 quint16 bytesRead = 0;
2742 bool first = true;
2743 Coords.resize(0);
2744 Coords.svgInit();
2745 quint16 flag;
2746 flag = paramLen & 0x8000;
2747 paramLen = paramLen & 0x7FFF;
2748 while (bytesRead < paramLen)
2749 {
2750 int posA = ts.device()->pos();
2751 QPointF p = getBinaryCoords(ts);
2752 if (first)
2753 {
2754 Coords.svgMoveTo(convertCoords(p.x()), convertCoords(p.y()));
2755 first = false;
2756 }
2757 else
2758 {
2759 Coords.svgLineTo(convertCoords(p.x()), convertCoords(p.y()));
2760 if (disjoint)
2761 first = true;
2762 }
2763 int posN = ts.device()->pos();
2764 bytesRead += posN - posA;
2765 }
2766 while (flag)
2767 {
2768 bytesRead = 0;
2769 ts >> paramLen;
2770 flag = paramLen & 0x8000;
2771 paramLen = paramLen & 0x7FFF;
2772 while (bytesRead < paramLen)
2773 {
2774 int posA = ts.device()->pos();
2775 if (disjoint)
2776 {
2777 QPointF p = getBinaryCoords(ts);
2778 if (first)
2779 {
2780 Coords.svgMoveTo(convertCoords(p.x()), convertCoords(p.y()));
2781 first = false;
2782 }
2783 else
2784 {
2785 Coords.svgLineTo(convertCoords(p.x()), convertCoords(p.y()));
2786 if (disjoint)
2787 first = true;
2788 }
2789 }
2790 else
2791 {
2792 QPointF p = getBinaryCoords(ts);
2793 Coords.svgLineTo(convertCoords(p.x()), convertCoords(p.y()));
2794 }
2795 int posN = ts.device()->pos();
2796 bytesRead += posN - posA;
2797 }
2798 }
2799 }
2800
getBinaryColorTable(QDataStream & ts,quint16 paramLen)2801 void CgmPlug::getBinaryColorTable(QDataStream &ts, quint16 paramLen)
2802 {
2803 quint16 flag;
2804 flag = paramLen & 0x8000;
2805 paramLen = paramLen & 0x7FFF;
2806 quint16 bytesRead = 0;
2807 int posA = ts.device()->pos();
2808 uint c = getBinaryUInt(ts, colorIndexPrecision);
2809 int posN = ts.device()->pos();
2810 bytesRead += posN - posA;
2811 QString tmpName = CommonStrings::None;
2812 while (bytesRead < paramLen)
2813 {
2814 posA = ts.device()->pos();
2815 ScColor cc = getBinaryDirectColor(ts);
2816 tmpName = handleColor(cc, "FromCGM"+cc.name());
2817 ColorTableMap.insert(c, tmpName);
2818 c++;
2819 posN = ts.device()->pos();
2820 bytesRead += posN - posA;
2821 }
2822 while (flag)
2823 {
2824 bytesRead = 0;
2825 ts >> paramLen;
2826 flag = paramLen & 0x8000;
2827 paramLen = paramLen & 0x7FFF;
2828 while (bytesRead < paramLen)
2829 {
2830 posA = ts.device()->pos();
2831 //ScColor cc = getBinaryDirectColor(ts);
2832 ColorTableMap.insert(c, tmpName);
2833 c++;
2834 posN = ts.device()->pos();
2835 bytesRead += posN - posA;
2836 }
2837 }
2838 }
2839
getBinaryDirectColor(ScBitReader * breader)2840 ScColor CgmPlug::getBinaryDirectColor(ScBitReader *breader)
2841 {
2842 ScColor ret;
2843 if (m_colorModel == 1) // RGB
2844 {
2845 int r = breader->getUInt(colorPrecision);
2846 int g = breader->getUInt(colorPrecision);
2847 int b = breader->getUInt(colorPrecision);
2848 r = qRound(r * (maxColor - minColor) / static_cast<double>(maxColor));
2849 g = qRound(g * (maxColor - minColor) / static_cast<double>(maxColor));
2850 b = qRound(b * (maxColor - minColor) / static_cast<double>(maxColor));
2851 ret = ScColor(r, g, b);
2852 }
2853 else if (m_colorModel == 4) // CMYK
2854 {
2855 uint c = breader->getUInt(colorPrecision);
2856 uint m = breader->getUInt(colorPrecision);
2857 uint y = breader->getUInt(colorPrecision);
2858 uint k = breader->getUInt(colorPrecision);
2859 c = qRound(c * (maxColor - minColor) / static_cast<double>(maxColor));
2860 m = qRound(m * (maxColor - minColor) / static_cast<double>(maxColor));
2861 y = qRound(y * (maxColor - minColor) / static_cast<double>(maxColor));
2862 k = qRound(k * (maxColor - minColor) / static_cast<double>(maxColor));
2863 ret = ScColor(c, m, y, k);
2864 }
2865 return ret;
2866 }
2867
getBinaryDirectColor(QDataStream & ts)2868 ScColor CgmPlug::getBinaryDirectColor(QDataStream &ts)
2869 {
2870 ScColor ret;
2871 if (m_colorModel == 1) // RGB
2872 {
2873 if (colorPrecision == 8)
2874 {
2875 quint8 ri, gi, bi;
2876 ts >> ri >> gi >> bi;
2877 int r = ri;
2878 int g = gi;
2879 int b = bi;
2880 r = qRound(r * (maxColor - minColor) / static_cast<double>(maxColor));
2881 g = qRound(g * (maxColor - minColor) / static_cast<double>(maxColor));
2882 b = qRound(b * (maxColor - minColor) / static_cast<double>(maxColor));
2883 ret = ScColor(r, g, b);
2884 }
2885 else if (colorPrecision == 16)
2886 {
2887 quint16 ri, gi, bi;
2888 ts >> ri >> gi >> bi;
2889 int r = ri;
2890 int g = gi;
2891 int b = bi;
2892 r = qRound((r * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2893 g = qRound((g * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2894 b = qRound((b * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2895 ret = ScColor(r, g, b);
2896 }
2897 else if (colorPrecision == 24)
2898 {
2899 quint8 p1;
2900 quint16 p2;
2901 quint32 ri = 0;
2902 quint32 gi = 0;
2903 quint32 bi = 0;
2904 ts >> p2;
2905 ts >> p1;
2906 ri = p2 << 8;
2907 ri |= p1;
2908 ts >> p2;
2909 ts >> p1;
2910 gi = p2 << 8;
2911 gi |= p1;
2912 ts >> p2;
2913 ts >> p1;
2914 bi = p2 << 8;
2915 bi |= p1;
2916 int r = ri;
2917 int g = gi;
2918 int b = bi;
2919 r = qRound((r * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2920 g = qRound((g * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2921 b = qRound((b * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2922 ret = ScColor(r, g, b);
2923 }
2924 else if (colorPrecision == 32)
2925 {
2926 quint32 ri, gi, bi;
2927 ts >> ri >> gi >> bi;
2928 int r = ri;
2929 int g = gi;
2930 int b = bi;
2931 r = qRound((r * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2932 g = qRound((g * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2933 b = qRound((b * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2934 ret = ScColor(r, g, b);
2935 }
2936 }
2937 else if (m_colorModel == 4) // CMYK
2938 {
2939 if (colorPrecision == 8)
2940 {
2941 quint8 ci, mi, yi, ki;
2942 ts >> ci >> mi >> yi >> ki;
2943 uint c = ci;
2944 uint m = mi;
2945 uint y = yi;
2946 uint k = ki;
2947 c = qRound(c * (maxColor - minColor) / static_cast<double>(maxColor));
2948 m = qRound(m * (maxColor - minColor) / static_cast<double>(maxColor));
2949 y = qRound(y * (maxColor - minColor) / static_cast<double>(maxColor));
2950 k = qRound(k * (maxColor - minColor) / static_cast<double>(maxColor));
2951 ret = ScColor(c, m, y, k);
2952 }
2953 else if (colorPrecision == 16)
2954 {
2955 quint16 ci, mi, yi, ki;
2956 ts >> ci >> mi >> yi >> ki;
2957 uint c = ci;
2958 uint m = mi;
2959 uint y = yi;
2960 uint k = ki;
2961 c = qRound((c * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2962 m = qRound((m * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2963 y = qRound((y * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2964 k = qRound((k * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2965 ret = ScColor(c, m, y, k);
2966 }
2967 else if (colorPrecision == 24)
2968 {
2969 quint8 p1;
2970 quint16 p2;
2971 quint32 ci = 0;
2972 ts >> p2;
2973 ts >> p1;
2974 ci = p2 << 8;
2975 ci |= p1;
2976 quint32 mi = 0;
2977 ts >> p2;
2978 ts >> p1;
2979 mi = p2 << 8;
2980 mi |= p1;
2981 quint32 yi = 0;
2982 ts >> p2;
2983 ts >> p1;
2984 yi = p2 << 8;
2985 yi |= p1;
2986 quint32 ki = 0;
2987 ts >> p2;
2988 ts >> p1;
2989 ki = p2 << 8;
2990 ki |= p1;
2991 uint c = ci;
2992 uint m = mi;
2993 uint y = yi;
2994 uint k = ki;
2995 c = qRound((c * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2996 m = qRound((m * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2997 y = qRound((y * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2998 k = qRound((k * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
2999 ret = ScColor(c, m, y, k);
3000 }
3001 else if (colorPrecision == 32)
3002 {
3003 quint32 ci, mi, yi, ki;
3004 ts >> ci >> mi >> yi >> ki;
3005 uint c = ci;
3006 uint m = mi;
3007 uint y = yi;
3008 uint k = ki;
3009 c = qRound((c * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
3010 m = qRound((m * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
3011 y = qRound((y * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
3012 k = qRound((k * (maxColor - minColor) / static_cast<double>(maxColor)) / static_cast<double>(maxColor) * 255.0);
3013 ret = ScColor(c, m, y, k);
3014 }
3015 }
3016 return ret;
3017 }
3018
getBinaryIndexedColor(ScBitReader * breader)3019 QString CgmPlug::getBinaryIndexedColor(ScBitReader *breader)
3020 {
3021 QString ret = "Black";
3022 uint c = breader->getUInt(colorIndexPrecision);
3023 if (ColorTableMap.contains(c) && (c <= maxColorIndex))
3024 ret = ColorTableMap[c];
3025 return ret;
3026 }
3027
getBinaryIndexedColor(QDataStream & ts)3028 QString CgmPlug::getBinaryIndexedColor(QDataStream &ts)
3029 {
3030 QString ret = "Black";
3031 uint c = getBinaryUInt(ts, colorIndexPrecision);
3032 if (ColorTableMap.contains(c) && (c <= maxColorIndex))
3033 ret = ColorTableMap[c];
3034 return ret;
3035 }
3036
getBinaryColor(QDataStream & ts)3037 QString CgmPlug::getBinaryColor(QDataStream &ts)
3038 {
3039 QString ret;
3040 ScColor color;
3041 if (colorMode == 0)
3042 {
3043 ret = getBinaryIndexedColor(ts);
3044 }
3045 else
3046 {
3047 color = getBinaryDirectColor(ts);
3048 ret = handleColor(color, "FromCGM"+color.name());
3049 }
3050 return ret;
3051 }
3052
getBinaryDistance(QDataStream & ts)3053 double CgmPlug::getBinaryDistance(QDataStream &ts)
3054 {
3055 double ret = 0.0;
3056 if (vdcType == 0) // integer coords
3057 {
3058 int x = getBinaryInt(ts, vdcInt);
3059 ret = x;
3060 }
3061 else
3062 ret = getBinaryReal(ts, vdcReal, vdcMantissa);
3063 return ret;
3064 }
3065
getBinaryCoords(QDataStream & ts,bool raw)3066 QPointF CgmPlug::getBinaryCoords(QDataStream &ts, bool raw)
3067 {
3068 QPointF ret = QPointF(0.0, 0.0);
3069 if (vdcType == 0) // integer coords
3070 {
3071 int x = getBinaryInt(ts, vdcInt);
3072 int y = getBinaryInt(ts, vdcInt);
3073 if (!raw)
3074 {
3075 if (vcdFlippedV)
3076 y = vdcHeight - y;
3077 if (vcdFlippedH)
3078 x = vdcWidth - x;
3079 }
3080 ret = QPointF(x, y);
3081 }
3082 else
3083 {
3084 double x = getBinaryReal(ts, vdcReal, vdcMantissa);
3085 double y = getBinaryReal(ts, vdcReal, vdcMantissa);
3086 if (!raw)
3087 {
3088 if (vcdFlippedV)
3089 y = vdcHeight - y;
3090 if (vcdFlippedH)
3091 x = vdcWidth - x;
3092 }
3093 ret = QPointF(x, y);
3094 }
3095 return ret;
3096 }
3097
getBinaryUInt(QDataStream & ts,int intP)3098 uint CgmPlug::getBinaryUInt(QDataStream &ts, int intP)
3099 {
3100 uint val = 0;
3101 if (intP == 1)
3102 {
3103 quint8 data;
3104 ts >> data;
3105 val = data >> 7;
3106 }
3107 else if (intP == 8)
3108 {
3109 quint8 data;
3110 ts >> data;
3111 val = data;
3112 }
3113 else if (intP == 16)
3114 {
3115 quint16 data;
3116 ts >> data;
3117 val = data;
3118 }
3119 else if (intP == 24)
3120 {
3121 quint8 p1;
3122 quint16 p2;
3123 quint32 data = 0;
3124 ts >> p2;
3125 ts >> p1;
3126 data = p2 << 8;
3127 data |= p1;
3128 val = data;
3129 }
3130 else if (intP == 32)
3131 {
3132 quint32 data;
3133 ts >> data;
3134 val = data;
3135 }
3136 return val;
3137 }
3138
getBinaryInt(QDataStream & ts,int intP)3139 int CgmPlug::getBinaryInt(QDataStream &ts, int intP)
3140 {
3141 int val = 0;
3142 if (intP == 8)
3143 {
3144 qint8 data;
3145 ts >> data;
3146 val = data;
3147 }
3148 else if (intP == 16)
3149 {
3150 qint16 data;
3151 ts >> data;
3152 val = data;
3153 }
3154 else if (intP == 24)
3155 {
3156 qint8 p1;
3157 qint16 p2;
3158 qint32 data = 0;
3159 ts >> p2;
3160 ts >> p1;
3161 data = p2 << 8;
3162 data |= p1;
3163 val = data;
3164 }
3165 else if (intP == 32)
3166 {
3167 qint32 data;
3168 ts >> data;
3169 val = data;
3170 }
3171 return val;
3172 }
3173
getBinaryReal(QDataStream & ts,int realP,int realM)3174 double CgmPlug::getBinaryReal(QDataStream &ts, int realP, int realM)
3175 {
3176 double val = 0.0;
3177 if (realP == 0) // real Format
3178 {
3179 if (realM == 9) // 32bit
3180 {
3181 ts.setFloatingPointPrecision(QDataStream::SinglePrecision);
3182 float data;
3183 ts >> data;
3184 val = data;
3185 }
3186 else
3187 {
3188 ts.setFloatingPointPrecision(QDataStream::DoublePrecision);
3189 double data;
3190 ts >> data;
3191 val = data;
3192 }
3193 }
3194 else // fixed Point Format
3195 {
3196 if (realM == 16) // 32bit
3197 {
3198 quint16 fraction;
3199 qint16 whole;
3200 ts >> whole;
3201 ts >> fraction;
3202 int gpart = whole;
3203 val = gpart + (fraction / static_cast<double>(0xFFFF));
3204 /* quint16 flag = whole & 0x8000;
3205 whole = whole & 0x7FFF;
3206 if (flag)
3207 val = whole - (fraction / static_cast<double>(0xFFFF));
3208 else
3209 val = whole + (fraction / static_cast<double>(0xFFFF)); */
3210 }
3211 else
3212 {
3213 quint32 fraction;
3214 qint32 whole;
3215 ts >> whole;
3216 ts >> fraction;
3217 int gpart = whole;
3218 val = gpart + (fraction / static_cast<double>(0xFFFFFFFF));
3219 /* quint32 flag = whole & 0x80000000;
3220 whole = whole & 0x7FFFFFFF;
3221 if (flag)
3222 val = whole - (fraction / static_cast<double>(0xFFFFFFFF));
3223 else
3224 val = whole + (fraction / static_cast<double>(0xFFFFFFFF)); */
3225 }
3226 }
3227 return val;
3228 }
3229
getBinaryText(QDataStream & ts)3230 QString CgmPlug::getBinaryText(QDataStream &ts)
3231 {
3232 quint8 textLen;
3233 QByteArray text;
3234 ts >> textLen;
3235 if (textLen == 0)
3236 ts >> textLen;
3237 if (textLen < 255)
3238 {
3239 text.resize(textLen);
3240 ts.readRawData(text.data(), textLen);
3241 }
3242 else
3243 {
3244 quint16 extTextLen;
3245 quint16 flag;
3246 QByteArray textE;
3247 ts >> extTextLen;
3248 flag = extTextLen & 0x8000;
3249 extTextLen = extTextLen & 0x7FFF;
3250 textE.resize(extTextLen);
3251 ts.readRawData(textE.data(), extTextLen);
3252 alignStreamToWord(ts, 0);
3253 text += textE;
3254 while (flag)
3255 {
3256 ts >> extTextLen;
3257 flag = extTextLen & 0x8000;
3258 extTextLen = extTextLen & 0x7FFF;
3259 textE.resize(extTextLen);
3260 ts.readRawData(textE.data(), extTextLen);
3261 text += textE;
3262 }
3263 }
3264 return text;
3265 }
3266
alignStreamToWord(QDataStream & ts,uint len)3267 void CgmPlug::alignStreamToWord(QDataStream &ts, uint len)
3268 {
3269 quint16 flag;
3270 flag = len & 0x8000;
3271 quint16 paramLen = len & 0x7FFF;
3272 ts.skipRawData(paramLen);
3273 while (flag)
3274 {
3275 ts >> paramLen;
3276 flag = paramLen & 0x8000;
3277 paramLen = paramLen & 0x7FFF;
3278 ts.skipRawData(paramLen);
3279 }
3280 uint adj = ts.device()->pos() % 2;
3281 if (adj != 0)
3282 ts.skipRawData(1);
3283 }
3284 /* End binary Decoder */
3285
3286 /* Start of core Functions common to both Decoders */
3287
handleStartMetaFile(const QString & value)3288 void CgmPlug::handleStartMetaFile(const QString& value)
3289 {
3290 if (importerFlags & LoadSavePlugin::lfCreateDoc)
3291 m_Doc->documentInfo().setTitle(value);
3292 // qDebug() << "Start Metafile" << value;
3293 }
3294
handleStartPicture(const QString & value)3295 void CgmPlug::handleStartPicture(const QString& value)
3296 {
3297 pictName = value;
3298 // qDebug() << "Start Picture" << value;
3299 }
3300
handleStartPictureBody(double width,double height)3301 void CgmPlug::handleStartPictureBody(double width, double height)
3302 {
3303 if (importerFlags & LoadSavePlugin::lfCreateDoc)
3304 {
3305 if (firstPage)
3306 {
3307 m_Doc->setPage(width, height, 0, 0, 0, 0, 0, 0, false, false);
3308 if (width > height)
3309 m_Doc->setPageOrientation(1);
3310 else
3311 m_Doc->setPageOrientation(0);
3312 m_Doc->setPageSize("Custom");
3313 m_Doc->changePageProperties(0, 0, 0, 0, height, width, height, width, m_Doc->pageOrientation(), m_Doc->pageSize(), m_Doc->currentPage()->pageNr(), false);
3314 }
3315 else
3316 {
3317 if (wasEndPic)
3318 {
3319 m_Doc->setPage(width, height, 0, 0, 0, 0, 0, 0, false, false);
3320 m_Doc->addPage(m_Doc->currentPage()->pageNr()+1);
3321 m_Doc->view()->addPage(m_Doc->currentPage()->pageNr(), true);
3322 }
3323 }
3324 wasEndPic = false;
3325 firstPage = false;
3326 }
3327 }
3328
handleMetaFileDescription(const QString & value)3329 void CgmPlug::handleMetaFileDescription(const QString& value)
3330 {
3331 if (importerFlags & LoadSavePlugin::lfCreateDoc)
3332 m_Doc->documentInfo().setComments(value);
3333 // qDebug() << "Metafile Description" << value;
3334 }
3335
handleColor(ScColor & color,const QString & proposedName)3336 QString CgmPlug::handleColor(ScColor &color, const QString& proposedName)
3337 {
3338 QString tmpName = m_Doc->PageColors.tryAddColor(proposedName, color);
3339 if (tmpName == proposedName)
3340 importedColors.append(tmpName);
3341 return tmpName;
3342 }
3343
convertCoords(double input)3344 double CgmPlug::convertCoords(double input)
3345 {
3346 return input * metaScale;
3347 }
3348
convertCoords(QPointF input)3349 QPointF CgmPlug::convertCoords(QPointF input)
3350 {
3351 return input * metaScale;
3352 }
3353
appendPath(QPainterPath & path1,QPainterPath & path2)3354 void CgmPlug::appendPath(QPainterPath &path1, QPainterPath &path2)
3355 {
3356 for (int i = 0; i < path2.elementCount(); ++i)
3357 {
3358 const QPainterPath::Element &elm = path2.elementAt(i);
3359 switch (elm.type)
3360 {
3361 case QPainterPath::MoveToElement:
3362 path1.moveTo(elm.x, elm.y);
3363 break;
3364 case QPainterPath::LineToElement:
3365 path1.lineTo(elm.x, elm.y);
3366 break;
3367 case QPainterPath::CurveToElement:
3368 path1.cubicTo(elm.x, elm.y, path2.elementAt(i+1).x, path2.elementAt(i+1).y, path2.elementAt(i+2).x, path2.elementAt(i+2).y );
3369 break;
3370 default:
3371 break;
3372 }
3373 }
3374 }
3375
itemAdd(PageItem::ItemType itemType,PageItem::ItemFrameType frameType,double x,double y,double b,double h,double w,const QString & fill,const QString & stroke)3376 PageItem* CgmPlug::itemAdd(PageItem::ItemType itemType, PageItem::ItemFrameType frameType, double x, double y, double b, double h, double w, const QString& fill, const QString& stroke)
3377 {
3378 int z;
3379 if (lineVisible)
3380 {
3381 if (fillType == 0)
3382 z = m_Doc->itemAdd(itemType, frameType, x, y, b, h, w, CommonStrings::None, stroke);
3383 else if ((fillType == 1) || (fillType == 3))
3384 z = m_Doc->itemAdd(itemType, frameType, x, y, b, h, w, fill, stroke);
3385 else if (fillType == 2)
3386 {
3387 z = m_Doc->itemAdd(itemType, frameType, x, y, b, h, w, fill, stroke);
3388 if (patternTable.contains(patternIndex))
3389 {
3390 PageItem *ite = m_Doc->Items->at(z);
3391 ite->setPattern(patternTable[patternIndex]);
3392 ScPattern pat = m_Doc->docPatterns[patternTable[patternIndex]];
3393 double patSX = 100;
3394 double patSY = 100;
3395 if (patternScaleX > -1)
3396 patSX = patternScaleX / pat.width * 100;
3397 if (patternScaleY > -1)
3398 patSY = patternScaleY / pat.height * 100;
3399 ite->setPatternTransform(patSX, patSY, 0, 0, 0, 0.0, 0.0);
3400 ite->GrType = Gradient_Pattern;
3401 }
3402 }
3403 else if (fillType == 4)
3404 z = m_Doc->itemAdd(itemType, frameType, x, y, b, h, w, CommonStrings::None, stroke);
3405 else
3406 z = m_Doc->itemAdd(itemType, frameType, x, y, b, h, w, fill, stroke);
3407 }
3408 else
3409 {
3410 if (fillType == 0)
3411 z = m_Doc->itemAdd(itemType, frameType, x, y, b, h, w, CommonStrings::None, fill);
3412 else if ((fillType == 1) || (fillType == 3))
3413 z = m_Doc->itemAdd(itemType, frameType, x, y, b, h, w, fill, CommonStrings::None);
3414 else if (fillType == 2)
3415 {
3416 z = m_Doc->itemAdd(itemType, frameType, x, y, b, h, w, fill, CommonStrings::None);
3417 if (patternTable.contains(patternIndex))
3418 {
3419 PageItem *ite = m_Doc->Items->at(z);
3420 ite->setPattern(patternTable[patternIndex]);
3421 ScPattern pat = m_Doc->docPatterns[patternTable[patternIndex]];
3422 double patSX = 100;
3423 double patSY = 100;
3424 if (patternScaleX > -1)
3425 patSX = patternScaleX / pat.width * 100;
3426 if (patternScaleY > -1)
3427 patSY = patternScaleY / pat.height * 100;
3428 ite->setPatternTransform(patSX, patSY, 0, 0, 0, 0.0, 0.0);
3429 ite->GrType = Gradient_Pattern;
3430 }
3431 }
3432 else
3433 z = m_Doc->itemAdd(itemType, frameType, x, y, b, h, w, CommonStrings::None, CommonStrings::None);
3434 }
3435 return m_Doc->Items->at(z);
3436 }
3437
finishItem(PageItem * ite,bool line)3438 void CgmPlug::finishItem(PageItem* ite, bool line)
3439 {
3440 ite->ClipEdited = true;
3441 ite->FrameType = 3;
3442 FPoint wh = getMaxClipF(&ite->PoLine);
3443 ite->setWidthHeight(wh.x(),wh.y());
3444 ite->setTextFlowMode(PageItem::TextFlowDisabled);
3445 m_Doc->adjustItemSize(ite);
3446 ite->OldB2 = ite->width();
3447 ite->OldH2 = ite->height();
3448 if (line)
3449 {
3450 ite->setLineStyle(lineType);
3451 ite->setLineEnd(lineCap);
3452 ite->setLineJoin(lineJoin);
3453 }
3454 else
3455 {
3456 ite->setLineStyle(edgeType);
3457 ite->setLineEnd(edgeCap);
3458 ite->setLineJoin(edgeJoin);
3459 }
3460 ite->updateClip();
3461 Elements.append(ite);
3462 if (groupStack.count() != 0)
3463 groupStack.top().append(ite);
3464 Coords.resize(0);
3465 Coords.svgInit();
3466 }
3467