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 							 -------------------
9 	begin                : Sat Mar 7 2015
10 	copyright            : (C) 2015 by Franz Schmid
11 	email                : Franz.Schmid@altmuehlnet.de
12  ***************************************************************************/
13 
14 #include <QByteArray>
15 #include <QCursor>
16 #include <QDrag>
17 #include <QFile>
18 #include <QList>
19 #include <QMimeData>
20 #include <QRawFont>
21 #include <QRegExp>
22 #include <QTextCodec>
23 #include <QUuid>
24 #include <QDebug>
25 
26 #include <cstdlib>
27 
28 #include "ui/customfdialog.h"
29 #include "importsvm.h"
30 #include "loadsaveplugin.h"
31 #include "fileloader.h"
32 #include "ui/missing.h"
33 #include "ui/multiprogressdialog.h"
34 #include "pageitem_imageframe.h"
35 #include "pagesize.h"
36 #include "prefscontext.h"
37 #include "prefsfile.h"
38 #include "prefsmanager.h"
39 #include "prefstable.h"
40 #include "ui/propertiespalette.h"
41 #include "rawimage.h"
42 #include "scclocale.h"
43 #include "sccolorengine.h"
44 #include "scconfig.h"
45 #include "scmimedata.h"
46 #include "scpaths.h"
47 #include "scpattern.h"
48 #include "scribus.h"
49 #include "scribusdoc.h"
50 #include "scribusview.h"
51 #include "scribusXml.h"
52 #include "scribuscore.h"
53 #include "sctextstream.h"
54 #include "selection.h"
55 #include "undomanager.h"
56 #include "util.h"
57 #include "util_file.h"
58 #include "util_formats.h"
59 #include "util_math.h"
60 
61 #define U_PMR_HEADER                  0x4001
62 #define U_PMR_ENDOFFILE               0x4002
63 #define U_PMR_COMMENT                 0x4003
64 #define U_PMR_GETDC                   0x4004
65 #define U_PMR_MULTIFORMATSTART        0x4005
66 #define U_PMR_MULTIFORMATSECTION      0x4006
67 #define U_PMR_MULTIFORMATEND          0x4007
68 #define U_PMR_OBJECT                  0x4008
69 #define U_PMR_CLEAR                   0x4009
70 #define U_PMR_FILLRECTS               0x400A
71 #define U_PMR_DRAWRECTS               0x400B
72 #define U_PMR_FILLPOLYGON             0x400C
73 #define U_PMR_DRAWLINES               0x400D
74 #define U_PMR_FILLELLIPSE             0x400E
75 #define U_PMR_DRAWELLIPSE             0x400F
76 #define U_PMR_FILLPIE                 0x4010
77 #define U_PMR_DRAWPIE                 0x4011
78 #define U_PMR_DRAWARC                 0x4012
79 #define U_PMR_FILLREGION              0x4013
80 #define U_PMR_FILLPATH                0x4014
81 #define U_PMR_DRAWPATH                0x4015
82 #define U_PMR_FILLCLOSEDCURVE         0x4016
83 #define U_PMR_DRAWCLOSEDCURVE         0x4017
84 #define U_PMR_DRAWCURVE               0x4018
85 #define U_PMR_DRAWBEZIERS             0x4019
86 #define U_PMR_DRAWIMAGE               0x401A
87 #define U_PMR_DRAWIMAGEPOINTS         0x401B
88 #define U_PMR_DRAWSTRING              0x401C
89 #define U_PMR_SETRENDERINGORIGIN      0x401D
90 #define U_PMR_SETANTIALIASMODE        0x401E
91 #define U_PMR_SETTEXTRENDERINGHINT    0x401F
92 #define U_PMR_SETTEXTCONTRAST         0x4020
93 #define U_PMR_SETINTERPOLATIONMODE    0x4021
94 #define U_PMR_SETPIXELOFFSETMODE      0x4022
95 #define U_PMR_SETCOMPOSITINGMODE      0x4023
96 #define U_PMR_SETCOMPOSITINGQUALITY   0x4024
97 #define U_PMR_SAVE                    0x4025
98 #define U_PMR_RESTORE                 0x4026
99 #define U_PMR_BEGINCONTAINER          0x4027
100 #define U_PMR_BEGINCONTAINERNOPARAMS  0x4028
101 #define U_PMR_ENDCONTAINER            0x4029
102 #define U_PMR_SETWORLDTRANSFORM       0x402A
103 #define U_PMR_RESETWORLDTRANSFORM     0x402B
104 #define U_PMR_MULTIPLYWORLDTRANSFORM  0x402C
105 #define U_PMR_TRANSLATEWORLDTRANSFORM 0x402D
106 #define U_PMR_SCALEWORLDTRANSFORM     0x402E
107 #define U_PMR_ROTATEWORLDTRANSFORM    0x402F
108 #define U_PMR_SETPAGETRANSFORM        0x4030
109 #define U_PMR_RESETCLIP               0x4031
110 #define U_PMR_SETCLIPRECT             0x4032
111 #define U_PMR_SETCLIPPATH             0x4033
112 #define U_PMR_SETCLIPREGION           0x4034
113 #define U_PMR_OFFSETCLIP              0x4035
114 #define U_PMR_DRAWDRIVERSTRING        0x4036
115 #define U_PMR_STROKEFILLPATH          0x4037
116 #define U_PMR_SERIALIZABLEOBJECT      0x4038
117 #define U_PMR_SETTSGRAPHICS           0x4039
118 #define U_PMR_SETTSCLIP               0x403A
119 
120 #define   U_BT_SolidColor               0x00
121 #define   U_BT_HatchFill                0x01
122 #define   U_BT_TextureFill              0x02
123 #define   U_BT_PathGradient             0x03
124 #define   U_BT_LinearGradient           0x04
125 
126 #define   U_OT_Invalid                  0x00
127 #define   U_OT_Brush                    0x01
128 #define   U_OT_Pen                      0x02
129 #define   U_OT_Path                     0x03
130 #define   U_OT_Region                   0x04
131 #define   U_OT_Image                    0x05
132 #define   U_OT_Font                     0x06
133 #define   U_OT_StringFormat             0x07
134 #define   U_OT_ImageAttributes          0x08
135 #define   U_OT_CustomLineCap            0x09
136 
137 #define   U_UT_World                    0x00
138 #define   U_UT_Display                  0x01
139 #define   U_UT_Pixel                    0x02
140 #define   U_UT_Point                    0x03
141 #define   U_UT_Inch                     0x04
142 #define   U_UT_Document                 0x05
143 #define   U_UT_Millimeter               0x06
144 
145 #define   U_PD_Transform                0x0001
146 #define   U_PD_StartCap                 0x0002
147 #define   U_PD_EndCap                   0x0004
148 #define   U_PD_Join                     0x0008
149 #define   U_PD_MiterLimit               0x0010
150 #define   U_PD_LineStyle                0x0020
151 #define   U_PD_DLCap                    0x0040
152 #define   U_PD_DLOffset                 0x0080
153 #define   U_PD_DLData                   0x0100
154 #define   U_PD_NonCenter                0x0200
155 #define   U_PD_CLData                   0x0400
156 #define   U_PD_CustomStartCap           0x0800
157 #define   U_PD_CustomEndCap             0x1000
158 
159 #define   U_PPT_Start                   0x00
160 #define   U_PPT_Line                    0x01
161 #define   U_PPT_Bezier                  0x03
162 
163 #define   U_SA_Near                     0x00
164 #define   U_SA_Center                   0x01
165 #define   U_SA_Far                      0x02
166 
167 #define   U_HSP_Horizontal              0x00000000
168 #define   U_HSP_Vertical                0x00000001
169 #define   U_HSP_ForwardDiagonal         0x00000002
170 #define   U_HSP_BackwardDiagonal        0x00000003
171 #define   U_HSP_LargeGrid               0x00000004
172 #define   U_HSP_DiagonalCross           0x00000005
173 #define   U_HSP_05Percent               0x00000006
174 #define   U_HSP_10Percent               0x00000007
175 #define   U_HSP_20Percent               0x00000008
176 #define   U_HSP_25Percent               0x00000009
177 #define   U_HSP_30Percent               0x0000000A
178 #define   U_HSP_40Percent               0x0000000B
179 #define   U_HSP_50Percent               0x0000000C
180 #define   U_HSP_60Percent               0x0000000D
181 #define   U_HSP_70Percent               0x0000000E
182 #define   U_HSP_75Percent               0x0000000F
183 #define   U_HSP_80Percent               0x00000010
184 #define   U_HSP_90Percent               0x00000011
185 #define   U_HSP_LightDownwardDiagonal   0x00000012
186 #define   U_HSP_LightUpwardDiagonal     0x00000013
187 #define   U_HSP_DarkDownwardDiagonal    0x00000014
188 #define   U_HSP_DarkUpwardDiagonal      0x00000015
189 #define   U_HSP_WideDownwardDiagonal    0x00000016
190 #define   U_HSP_WideUpwardDiagonal      0x00000017
191 #define   U_HSP_LightVertical           0x00000018
192 #define   U_HSP_LightHorizontal         0x00000019
193 #define   U_HSP_NarrowVertical          0x0000001A
194 #define   U_HSP_NarrowHorizontal        0x0000001B
195 #define   U_HSP_DarkVertical            0x0000001C
196 #define   U_HSP_DarkHorizontal          0x0000001D
197 #define   U_HSP_DashedDownwardDiagonal  0x0000001E
198 #define   U_HSP_DashedUpwardDiagonal    0x0000001F
199 #define   U_HSP_DashedHorizontal        0x00000020
200 #define   U_HSP_DashedVertical          0x00000021
201 #define   U_HSP_SmallConfetti           0x00000022
202 #define   U_HSP_LargeConfetti           0x00000023
203 #define   U_HSP_ZigZag                  0x00000024
204 #define   U_HSP_Wave                    0x00000025
205 #define   U_HSP_DiagonalBrick           0x00000026
206 #define   U_HSP_HorizontalBrick         0x00000027
207 #define   U_HSP_Weave                   0x00000028
208 #define   U_HSP_Plaid                   0x00000029
209 #define   U_HSP_Divot                   0x0000002A
210 #define   U_HSP_DottedGrid              0x0000002B
211 #define   U_HSP_DottedDiamond           0x0000002C
212 #define   U_HSP_Shingle                 0x0000002D
213 #define   U_HSP_Trellis                 0x0000002E
214 #define   U_HSP_Sphere                  0x0000002F
215 #define   U_HSP_SmallGrid               0x00000030
216 #define   U_HSP_SmallCheckerBoard       0x00000031
217 #define   U_HSP_LargeCheckerBoard       0x00000032
218 #define   U_HSP_OutlinedDiamond         0x00000033
219 #define   U_HSP_SolidDiamond            0x00000034
220 
221 #define   U_LS_Solid                    0x00
222 #define   U_LS_Dash                     0x01
223 #define   U_LS_Dot                      0x02
224 #define   U_LS_DashDot                  0x03
225 #define   U_LS_DashDotDot               0x04
226 #define   U_LS_Custom                   0x05
227 
228 #define   U_LJT_Miter                   0x00
229 #define   U_LJT_Bevel                   0x01
230 #define   U_LJT_Round                   0x02
231 #define   U_LJT_MiterClipped            0x03
232 
233 #define   U_LCT_Flat                    0x00
234 #define   U_LCT_Square                  0x01
235 #define   U_LCT_Round                   0x02
236 
237 #define   U_MDT_Wmf                     0x01
238 #define   U_MDT_WmfPlaceable            0x02
239 #define   U_MDT_Emf                     0x03
240 #define   U_MDT_EmfPlusOnly             0x04
241 #define   U_MDT_EmfPlusDual             0x05
242 
243 #define   U_IDT_Bitmap                  0x01
244 #define   U_IDT_Metafile                0x02
245 
246 #define   U_PF_1bppIndexed              0x00030101
247 #define   U_PF_4bppIndexed              0x00030402
248 #define   U_PF_8bppIndexed              0x00030803
249 #define   U_PF_16bppGrayScale           0x00101004
250 #define   U_PF_16bppRGB555              0x00021005
251 #define   U_PF_16bppRGB565              0x00021006
252 #define   U_PF_16bppARGB1555            0x00061007
253 #define   U_PF_24bppRGB                 0x00021808
254 #define   U_PF_32bppRGB                 0x00022009
255 #define   U_PF_32bppARGB                0x0026200A
256 #define   U_PF_32bppPARGB               0x000E200B
257 #define   U_PF_48bppRGB                 0x0010300C
258 #define   U_PF_64bppARGB                0x0034400D
259 #define   U_PF_64bppPARGB               0x001A400E
260 
261 #define   U_IE_BlurEffectGuid                     "{633C80A4-1843-482B-9EF2-BE2834C5FDD4}"
262 #define   U_IE_BrightnessContrastEffectGuid       "{D3A1DBE1-8EC4-4C17-9F4C-EA97AD1C343D}"
263 #define   U_IE_ColorBalanceEffectGuid             "{537E597D-251E-48DA-9664-29CA496B70F8}"
264 #define   U_IE_ColorCurveEffectGuid               "{DD6A0022-58E4-4A67-9D9B-D48EB881A53D}"
265 #define   U_IE_ColorLookupTableEffectGuid         "{A7CE72A9-0F7F-40D7-B3CC-D0C02D5C3212}"
266 #define   U_IE_ColorMatrixEffectGuid              "{718F2615-7933-40E3-A511-5F68FE14DD74}"
267 #define   U_IE_HueSaturationLightnessEffectGuid   "{8B2DD6C3-EB07-4D87-A5F0-7108E26A9C5F}"
268 #define   U_IE_LevelsEffectGuid                   "{99C354EC-2A31-4F3A-8C34-17A803B33A25}"
269 #define   U_IE_RedEyeCorrectionEffectGuid         "{74D29D05-69A4-4266-9549-3CC52836B632}"
270 #define   U_IE_SharpenEffectGuid                  "{63CBF3EE-C526-402C-8F71-62C540BF5142}"
271 #define   U_IE_TintEffectGuid                     "{1077AF00-2848-4441-9489-44AD4C2D7A2C}"
272 
273 #define   U_RNDT_Kids                   0x00000000
274 #define   U_RNDT_And                    0x00000001
275 #define   U_RNDT_Or                     0x00000002
276 #define   U_RNDT_Xor                    0x00000003
277 #define   U_RNDT_Exclude                0x00000004
278 #define   U_RNDT_Complement             0x00000005
279 #define   U_RNDT_Rect                   0x10000000
280 #define   U_RNDT_Path                   0x10000001
281 #define   U_RNDT_Empty                  0x10000002
282 #define   U_RNDT_Infinite               0x10000003
283 
SvmPlug(ScribusDoc * doc,int flags)284 SvmPlug::SvmPlug(ScribusDoc* doc, int flags)
285 {
286 	tmpSel=new Selection(this, false);
287 	m_Doc=doc;
288 	importerFlags = flags;
289 	interactive = (flags & LoadSavePlugin::lfInteractive);
290 	progressDialog = nullptr;
291 }
292 
readThumbnail(const QString & fName)293 QImage SvmPlug::readThumbnail(const QString& fName)
294 {
295 	QFileInfo fi = QFileInfo(fName);
296 	baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
297 	double b = 0;
298 	double h = 0;
299 	double x = 0;
300 	double y = 0;
301 	parseHeader(fName, x, y, b, h);
302 	if (b == 0.0)
303 		b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
304 	if (h == 0.0)
305 		h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
306 	docWidth = b;
307 	docHeight = h;
308 	docX = x;
309 	docY = y;
310 	baseX = 0;
311 	baseY = 0;
312 	progressDialog = nullptr;
313 	m_Doc = new ScribusDoc();
314 	m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
315 	m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
316 	m_Doc->addPage(0);
317 	m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
318 	baseX = m_Doc->currentPage()->xOffset();
319 	baseY = m_Doc->currentPage()->yOffset();
320 	Elements.clear();
321 	m_Doc->setLoading(true);
322 	m_Doc->DoDrawing = false;
323 	m_Doc->scMW()->setScriptRunning(true);
324 	QString CurDirP = QDir::currentPath();
325 	QDir::setCurrent(fi.path());
326 	if (convert(fName))
327 	{
328 		tmpSel->clear();
329 		QDir::setCurrent(CurDirP);
330 		if (Elements.count() > 0)
331 		{
332 			m_Doc->m_Selection->delaySignalsOn();
333 			m_Doc->m_Selection->clear();
334 			for (int dre=0; dre<Elements.count(); ++dre)
335 			{
336 				m_Doc->m_Selection->addItem(Elements.at(dre), true);
337 			}
338 			m_Doc->m_Selection->setGroupRect();
339 			double gx, gy, gh, gw;
340 			m_Doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
341 			m_Doc->moveGroup(baseX - gx, baseY - gy);
342 			m_Doc->m_Selection->clear();
343 			m_Doc->m_Selection->delaySignalsOff();
344 			m_Doc->currentPage()->setInitialHeight(gh);
345 			m_Doc->currentPage()->setInitialWidth(gw);
346 			m_Doc->currentPage()->setHeight(gh);
347 			m_Doc->currentPage()->setWidth(gw);
348 			m_Doc->setPageHeight(gh);
349 			m_Doc->setPageWidth(gw);
350 			m_Doc->setPageSize("Custom");
351 			m_Doc->currentPage()->setSize("Custom");
352 			m_Doc->reformPages(true);
353 		}
354 		if (Elements.count() > 1)
355 		{
356 			PageItem* grItem = m_Doc->groupObjectsList(Elements);
357 			grItem->setXYPos(baseX, baseY, true);
358 		}
359 		else if (Elements.count() == 1)
360 			Elements.at(0)->setXYPos(baseX, baseY, true);
361 		m_Doc->DoDrawing = true;
362 		m_Doc->m_Selection->delaySignalsOn();
363 		QImage tmpImage;
364 		if (Elements.count() > 0)
365 		{
366 			for (int dre=0; dre<Elements.count(); ++dre)
367 			{
368 				tmpSel->addItem(Elements.at(dre), true);
369 			}
370 			tmpSel->setGroupRect();
371 			double xs = tmpSel->width();
372 			double ys = tmpSel->height();
373 			tmpImage = Elements.at(0)->DrawObj_toImage(500);
374 			tmpImage.setText("XSize", QString("%1").arg(xs));
375 			tmpImage.setText("YSize", QString("%1").arg(ys));
376 		}
377 		m_Doc->scMW()->setScriptRunning(false);
378 		m_Doc->setLoading(false);
379 		m_Doc->m_Selection->delaySignalsOff();
380 		delete m_Doc;
381 		return tmpImage;
382 	}
383 	QDir::setCurrent(CurDirP);
384 	m_Doc->DoDrawing = true;
385 	m_Doc->scMW()->setScriptRunning(false);
386 	delete m_Doc;
387 	return QImage();
388 }
389 
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)390 bool SvmPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
391 {
392 	bool success = false;
393 	interactive = (flags & LoadSavePlugin::lfInteractive);
394 	importerFlags = flags;
395 	cancel = false;
396 	double x, y, b, h;
397 	bool ret = false;
398 	QFileInfo fi = QFileInfo(fNameIn);
399 	if ( !ScCore->usingGUI() )
400 	{
401 		interactive = false;
402 		showProgress = false;
403 	}
404 	baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
405 	if ( showProgress )
406 	{
407 		ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
408 		progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
409 		QStringList barNames, barTexts;
410 		barNames << "GI";
411 		barTexts << tr("Analyzing File:");
412 		QList<bool> barsNumeric;
413 		barsNumeric << false;
414 		progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
415 		progressDialog->setOverallTotalSteps(3);
416 		progressDialog->setOverallProgress(0);
417 		progressDialog->setProgress("GI", 0);
418 		progressDialog->show();
419 		connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
420 		qApp->processEvents();
421 	}
422 	else
423 		progressDialog = nullptr;
424 /* Set default Page to size defined in Preferences */
425 	x = 0.0;
426 	y = 0.0;
427 	b = 0.0;
428 	h = 0.0;
429 	if (progressDialog)
430 	{
431 		progressDialog->setOverallProgress(1);
432 		qApp->processEvents();
433 	}
434 	parseHeader(fNameIn, x, y, b, h);
435 	if (b == 0.0)
436 		b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
437 	if (h == 0.0)
438 		h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
439 	docWidth = b;
440 	docHeight = h;
441 	docX = x;
442 	docY = y;
443 	baseX = 0;
444 	baseY = 0;
445 	if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
446 	{
447 		m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
448 		m_Doc->addPage(0);
449 		m_Doc->view()->addPage(0, true);
450 		m_Doc->currentPage()->setInitialWidth(docWidth);
451 		m_Doc->currentPage()->setInitialHeight(docHeight);
452 		m_Doc->currentPage()->setWidth(docWidth);
453 		m_Doc->currentPage()->setHeight(docHeight);
454 		m_Doc->currentPage()->setMasterPageNameNormal();
455 		m_Doc->currentPage()->setSize("Custom");
456 		m_Doc->reformPages(true);
457 		baseX = m_Doc->currentPage()->xOffset();
458 		baseY = m_Doc->currentPage()->yOffset();
459 	}
460 	else
461 	{
462 		if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
463 		{
464 			m_Doc = ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
465 			ScCore->primaryMainWindow()->HaveNewDoc();
466 			m_Doc->setPageHeight(docHeight);
467 			m_Doc->setPageWidth(docWidth);
468 			m_Doc->currentPage()->setInitialWidth(docWidth);
469 			m_Doc->currentPage()->setInitialHeight(docHeight);
470 			m_Doc->currentPage()->setWidth(docWidth);
471 			m_Doc->currentPage()->setHeight(docHeight);
472 			ret = true;
473 			baseX = m_Doc->currentPage()->xOffset();
474 			baseY = m_Doc->currentPage()->yOffset();
475 		}
476 	}
477 	if ((!ret) && (interactive))
478 	{
479 		baseX = m_Doc->currentPage()->xOffset();
480 		baseY = m_Doc->currentPage()->yOffset();
481 	}
482 	if ((ret) || (!interactive))
483 	{
484 		if (docWidth > docHeight)
485 			m_Doc->setPageOrientation(1);
486 		else
487 			m_Doc->setPageOrientation(0);
488 		m_Doc->setPageSize("Custom");
489 	}
490 	if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
491 		m_Doc->view()->deselectItems();
492 	Elements.clear();
493 	m_Doc->setLoading(true);
494 	m_Doc->DoDrawing = false;
495 	if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
496 		m_Doc->view()->updatesOn(false);
497 	m_Doc->scMW()->setScriptRunning(true);
498 	qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
499 	QString CurDirP = QDir::currentPath();
500 	QDir::setCurrent(fi.path());
501 	if (convert(fNameIn))
502 	{
503 		tmpSel->clear();
504 		QDir::setCurrent(CurDirP);
505 		if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
506 			m_Doc->groupObjectsList(Elements);
507 		m_Doc->DoDrawing = true;
508 		m_Doc->scMW()->setScriptRunning(false);
509 		m_Doc->setLoading(false);
510 		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
511 		if ((Elements.count() > 0) && (!ret) && (interactive))
512 		{
513 			if (flags & LoadSavePlugin::lfScripted)
514 			{
515 				bool loadF = m_Doc->isLoading();
516 				m_Doc->setLoading(false);
517 				m_Doc->changed();
518 				m_Doc->setLoading(loadF);
519 				if (!(flags & LoadSavePlugin::lfLoadAsPattern))
520 				{
521 					m_Doc->m_Selection->delaySignalsOn();
522 					for (int dre=0; dre<Elements.count(); ++dre)
523 					{
524 						m_Doc->m_Selection->addItem(Elements.at(dre), true);
525 					}
526 					m_Doc->m_Selection->delaySignalsOff();
527 					m_Doc->m_Selection->setGroupRect();
528 					if (m_Doc->view() != nullptr)
529 						m_Doc->view()->updatesOn(true);
530 				}
531 			}
532 			else
533 			{
534 				m_Doc->DragP = true;
535 				m_Doc->DraggedElem = nullptr;
536 				m_Doc->DragElements.clear();
537 				m_Doc->m_Selection->delaySignalsOn();
538 				for (int dre=0; dre<Elements.count(); ++dre)
539 				{
540 					tmpSel->addItem(Elements.at(dre), true);
541 				}
542 				tmpSel->setGroupRect();
543 				ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
544 				m_Doc->itemSelection_DeleteItem(tmpSel);
545 				m_Doc->view()->updatesOn(true);
546 				if (importedColors.count() != 0)
547 				{
548 					for (int cd = 0; cd < importedColors.count(); cd++)
549 					{
550 						m_Doc->PageColors.remove(importedColors[cd]);
551 					}
552 				}
553 				if (importedPatterns.count() != 0)
554 				{
555 					for (int cd = 0; cd < importedPatterns.count(); cd++)
556 					{
557 						m_Doc->docPatterns.remove(importedPatterns[cd]);
558 					}
559 				}
560 				m_Doc->m_Selection->delaySignalsOff();
561 				// We must copy the TransationSettings object as it is owned
562 				// by handleObjectImport method afterwards
563 				TransactionSettings* transacSettings = new TransactionSettings(trSettings);
564 				m_Doc->view()->handleObjectImport(md, transacSettings);
565 				m_Doc->DragP = false;
566 				m_Doc->DraggedElem = nullptr;
567 				m_Doc->DragElements.clear();
568 			}
569 		}
570 		else
571 		{
572 			m_Doc->changed();
573 			m_Doc->reformPages();
574 			if (!(flags & LoadSavePlugin::lfLoadAsPattern))
575 				m_Doc->view()->updatesOn(true);
576 		}
577 		success = true;
578 	}
579 	else
580 	{
581 		QDir::setCurrent(CurDirP);
582 		m_Doc->DoDrawing = true;
583 		m_Doc->scMW()->setScriptRunning(false);
584 		if (m_Doc->view() != nullptr)
585 			m_Doc->view()->updatesOn(true);
586 		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
587 	}
588 	if (interactive)
589 		m_Doc->setLoading(false);
590 	//CB If we have a gui we must refresh it if we have used the progressbar
591 	if (!(flags & LoadSavePlugin::lfLoadAsPattern))
592 	{
593 		if ((showProgress) && (!interactive))
594 			m_Doc->view()->DrawNew();
595 	}
596 	qApp->restoreOverrideCursor();
597 	return success;
598 }
599 
~SvmPlug()600 SvmPlug::~SvmPlug()
601 {
602 	delete progressDialog;
603 	delete tmpSel;
604 }
605 
parseHeader(const QString & fName,double & x,double & y,double & b,double & h)606 void SvmPlug::parseHeader(const QString& fName, double &x, double &y, double &b, double &h)
607 {
608 	QFile f(fName);
609 	if (f.open(QIODevice::ReadOnly))
610 	{
611 		QDataStream ds(&f);
612 		ds.setByteOrder(QDataStream::LittleEndian);
613 		ds.setFloatingPointPrecision(QDataStream::SinglePrecision);
614 		QByteArray magic;
615 		magic.resize(6);
616 		ds.readRawData(magic.data(), 6);
617 		if (magic == "VCLMTF")
618 		{
619 			ds >> head.versionCompat.version;
620 			ds >> head.versionCompat.length;
621 			ds >> head.compressionMode;
622 			ds >> head.mapMode.version.version;
623 			ds >> head.mapMode.version.length;
624 			ds >> head.mapMode.unit;
625 			ds >> head.mapMode.origin;
626 			ds >> head.mapMode.scaleX.numerator;
627 			ds >> head.mapMode.scaleX.denominator;
628 			ds >> head.mapMode.scaleY.numerator;
629 			ds >> head.mapMode.scaleY.denominator;
630 			ds >> head.mapMode.isSimple;
631 			ds >> head.width;
632 			ds >> head.height;
633 			ds >> head.actionCount;
634 			m_records = head.actionCount;
635 			b = convertLogical2Pts(head.width);
636 			h = convertLogical2Pts(head.height);
637 			x = convertLogical2Pts(head.mapMode.origin.x());
638 			y = convertLogical2Pts(head.mapMode.origin.y());
639 			f.close();
640 		}
641 	}
642 }
643 
convert(const QString & fn)644 bool SvmPlug::convert(const QString& fn)
645 {
646 	importedColors.clear();
647 	importedPatterns.clear();
648 	currentDC.CurrColorFill = "White";
649 	currentDC.CurrFillTrans = 0.0;
650 	currentDC.CurrColorStroke = "Black";
651 	currentDC.CurrStrokeTrans = 0.0;
652 	currentDC.CurrColorText = "Black";
653 	currentDC.backColor = CommonStrings::None;
654 	currentDC.LineW = 1.0;
655 	currentDC.penStyle = Qt::SolidLine;
656 	currentDC.penCap = Qt::FlatCap;
657 	currentDC.penJoin = Qt::MiterJoin;
658 	currentDC.m_mapMode = 1;
659 	currentDC.backgroundMode = false;
660 	currentDC.arcDirection = true;
661 	currentDC.alphaOn = true;
662 	currentDC.fillRule = true;
663 	currentDC.textAlignment = 0;
664 	currentDC.brushStyle = U_BT_SolidColor;
665 	currentDC.hatchStyle = 0;
666 	currentDC.m_WorldMap = QTransform();
667 	currentDC.m_WorldMapEMFP = QTransform();
668 	currentDC.Coords.resize(0);
669 	currentDC.Coords.svgInit();
670 	currentDC.clipPath.resize(0);
671 	currentDC.clipPath.svgInit();
672 	currentDC.fontSize = 12;
673 	currentDC.fontName = "Arial";
674 	currentDC.fontRotation = 0;
675 	currentDC.viewOrigin = QPointF(0, 0);
676 	currentDC.winOrigin = QPointF(0, 0);
677 	currentDC.currentPoint = QPointF();
678 	currentDC.originEMFP = QPointF(0, 0);
679 	currentDC.patternName = "";
680 	currentDC.emfPlusUnit = 2;
681 	inPath = false;
682 	inEMFPlus = false;
683 	emfPlusDual = false;
684 	SerializableObject_Valid = false;
685 	m_Effects.clear();
686 	emfPlusScale = 1.0;
687 	m_ObjSize = 0;
688 	m_currObjSize = 0;
689 	emfStyleMapEMP.clear();
690 	seen_XGRAD_SEQ_BEGIN = false;
691 	if (progressDialog)
692 	{
693 		progressDialog->setOverallProgress(2);
694 		progressDialog->setLabel("GI", tr("Generating Items"));
695 		qApp->processEvents();
696 	}
697 	QFile f(fn);
698 	if (f.open(QIODevice::ReadOnly))
699 	{
700 		if (progressDialog)
701 		{
702 			progressDialog->setTotalSteps("GI", m_records);
703 			qApp->processEvents();
704 		}
705 		QDataStream ds(&f);
706 		ds.setByteOrder(QDataStream::LittleEndian);
707 		ds.setFloatingPointPrecision(QDataStream::SinglePrecision);
708 		QByteArray magic;
709 		magic.resize(6);
710 		ds.readRawData(magic.data(), 6);
711 		if (magic != "VCLMTF")
712 			return false;
713 		recordCount = 0;
714 		qint64 posi = ds.device()->pos();
715 		SvmHeader head;
716 		ds >> head.versionCompat.version;
717 		ds >> head.versionCompat.length;
718 		ds >> head.compressionMode;
719 		ds >> head.mapMode.version.version;
720 		ds >> head.mapMode.version.length;
721 		ds >> head.mapMode.unit;
722 		ds >> head.mapMode.origin;
723 		ds >> head.mapMode.scaleX.numerator;
724 		ds >> head.mapMode.scaleX.denominator;
725 		ds >> head.mapMode.scaleY.numerator;
726 		ds >> head.mapMode.scaleY.denominator;
727 		ds >> head.mapMode.isSimple;
728 		ds >> head.width;
729 		ds >> head.height;
730 		ds >> head.actionCount;
731 		while (!ds.atEnd())
732 		{
733 			recordCount++;
734 			quint16  actionType;
735 			quint16  version;
736 			quint32  totalSize;
737 			ds >> actionType >> version >> totalSize;
738 			posi = ds.device()->pos();
739 			if (seen_XGRAD_SEQ_BEGIN)
740 			{
741 				switch (actionType)
742 				{
743 					case META_GRADIENTEX_ACTION:
744 						handleGradientEX(ds, version);
745 						break;
746 					case META_COMMENT_ACTION:
747 						handleComment(ds);
748 						break;
749 					default:
750 						break;
751 				}
752 			}
753 			else
754 			{
755 				switch (actionType)
756 				{
757 					case META_NULL_ACTION:
758 						break;
759 					case META_PIXEL_ACTION:
760 					//	qDebug() << "PIXEL";
761 						break;
762 					case META_POINT_ACTION:
763 					//	qDebug() << "POINT";
764 						break;
765 					case META_LINE_ACTION:
766 						handleLine(ds);
767 						break;
768 					case META_RECT_ACTION:
769 						handleRectangle(ds);
770 						break;
771 					case META_ROUNDRECT_ACTION:
772 						handleRoundRect(ds);
773 						break;
774 					case META_ELLIPSE_ACTION:
775 						handleEllipse(ds);
776 						break;
777 					case META_ARC_ACTION:
778 					//	qDebug() << "ARC";
779 						break;
780 					case META_PIE_ACTION:
781 					//	qDebug() << "PIE";
782 						break;
783 					case META_CHORD_ACTION:
784 					//	qDebug() << "CHORD";
785 						break;
786 					case META_POLYLINE_ACTION:
787 						handlePolyline(ds);
788 						break;
789 					case META_POLYGON_ACTION:
790 						handlePolygon(ds);
791 						break;
792 					case META_POLYPOLYGON_ACTION:
793 						handlePolyPolygon(ds, version);
794 						break;
795 					case META_TEXT_ACTION:
796 						handleSmallText(ds);
797 						break;
798 					case META_TEXTARRAY_ACTION:
799 						handleText(ds, version);
800 						break;
801 					case META_STRETCHTEXT_ACTION:
802 					//	qDebug() << "STRETCHTEXT";
803 						break;
804 					case META_TEXTRECT_ACTION:
805 					//	qDebug() << "TEXTRECT";
806 						break;
807 					case META_BMP_ACTION:
808 					//	qDebug() << "BMP";
809 						break;
810 					case META_BMPSCALE_ACTION:
811 						handleImage(ds, posi, totalSize);
812 						break;
813 					case META_BMPSCALEPART_ACTION:
814 					//	qDebug() << "BMPSCALEPART";
815 						break;
816 					case META_BMPEX_ACTION:
817 					//	qDebug() << "BMPEX";
818 						break;
819 					case META_BMPEXSCALE_ACTION:
820 						handleImageEX(ds, posi, totalSize);
821 						break;
822 					case META_BMPEXSCALEPART_ACTION:
823 					//	qDebug() << "BMPEXSCALEPART";
824 						break;
825 					case META_MASK_ACTION:
826 					//	qDebug() << "MASK";
827 						break;
828 					case META_MASKSCALE_ACTION:
829 					//	qDebug() << "MASKSCALE";
830 						break;
831 					case META_MASKSCALEPART_ACTION:
832 					//	qDebug() << "MASKSCALEPART";
833 						break;
834 					case META_GRADIENT_ACTION:
835 						handleGradient(ds);
836 						break;
837 					case META_HATCH_ACTION:
838 						handleHatch(ds, version);
839 						break;
840 					case META_WALLPAPER_ACTION:
841 					//	qDebug() << "WALLPAPER";
842 						break;
843 					case META_CLIPREGION_ACTION:
844 					//	qDebug() << "CLIPREGION";
845 						break;
846 					case META_ISECTRECTCLIPREGION_ACTION:
847 					//	qDebug() << "ISECTRECTCLIPREGION";
848 						break;
849 					case META_ISECTREGIONCLIPREGION_ACTION:
850 					//	qDebug() << "ISECTREGIONCLIPREGION";
851 						break;
852 					case META_MOVECLIPREGION_ACTION:
853 					//	qDebug() << "MOVECLIPREGION";
854 						break;
855 					case META_LINECOLOR_ACTION:
856 						getColor(ds, currentDC.CurrColorStroke);
857 						break;
858 					case META_FILLCOLOR_ACTION:
859 						getColor(ds, currentDC.CurrColorFill);
860 						break;
861 					case META_TEXTCOLOR_ACTION:
862 						getColor(ds, currentDC.CurrColorText);
863 						break;
864 					case META_TEXTFILLCOLOR_ACTION:
865 						getColor(ds, currentDC.backColor);
866 						break;
867 						case META_TEXTALIGN_ACTION:
868 						{
869 							quint16 alig;
870 							ds >> alig;
871 							currentDC.textAlignment = alig;
872 						}
873 						break;
874 					case META_MAPMODE_ACTION:
875 						{
876 							MapMode m;
877 							ds >> m.version.version;
878 							ds >> m.version.length;
879 							ds >> m.unit;
880 							ds >> m.origin;
881 							ds >> m.scaleX.numerator;
882 							ds >> m.scaleX.denominator;
883 							ds >> m.scaleY.numerator;
884 							ds >> m.scaleY.denominator;
885 							ds >> m.isSimple;
886 							currentDC.viewOrigin = convertLogical2Pts(QPointF(m.origin.x(), m.origin.y()));
887 						}
888 						break;
889 					case META_FONT_ACTION:
890 						handleFontDef(ds);
891 						break;
892 					case META_PUSH_ACTION:
893 						dcStack.push(currentDC);
894 						break;
895 					case META_POP_ACTION:
896 						if (dcStack.count() > 0)
897 							currentDC = dcStack.pop();
898 						break;
899 					case META_TRANSPARENT_ACTION:
900 						handleTransparent(ds, version);
901 						break;
902 					case META_EPS_ACTION:
903 					//	qDebug() << "EPS";
904 						break;
905 					case META_REFPOINT_ACTION:
906 					//	qDebug() << "REFPOINT";
907 						break;
908 					case META_TEXTLINECOLOR_ACTION:
909 					//	qDebug() << "TEXTLINECOLOR";
910 						break;
911 					case META_TEXTLINE_ACTION:
912 					//	qDebug() << "TEXTLINE";
913 						break;
914 					case META_FLOATTRANSPARENT_ACTION:
915 					//	qDebug() << "FLOATTRANSPARENT";
916 						break;
917 					case META_GRADIENTEX_ACTION:
918 						handleGradientEX(ds, version);
919 						break;
920 					case META_LAYOUTMODE_ACTION:
921 					//	qDebug() << "LAYOUTMODE";
922 						break;
923 					case META_TEXTLANGUAGE_ACTION:
924 					//	qDebug() << "TEXTLANGUAGE";
925 						break;
926 					case META_OVERLINECOLOR_ACTION:
927 					//	qDebug() << "OVERLINECOLOR";
928 						break;
929 					case META_RENDERGRAPHIC_ACTION:
930 					//	qDebug() << "RENDERGRAPHIC";
931 						break;
932 					case META_COMMENT_ACTION:
933 						handleComment(ds);
934 						break;
935 					case META_RASTEROP_ACTION:
936 						break;
937 					default:
938 						break;
939 				}
940 			}
941 			ds.device()->seek(posi + totalSize);
942 			if (progressDialog)
943 			{
944 				progressDialog->setProgress("GI", recordCount);
945 				qApp->processEvents();
946 			}
947 		}
948 		if (Elements.count() == 0)
949 		{
950 			if (importedColors.count() != 0)
951 			{
952 				for (int cd = 0; cd < importedColors.count(); cd++)
953 				{
954 					m_Doc->PageColors.remove(importedColors[cd]);
955 				}
956 			}
957 			if (importedPatterns.count() != 0)
958 			{
959 				for (int cd = 0; cd < importedPatterns.count(); cd++)
960 				{
961 					m_Doc->docPatterns.remove(importedPatterns[cd]);
962 				}
963 			}
964 		}
965 		f.close();
966 	}
967 	if (progressDialog)
968 		progressDialog->close();
969 	return true;
970 }
971 
aligntoQuadWord(QDataStream & ds)972 void SvmPlug::aligntoQuadWord(QDataStream &ds)
973 {
974 	if ((ds.device()->pos() % 4) != 0)
975 	{
976 		qint32 adj = 4 - (ds.device()->pos() % 4);
977 		ds.skipRawData(adj);
978 	}
979 }
980 
convertLogical2Pts(double in)981 double SvmPlug::convertLogical2Pts(double in)
982 {
983 	QPointF pp;
984 	pp.setX(in);
985 	pp = convertLogical2Pts(pp);
986 	return pp.x();
987 }
988 
convertLogical2Pts(QPointF in)989 QPointF SvmPlug::convertLogical2Pts(QPointF in)
990 {
991 	QPointF out;
992 	switch (head.mapMode.unit)
993 	{
994 		case MAP_100TH_MM:
995 			out.setX(in.x() / 1000.0 / 2.54 * 72.0);
996 			out.setY(in.y() / 1000.0 / 2.54 * 72.0);
997 			break;
998 		case MAP_10TH_MM:
999 			out.setX(in.x() / 100.0 / 2.54 * 72.0);
1000 			out.setY(in.y() / 100.0 / 2.54 * 72.0);
1001 			break;
1002 		case MAP_MM:
1003 			out.setX(in.x() / 10.0 / 2.54 * 72.0);
1004 			out.setY(in.y() / 10.0 / 2.54 * 72.0);
1005 			break;
1006 		case MAP_CM:
1007 			out.setX(in.x() / 2.54 * 72.0);
1008 			out.setY(in.y() / 2.54 * 72.0);
1009 			break;
1010 		case MAP_1000TH_INCH:
1011 			out.setX(in.x() / 1000.0 * 72.0);
1012 			out.setY(in.y() / 1000.0 * 72.0);
1013 			break;
1014 		case MAP_100TH_INCH:
1015 			out.setX(in.x() / 100.0 * 72.0);
1016 			out.setY(in.y() / 100.0 * 72.0);
1017 			break;
1018 		case MAP_10TH_INCH:
1019 			out.setX(in.x() / 10.0 * 72.0);
1020 			out.setY(in.y() / 10.0 * 72.0);
1021 			break;
1022 		case MAP_INCH:
1023 			out.setX(in.x() * 72.0);
1024 			out.setY(in.y() * 72.0);
1025 			break;
1026 		case MAP_TWIP:
1027 			out.setX(in.x() / 1440.0 * 72.0);
1028 			out.setY(in.y() / 1440.0 * 72.0);
1029 			break;
1030 		default:
1031 			out = in;
1032 			break;
1033 	}
1034 	return out;
1035 }
1036 
getPolyPolygonPoints(QDataStream & ds,quint16 version)1037 FPointArray SvmPlug::getPolyPolygonPoints(QDataStream &ds, quint16 version)
1038 {
1039 	quint16 numPolys;
1040 	ds >> numPolys;
1041 	FPointArray pointsPoly;
1042 	pointsPoly.svgInit();
1043 	for (quint16 a = 0; a < numPolys; a++)
1044 	{
1045 		quint16 numPoints;
1046 		ds >> numPoints;
1047 		FPointArray poly = getPolyPoints(ds, numPoints, true);
1048 		pointsPoly += poly;
1049 		if (numPolys > 1)
1050 			pointsPoly.setMarker();
1051 	}
1052 	if (version > 1)
1053 	{
1054 		quint16 numComPolys;
1055 		ds >> numComPolys;
1056 		if (numComPolys > 0)
1057 		{
1058 			pointsPoly.resize(0);
1059 			pointsPoly.svgInit();
1060 			for (quint16 i = 0 ; i < numComPolys ; i++)
1061 			{
1062 				FPointArray poly;
1063 				poly.svgInit();
1064 				QList<QPointF> points;
1065 				QList<quint8> pTypes;
1066 				quint16 vv, indexNum;
1067 				ds >> indexNum >> vv;
1068 				quint32 dummy;
1069 				ds >> dummy;
1070 				qint64 posC = ds.device()->pos();
1071 				quint16  numPoints;
1072 				ds >> numPoints;
1073 				points.reserve(numPoints);
1074 				for (uint i = 0; i < numPoints; ++i)
1075 				{
1076 					QPointF p = getPoint(ds);
1077 					points.append(p);
1078 				}
1079 				pTypes.reserve(numPoints);
1080 				for (uint i = 0; i < numPoints; ++i)
1081 				{
1082 					quint8 ptyc;
1083 					ds >> ptyc;
1084 					pTypes.append(ptyc);
1085 				}
1086 				for (quint16 c = 0; c < numPoints; c++)
1087 				{
1088 					QPointF p = points[c];
1089 					quint8 pty = pTypes[c];
1090 					if (pty == 1)
1091 					{
1092 						if ((c < numPoints-2) && (pTypes[c+1] == 2))
1093 						{
1094 							QPointF p2 = points[c+1];
1095 							QPointF p3 = points[c+2];
1096 							poly.svgCurveToCubic(p.x(), p.y(), p2.x(), p2.y(), p3.x(), p3.y());
1097 							c += 2;
1098 						}
1099 						else
1100 							poly.svgMoveTo(p.x(), p.y());
1101 					}
1102 					else if (pty == 0)
1103 					{
1104 						if ((c < numPoints-2) && (pTypes[c+1] == 2))
1105 						{
1106 							QPointF p2 = points[c+1];
1107 							QPointF p3 = points[c+2];
1108 							poly.svgCurveToCubic(p.x(), p.y(), p2.x(), p2.y(), p3.x(), p3.y());
1109 							c += 2;
1110 						}
1111 						else
1112 							poly.svgLineTo(p.x(), p.y());
1113 					}
1114 					else if (pty == 3)
1115 					{
1116 						QPointF p2 = points[c+1];
1117 						QPointF p3 = points[c+2];
1118 						poly.svgCurveToCubic(p.x(), p.y(), p2.x(), p2.y(), p3.x(), p3.y());
1119 						c += 2;
1120 					}
1121 				}
1122 				ds.device()->seek(dummy + posC);
1123 				poly.svgClosePath();
1124 				pointsPoly += poly;
1125 				if (numPolys > 1)
1126 					pointsPoly.setMarker();
1127 			}
1128 		}
1129 	}
1130 	return pointsPoly;
1131 }
1132 
getPolyPoints(QDataStream & ds,quint32 count,bool closed)1133 FPointArray SvmPlug::getPolyPoints(QDataStream &ds, quint32 count, bool closed)
1134 {
1135 	bool bFirst = true;
1136 	FPointArray polyline;
1137 	polyline.svgInit();
1138 	for (quint32 a = 0; a < count; a++)
1139 	{
1140 		QPointF p = getPoint(ds);
1141 		if (bFirst)
1142 		{
1143 			polyline.svgMoveTo(p.x(), p.y());
1144 			bFirst = false;
1145 		}
1146 		else
1147 			polyline.svgLineTo(p.x(), p.y());
1148 	}
1149 	if ((polyline.size() > 4) && (closed))
1150 		polyline.svgClosePath();
1151 	return polyline;
1152 }
1153 
getPoint(QDataStream & ds)1154 QPointF SvmPlug::getPoint(QDataStream &ds)
1155 {
1156 	qint32 x1, y1;
1157 	ds >> x1 >> y1;
1158 	QPointF p = convertLogical2Pts(QPointF(x1, y1));
1159 	p += currentDC.viewOrigin;
1160 	return p;
1161 }
1162 
getColor(QDataStream & ds,QString & colorN)1163 void SvmPlug::getColor(QDataStream &ds, QString &colorN)
1164 {
1165 	quint32 colorData;
1166 	quint8  colorValid;
1167 	ds >> colorData;
1168 	ds >> colorValid;
1169 	QColor col = QColor::fromRgb(colorData);
1170 	if (colorValid)
1171 		colorN = handleColor(col);
1172 	else
1173 		colorN = CommonStrings::None;
1174 }
1175 
intersectBoundingRect(PageItem * item,QLineF gradientVector)1176 QPointF SvmPlug::intersectBoundingRect(PageItem *item, QLineF gradientVector)
1177 {
1178 	QPointF interPoint;
1179 	QPointF gradEnd;
1180 	if (gradientVector.intersects(QLineF(0, 0, item->width(), 0), &interPoint) == QLineF::BoundedIntersection)
1181 		gradEnd = interPoint;
1182 	else if (gradientVector.intersects(QLineF(item->width(), 0, item->width(), item->height()), &interPoint) == QLineF::BoundedIntersection)
1183 		gradEnd = interPoint;
1184 	else if (gradientVector.intersects(QLineF(item->width(), item->height(), 0, item->height()), &interPoint) == QLineF::BoundedIntersection)
1185 		gradEnd = interPoint;
1186 	else if (gradientVector.intersects(QLineF(0, item->height(), 0, 0), &interPoint) == QLineF::BoundedIntersection)
1187 		gradEnd = interPoint;
1188 	return gradEnd;
1189 }
1190 
finishItem(PageItem * ite,bool fill)1191 void SvmPlug::finishItem(PageItem* ite, bool fill)
1192 {
1193 	ite->fillRule = currentDC.fillRule;
1194 	ite->ClipEdited = true;
1195 	ite->FrameType = 3;
1196 	ite->setFillShade(100.0);
1197 	ite->setLineShade(100.0);
1198 	ite->setLineJoin(currentDC.penJoin);
1199 	ite->setLineEnd(currentDC.penCap);
1200 	ite->setLineStyle(currentDC.penStyle);
1201 	if (!currentDC.dashArray.isEmpty())
1202 	{
1203 		ite->DashValues.clear();
1204 		for (int a = 0; a < currentDC.dashArray.count(); a++)
1205 		{
1206 			ite->DashValues.append(currentDC.dashArray[a] * ite->lineWidth());
1207 		}
1208 	}
1209 	ite->DashOffset = currentDC.dashOffset;
1210 	if (inEMFPlus && currentDC.alphaOn)
1211 	{
1212 		ite->setFillTransparency(currentDC.CurrFillTrans);
1213 		ite->setLineTransparency(currentDC.CurrStrokeTrans);
1214 	}
1215 	FPoint oldPos = getMinClipF(&ite->PoLine);
1216 	FPoint wh = getMaxClipF(&ite->PoLine);
1217 	ite->setWidthHeight(wh.x(),wh.y());
1218 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
1219 	m_Doc->adjustItemSize(ite);
1220 	ite->moveBy(-docX, -docY, true);
1221 	ite->OldB2 = ite->width();
1222 	ite->OldH2 = ite->height();
1223 	ite->updateClip();
1224 	if (fill)
1225 	{
1226 		if (inEMFPlus)
1227 		{
1228 			if (currentDC.brushStyle == U_BT_HatchFill)
1229 			{
1230 				switch (currentDC.hatchStyle)
1231 				{
1232 					case U_HSP_Horizontal:
1233 						ite->setHatchParameters(0, 5, 0, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
1234 						ite->GrType = Gradient_Hatch;
1235 						break;
1236 					case U_HSP_Vertical:
1237 						ite->setHatchParameters(0, 5, 90, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
1238 						ite->GrType = Gradient_Hatch;
1239 						break;
1240 					case U_HSP_ForwardDiagonal:
1241 						ite->setHatchParameters(0, 5, -45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
1242 						ite->GrType = Gradient_Hatch;
1243 						break;
1244 					case U_HSP_BackwardDiagonal:
1245 						ite->setHatchParameters(0, 5, 45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
1246 						ite->GrType = Gradient_Hatch;
1247 						break;
1248 					case U_HSP_LargeGrid:
1249 						ite->setHatchParameters(1, 5, 0, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
1250 						ite->GrType = Gradient_Hatch;
1251 						break;
1252 					case U_HSP_DiagonalCross:
1253 						ite->setHatchParameters(1, 5, 45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
1254 						ite->GrType = Gradient_Hatch;
1255 						break;
1256 					default:
1257 						ite->setHatchParameters(1, 5, 45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
1258 						ite->GrType = Gradient_Hatch;
1259 						break;
1260 				}
1261 			}
1262 			else if (currentDC.brushStyle == U_BT_LinearGradient)
1263 			{
1264 				ite->fill_gradient = currentDC.gradient;
1265 				QLineF gradientVectorE;
1266 				gradientVectorE.setP1(QPointF(ite->width() / 2.0, ite->height() / 2.0));
1267 				gradientVectorE.setAngle(currentDC.gradientAngle);
1268 				gradientVectorE.setLength(sqrt(ite->width() * ite->width() + ite->height() * ite->height()) / 2.0 + 1.0);
1269 				QPointF gradEnd = intersectBoundingRect(ite, gradientVectorE);
1270 				QLineF gradientVectorS;
1271 				gradientVectorS.setP1(QPointF(ite->width() / 2.0, ite->height() / 2.0));
1272 				gradientVectorS.setAngle(currentDC.gradientAngle + 180);
1273 				gradientVectorS.setLength(sqrt(ite->width() * ite->width() + ite->height() * ite->height()) / 2.0 + 1.0);
1274 				QPointF gradStart = intersectBoundingRect(ite, gradientVectorS);
1275 				ite->setGradientVector(gradStart.x(), gradStart.y(), gradEnd.x(), gradEnd.y(), gradStart.x(), gradStart.y(), 1, 0);
1276 				ite->setGradientType(6);
1277 			}
1278 			else if (currentDC.brushStyle == U_BT_PathGradient)
1279 			{
1280 				FPoint newPos = getMinClipF(&ite->PoLine);
1281 				double dx = newPos.x() - oldPos.x();
1282 				double dy = newPos.y() - oldPos.y();
1283 				QPointF cx = currentDC.gradientStart + QPointF(dx, dy);
1284 				FPointArray gpath = currentDC.gradientPath.copy();
1285 				gpath.translate(dx, dy);
1286 				for (int sub = 0; sub < 2; sub++)
1287 				{
1288 					FPointArray points;
1289 					double nearT = 0.5;
1290 					uint psize = gpath.size();
1291 					for (uint a = 0; a < psize-3; a += 4)
1292 					{
1293 						if (gpath.isMarker(a))
1294 						{
1295 							points.setMarker();
1296 							continue;
1297 						}
1298 						const FPoint& base = gpath.point(a);
1299 						const FPoint& c1 = gpath.point(a+1);
1300 						const FPoint& base2 =  gpath.point(a+2);
1301 						const FPoint& c2 = gpath.point(a+3);
1302 						FPoint cn1 = (1.0 - nearT) * base + nearT * c1;
1303 						FPoint cn2 = (1.0 - nearT) * cn1 + nearT * ((1.0 - nearT) * c1 + nearT * c2);
1304 						FPoint cn3 = (1.0 - nearT) * ((1.0 - nearT) * c1 + nearT * c2) + nearT * ((1.0 - nearT) * c2 + nearT * base2);
1305 						FPoint cn4 = (1.0 - nearT) * c2 + nearT * base2;
1306 						FPoint bp1 = (1.0 - nearT) * cn2 + nearT * cn3;
1307 						if ((base == c1) && (base2 == c2))
1308 						{
1309 							points.addPoint(base);
1310 							points.addPoint(c1);
1311 							points.addPoint(bp1);
1312 							points.addPoint(bp1);
1313 							points.addPoint(bp1);
1314 							points.addPoint(bp1);
1315 							points.addPoint(base2);
1316 							points.addPoint(c2);
1317 						}
1318 						else
1319 						{
1320 							points.addPoint(base);
1321 							points.addPoint(cn1);
1322 							points.addPoint(bp1);
1323 							points.addPoint(cn2);
1324 							points.addPoint(bp1);
1325 							points.addPoint(cn3);
1326 							points.addPoint(base2);
1327 							points.addPoint(cn4);
1328 						}
1329 					}
1330 					gpath = points;
1331 				}
1332 				ite->meshGradientPatches.clear();
1333 				FPoint center = FPoint(cx.x(), cx.y());
1334 				QList<VColorStop*> colorStops = currentDC.gradient.colorStops();
1335 				if (colorStops.count() == 2)
1336 				{
1337 					int endC = colorStops.count() - 1;
1338 					MeshPoint cP;
1339 					cP.resetTo(center);
1340 					cP.transparency = colorStops[0]->opacity;
1341 					cP.shade = 100;
1342 					cP.colorName = colorStops[0]->name;
1343 					cP.color = colorStops[0]->color;
1344 					for (int poi = 0; poi < gpath.size()-3; poi += 4)
1345 					{
1346 						meshGradientPatch patch;
1347 						patch.BL = cP;
1348 						patch.BR = cP;
1349 						if (gpath.isMarker(poi))
1350 							continue;
1351 						MeshPoint tL;
1352 						tL.resetTo(gpath.point(poi));
1353 						tL.controlRight = gpath.point(poi + 1);
1354 						tL.transparency = colorStops[endC]->opacity;
1355 						tL.shade = 100;
1356 						tL.colorName = colorStops[endC]->name;
1357 						tL.color = colorStops[endC]->color;
1358 						MeshPoint tR;
1359 						tR.resetTo(gpath.point(poi + 2));
1360 						tR.controlLeft = gpath.point(poi + 3);
1361 						tR.transparency = colorStops[endC]->opacity;
1362 						tR.shade = 100;
1363 						tR.colorName = colorStops[endC]->name;
1364 						tR.color = colorStops[endC]->color;
1365 						patch.TL = tL;
1366 						patch.TR = tR;
1367 						ite->meshGradientPatches.append(patch);
1368 					}
1369 				}
1370 				else
1371 				{
1372 					FPointArray gpath2 = gpath.copy();
1373 					QTransform mm;
1374 					mm.translate(cx.x(), cx.y());
1375 					mm.scale(colorStops[1]->rampPoint, colorStops[1]->rampPoint);
1376 					mm.translate(-cx.x(), -cx.y());
1377 					gpath2.map(mm);
1378 					MeshPoint cP;
1379 					cP.resetTo(center);
1380 					cP.transparency = colorStops[0]->opacity;
1381 					cP.shade = 100;
1382 					cP.colorName = colorStops[0]->name;
1383 					cP.color = colorStops[0]->color;
1384 					for (int poi = 0; poi < gpath2.size()-3; poi += 4)
1385 					{
1386 						meshGradientPatch patch;
1387 						patch.BL = cP;
1388 						patch.BR = cP;
1389 						if (gpath.isMarker(poi))
1390 							continue;
1391 						MeshPoint tL;
1392 						tL.resetTo(gpath2.point(poi));
1393 						tL.controlRight = gpath2.point(poi + 1);
1394 						tL.transparency = colorStops[1]->opacity;
1395 						tL.shade = 100;
1396 						tL.colorName = colorStops[1]->name;
1397 						tL.color = colorStops[1]->color;
1398 						MeshPoint tR;
1399 						tR.resetTo(gpath2.point(poi + 2));
1400 						tR.controlLeft = gpath2.point(poi + 3);
1401 						tR.transparency = colorStops[1]->opacity;
1402 						tR.shade = 100;
1403 						tR.colorName = colorStops[1]->name;
1404 						tR.color = colorStops[1]->color;
1405 						patch.TL = tL;
1406 						patch.TR = tR;
1407 						ite->meshGradientPatches.append(patch);
1408 					}
1409 					for (int cstp = 2; cstp < colorStops.count(); cstp++)
1410 					{
1411 						FPointArray gpath3 = gpath2.copy();
1412 						gpath2 = gpath.copy();
1413 						QTransform mm;
1414 						mm.translate(cx.x(), cx.y());
1415 						mm.scale(colorStops[cstp]->rampPoint, colorStops[cstp]->rampPoint);
1416 						mm.translate(-cx.x(), -cx.y());
1417 						gpath2.map(mm);
1418 						for (int poi = 0; poi < gpath2.size()-3; poi += 4)
1419 						{
1420 							if (gpath.isMarker(poi))
1421 								continue;
1422 							meshGradientPatch patch;
1423 							MeshPoint bL;
1424 							bL.resetTo(gpath3.point(poi));
1425 							bL.controlRight = gpath3.point(poi + 1);
1426 							bL.transparency = colorStops[cstp - 1]->opacity;
1427 							bL.shade = 100;
1428 							bL.colorName = colorStops[cstp - 1]->name;
1429 							bL.color = colorStops[cstp - 1]->color;
1430 							patch.BL = bL;
1431 							MeshPoint bR;
1432 							bR.resetTo(gpath3.point(poi + 2));
1433 							bR.controlLeft = gpath3.point(poi + 3);
1434 							bR.transparency = colorStops[cstp - 1]->opacity;
1435 							bR.shade = 100;
1436 							bR.colorName = colorStops[cstp - 1]->name;
1437 							bR.color = colorStops[cstp - 1]->color;
1438 							patch.BR = bR;
1439 							MeshPoint tL;
1440 							tL.resetTo(gpath2.point(poi));
1441 							tL.controlRight = gpath2.point(poi + 1);
1442 							tL.transparency = colorStops[cstp]->opacity;
1443 							tL.shade = 100;
1444 							tL.colorName = colorStops[cstp]->name;
1445 							tL.color = colorStops[cstp]->color;
1446 							MeshPoint tR;
1447 							tR.resetTo(gpath2.point(poi + 2));
1448 							tR.controlLeft = gpath2.point(poi + 3);
1449 							tR.transparency = colorStops[cstp]->opacity;
1450 							tR.shade = 100;
1451 							tR.colorName = colorStops[cstp]->name;
1452 							tR.color = colorStops[cstp]->color;
1453 							patch.TL = tL;
1454 							patch.TR = tR;
1455 							ite->meshGradientPatches.append(patch);
1456 						}
1457 					}
1458 				}
1459 				ite->GrType = Gradient_PatchMesh;
1460 			}
1461 			else if (currentDC.brushStyle == U_BT_TextureFill)
1462 			{
1463 				if (m_Doc->docPatterns.contains(currentDC.patternName))
1464 				{
1465 					ite->setPattern(currentDC.patternName);
1466 					ScPattern pat = m_Doc->docPatterns[currentDC.patternName];
1467 					if ((pat.height < ite->height()) || (pat.width < ite->width()))
1468 					{
1469 						if (currentDC.patternMode == 1)
1470 							ite->setPatternFlip(true, false);
1471 						else if (currentDC.patternMode == 2)
1472 							ite->setPatternFlip(false, true);
1473 						else if (currentDC.patternMode == 3)
1474 							ite->setPatternFlip(true, true);
1475 						else if (currentDC.patternMode == 4)
1476 						{
1477 							double sx = ite->width() / pat.width * 100;
1478 							double sy = ite->height() / pat.height * 100;
1479 							ite->setPatternTransform(sx, sy, 0, 0, 0, 0, 0);
1480 						}
1481 					}
1482 					else
1483 					{
1484 						double sx = ite->width() / pat.width * 100;
1485 						double sy = ite->height() / pat.height * 100;
1486 						ite->setPatternTransform(sx, sy, 0, 0, 0, 0, 0);
1487 					}
1488 					ite->GrType = Gradient_Pattern;
1489 				}
1490 			}
1491 		}
1492 	}
1493 	if (inEMFPlus)
1494 	{
1495 		if ((currentDC.brushStyle == U_BT_PathGradient) || (currentDC.brushStyle == U_BT_LinearGradient))
1496 		{
1497 			if ((!currentDC.clipPath.isEmpty()) && (ite->itemType() != PageItem::ImageFrame))
1498 			{
1499 				PageItem *iteG;
1500 				QList<PageItem*> gElements;
1501 				gElements.append(ite);
1502 				tmpSel->clear();
1503 				tmpSel->addItem(ite, true);
1504 				iteG = m_Doc->groupObjectsSelection(tmpSel);
1505 				iteG->setTextFlowMode(PageItem::TextFlowUsesBoundingBox);
1506 				double oldX = iteG->xPos();
1507 				double oldY = iteG->yPos();
1508 				double oldW = iteG->width();
1509 				double oldH = iteG->height();
1510 				double oldgW = iteG->groupWidth;
1511 				double oldgH = iteG->groupHeight;
1512 				iteG->PoLine = currentDC.clipPath.copy();
1513 				iteG->PoLine.translate(baseX, baseY);
1514 				FPoint xy = getMinClipF(&iteG->PoLine);
1515 				iteG->setXYPos(xy.x(), xy.y(), true);
1516 				iteG->PoLine.translate(-xy.x(), -xy.y());
1517 				FPoint wh = getMaxClipF(&iteG->PoLine);
1518 				iteG->setWidthHeight(wh.x(),wh.y());
1519 				iteG->groupWidth = oldgW * (iteG->width() / oldW);
1520 				iteG->groupHeight = oldgH * (iteG->height() / oldH);
1521 				double dx = (iteG->xPos() - oldX) / (iteG->width() / iteG->groupWidth);
1522 				double dy = (iteG->yPos() - oldY) / (iteG->height() / iteG->groupHeight);
1523 				for (int em = 0; em < iteG->groupItemList.count(); ++em)
1524 				{
1525 					PageItem* embedded = iteG->groupItemList.at(em);
1526 					embedded->moveBy(-dx, -dy, true);
1527 					m_Doc->setRedrawBounding(embedded);
1528 					embedded->OwnPage = m_Doc->OnPage(embedded);
1529 				}
1530 				iteG->ClipEdited = true;
1531 				iteG->OldB2 = ite->width();
1532 				iteG->OldH2 = ite->height();
1533 				iteG->Clip = flattenPath(iteG->PoLine, iteG->Segments);
1534 				iteG->updateGradientVectors();
1535 				ite = iteG;
1536 				tmpSel->clear();
1537 			}
1538 		}
1539 	}
1540 	Elements.append(ite);
1541 }
1542 
handleEllipse(QDataStream & ds)1543 void SvmPlug::handleEllipse(QDataStream &ds)
1544 {
1545 	QPointF p1 = getPoint(ds);
1546 	QPointF p2 = getPoint(ds);
1547 	QRectF box = QRectF(p1, p2);
1548 	int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX, baseY, box.width(), box.height(), 0, currentDC.CurrColorFill, CommonStrings::None);
1549 	PageItem* ite = m_Doc->Items->at(z);
1550 	QTransform mm(1.0, 0.0, 0.0, 1.0, box.x(), box.y());
1551 	ite->PoLine.map(mm);
1552 	finishItem(ite);
1553 }
1554 
handleRectangle(QDataStream & ds)1555 void SvmPlug::handleRectangle(QDataStream &ds)
1556 {
1557 	QPointF p1 = getPoint(ds);
1558 	QPointF p2 = getPoint(ds);
1559 	QRectF box = QRectF(p1, p2);
1560 	int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX, baseY, box.width(), box.height(), 0, currentDC.CurrColorFill, CommonStrings::None);
1561 	PageItem* ite = m_Doc->Items->at(z);
1562 	QTransform mm(1.0, 0.0, 0.0, 1.0, box.x(), box.y());
1563 	ite->PoLine.map(mm);
1564 	finishItem(ite);
1565 }
1566 
handleRoundRect(QDataStream & ds)1567 void SvmPlug::handleRoundRect(QDataStream &ds)
1568 {
1569 	QPointF p1 = getPoint(ds);
1570 	QPointF p2 = getPoint(ds);
1571 	qint32 x1, y1;
1572 	ds >> x1 >> y1;
1573 	QPointF p3 = convertLogical2Pts(QPointF(x1, y1));
1574 	QRectF BoxDev = QRectF(p1, p2);
1575 	int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX, baseY, BoxDev.width(), BoxDev.height(), 0, currentDC.CurrColorFill, CommonStrings::None);
1576 	PageItem* ite = m_Doc->Items->at(z);
1577 	QTransform mm(1.0, 0.0, 0.0, 1.0, BoxDev.x(), BoxDev.y());
1578 	ite->PoLine.map(mm);
1579 	finishItem(ite);
1580 	if ((p3.x() != 0.0) || (p3.y() != 0.0))
1581 	{
1582 		ite->setCornerRadius(qMax(p3.x(), p3.y()));
1583 		ite->SetFrameRound();
1584 		m_Doc->setRedrawBounding(ite);
1585 	}
1586 }
1587 
handlePolyline(QDataStream & ds)1588 void SvmPlug::handlePolyline(QDataStream &ds)
1589 {
1590 	quint16   numPoints;
1591 	ds >> numPoints;
1592 	FPointArray poly = getPolyPoints(ds, numPoints, false);
1593 	VersionCompat comp;
1594 	ds >> comp.version;
1595 	ds >> comp.length;
1596 	quint16 lineStyle;
1597 	quint32 lineWidth = 0;
1598 	ds >> lineStyle;
1599 	if (comp.version > 1)
1600 		ds >> lineWidth;
1601 	currentDC.LineW = convertLogical2Pts(lineWidth);
1602 	if (poly.count() != 0)
1603 	{
1604 		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
1605 		PageItem* ite = m_Doc->Items->at(z);
1606 		ite->PoLine = poly.copy();
1607 		finishItem(ite, false);
1608 	}
1609 }
1610 
handleLine(QDataStream & ds)1611 void SvmPlug::handleLine(QDataStream &ds)
1612 {
1613 	QPointF p1 = getPoint(ds);
1614 	QPointF p2 = getPoint(ds);
1615 	VersionCompat comp;
1616 	ds >> comp.version;
1617 	ds >> comp.length;
1618 	quint16 lineStyle;
1619 	quint32 lineWidth = 0;
1620 	ds >> lineStyle;
1621 	if (comp.version > 1)
1622 		ds >> lineWidth;
1623 	currentDC.LineW = convertLogical2Pts(lineWidth);
1624 	FPointArray  pointArray;
1625 	pointArray.svgInit();
1626 	pointArray.svgMoveTo(p1.x(), p1.y());
1627 	pointArray.svgLineTo(p2.x(), p2.y());
1628 	int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
1629 	PageItem* ite = m_Doc->Items->at(z);
1630 	ite->PoLine = pointArray.copy();
1631 	finishItem(ite);
1632 }
1633 
handleArc(QDataStream & ds)1634 void SvmPlug::handleArc(QDataStream &ds)
1635 {
1636 	QPointF p1 = getPoint(ds);
1637 	QPointF p2 = getPoint(ds);
1638 	QRectF BoxDev = QRectF(p1, p2);
1639 	QPointF st = getPoint(ds);
1640 	QPointF en = getPoint(ds);
1641 	QLineF stlin = QLineF(BoxDev.center(), st);
1642 	QLineF enlin = QLineF(BoxDev.center(), en);
1643 	FPointArray  pointArray;
1644 	QPainterPath painterPath;
1645 	painterPath.arcMoveTo(BoxDev, stlin.angle());
1646 	if (currentDC.arcDirection)
1647 		painterPath.arcTo(BoxDev, stlin.angle(), enlin.angle() - stlin.angle());
1648 	else
1649 		painterPath.arcTo(BoxDev, stlin.angle(), stlin.angle() - enlin.angle());
1650 	pointArray.fromQPainterPath(painterPath);
1651 	if (pointArray.count() != 0)
1652 	{
1653 		if (inPath)
1654 		{
1655 			currentDC.Coords += pointArray;
1656 			currentDC.currentPoint = en;
1657 		}
1658 		else
1659 		{
1660 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
1661 			PageItem* ite = m_Doc->Items->at(z);
1662 			ite->PoLine = pointArray.copy();
1663 			finishItem(ite, false);
1664 		}
1665 	}
1666 }
1667 
handleArcTo(QDataStream & ds)1668 void SvmPlug::handleArcTo(QDataStream &ds)
1669 {
1670 	QPointF p1 = getPoint(ds);
1671 	QPointF p2 = getPoint(ds);
1672 	QRectF BoxDev = QRectF(p1, p2);
1673 	QPointF st = getPoint(ds);
1674 	QPointF en = getPoint(ds);
1675 	QLineF stlin = QLineF(BoxDev.center(), st);
1676 	QLineF enlin = QLineF(BoxDev.center(), en);
1677 	if (inPath)
1678 	{
1679 		if (enlin.angleTo(stlin) > 180)
1680 		{
1681 		//	currentDC.Coords.svgMoveTo(st.x(), st.y());
1682 			currentDC.Coords.svgArcTo(BoxDev.width() / 2.0, BoxDev.height() / 2.0, 0, enlin.angleTo(stlin) < 180, stlin.angleTo(enlin) > 180, en.x(), en.y());
1683 		}
1684 		else
1685 		{
1686 		//	currentDC.Coords.svgMoveTo(st.x(), st.y());
1687 			currentDC.Coords.svgArcTo(BoxDev.width() / 2.0, BoxDev.height() / 2.0, 0, enlin.angleTo(stlin) > 180, stlin.angleTo(enlin) > 180, en.x(), en.y());
1688 		}
1689 		currentDC.currentPoint = en;
1690 	}
1691 	else
1692 	{
1693 		FPointArray  pointArray;
1694 		QPainterPath painterPath;
1695 		double ang1 = stlin.angleTo(enlin);
1696 		if (currentDC.arcDirection)
1697 		{
1698 			painterPath.arcMoveTo(BoxDev, stlin.angle());
1699 			painterPath.arcTo(BoxDev, stlin.angle(), ang1);
1700 		}
1701 		else
1702 		{
1703 			painterPath.arcMoveTo(BoxDev, stlin.angle());
1704 			painterPath.arcTo(BoxDev, stlin.angle(), -(360 - ang1));
1705 		}
1706 		pointArray.fromQPainterPath(painterPath);
1707 		if (pointArray.count() != 0)
1708 		{
1709 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
1710 			PageItem* ite = m_Doc->Items->at(z);
1711 			ite->PoLine = pointArray.copy();
1712 			finishItem(ite, false);
1713 		}
1714 	}
1715 }
1716 
handleChord(QDataStream & ds)1717 void SvmPlug::handleChord(QDataStream &ds)
1718 {
1719 	QPointF p1 = getPoint(ds);
1720 	QPointF p2 = getPoint(ds);
1721 	QRectF BoxDev = QRectF(p1, p2);
1722 	QPointF st = getPoint(ds);
1723 	QPointF en = getPoint(ds);
1724 	QLineF stlin = QLineF(BoxDev.center(), st);
1725 	QLineF enlin = QLineF(BoxDev.center(), en);
1726 	FPointArray  pointArray;
1727 	QPainterPath painterPath;
1728 	QPointF firstPoint;
1729 	double ang1 = stlin.angleTo(enlin);
1730 	if (currentDC.arcDirection)
1731 	{
1732 		painterPath.arcMoveTo(BoxDev, stlin.angle());
1733 		firstPoint = painterPath.currentPosition();
1734 		painterPath.arcTo(BoxDev, stlin.angle(), ang1);
1735 	}
1736 	else
1737 	{
1738 		painterPath.arcMoveTo(BoxDev, stlin.angle());
1739 		firstPoint = painterPath.currentPosition();
1740 		painterPath.arcTo(BoxDev, stlin.angle(), -(360 - ang1));
1741 	}
1742 	painterPath.lineTo(firstPoint);
1743 	pointArray.fromQPainterPath(painterPath);
1744 	if (pointArray.count() != 0)
1745 	{
1746 		if (inPath)
1747 		{
1748 			currentDC.Coords += pointArray;
1749 			currentDC.currentPoint = firstPoint;
1750 		}
1751 		else
1752 		{
1753 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, currentDC.CurrColorFill, currentDC.CurrColorStroke);
1754 			PageItem* ite = m_Doc->Items->at(z);
1755 			ite->PoLine = pointArray.copy();
1756 			finishItem(ite);
1757 		}
1758 	}
1759 }
1760 
handlePie(QDataStream & ds)1761 void SvmPlug::handlePie(QDataStream &ds)
1762 {
1763 	QPointF p1 = getPoint(ds);
1764 	QPointF p2 = getPoint(ds);
1765 	QRectF BoxDev = QRectF(p1, p2);
1766 	QPointF st = getPoint(ds);
1767 	QPointF en = getPoint(ds);
1768 	QLineF stlin = QLineF(BoxDev.center(), st);
1769 	QLineF enlin = QLineF(BoxDev.center(), en);
1770 	FPointArray  pointArray;
1771 	QPainterPath painterPath;
1772 	QPointF firstPoint;
1773 	double ang1 = stlin.angleTo(enlin);
1774 	if (currentDC.arcDirection)
1775 	{
1776 		painterPath.arcMoveTo(BoxDev, stlin.angle());
1777 		firstPoint = painterPath.currentPosition();
1778 		painterPath.arcTo(BoxDev, stlin.angle(), ang1);
1779 	}
1780 	else
1781 	{
1782 		painterPath.arcMoveTo(BoxDev, stlin.angle());
1783 		firstPoint = painterPath.currentPosition();
1784 		painterPath.arcTo(BoxDev, stlin.angle(), -(360 - ang1));
1785 	}
1786 	painterPath.lineTo(BoxDev.center());
1787 	painterPath.lineTo(firstPoint);
1788 	pointArray.fromQPainterPath(painterPath);
1789 	if (pointArray.count() != 0)
1790 	{
1791 		if (inPath)
1792 		{
1793 			currentDC.Coords += pointArray;
1794 			currentDC.currentPoint = firstPoint;
1795 		}
1796 		else
1797 		{
1798 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, currentDC.CurrColorFill, currentDC.CurrColorStroke);
1799 			PageItem* ite = m_Doc->Items->at(z);
1800 			ite->PoLine = pointArray.copy();
1801 			finishItem(ite);
1802 		}
1803 	}
1804 }
1805 
handleFontDef(QDataStream & ds)1806 void SvmPlug::handleFontDef(QDataStream &ds)
1807 {
1808 	quint16 fontV, fontNL;
1809 	quint32 fontL;
1810 	ds >> fontV;
1811 	ds >> fontL;
1812 	ds >> fontNL;
1813 	QString fName = "";
1814 	QString fStyle = "";
1815 	for (uint i = 0; i < fontNL; ++i)
1816 	{
1817 		quint8  ch;
1818 		ds >> ch;
1819 		fName += char(ch);
1820 	}
1821 	ds >> fontNL;
1822 	for (uint i = 0; i < fontNL; ++i)
1823 	{
1824 		quint8  ch;
1825 		ds >> ch;
1826 		fStyle += char(ch);
1827 	}
1828 	quint32  width;
1829 	quint32  height;
1830 	ds >> width;
1831 	ds >> height;
1832 	qint16 ori;
1833 	quint16 tempu16;
1834 	quint8 tempu8;
1835 	ds >> currentDC.fontEnc;          // charset
1836 	ds >> tempu16;          // family
1837 	ds >> currentDC.fontPit;          // pitch
1838 	ds >> currentDC.fontWgt;          // weight
1839 	ds >> currentDC.fontUdl;          // underline
1840 	ds >> currentDC.fontStk;          // strikeout
1841 	ds >> currentDC.fontIta;          // italic
1842 	ds >> tempu16;          // language
1843 	ds >> currentDC.fontWdt;          // width
1844 	ds >> ori;          // orientation
1845 	ds >> tempu8;
1846 	ds >> currentDC.fontOul;
1847 	ds >> currentDC.fontShd;
1848 	ds >> currentDC.fontKer;
1849 	if (fontV > 1)
1850 	{
1851 		ds >> tempu8;
1852 		ds >> tempu16;
1853 		ds >> tempu8;
1854 		ds >> tempu16;
1855 	}
1856 	if (fontV > 2)
1857 		ds >> currentDC.fontOvl;
1858 	if (fName.length() < 4)
1859 		currentDC.fontName = "Arial";
1860 	else
1861 		currentDC.fontName = fName;
1862 	currentDC.fontSize = convertLogical2Pts(height);
1863 	currentDC.fontRotation = ori / 10.0;
1864 }
1865 
handleSmallText(QDataStream & ds)1866 void SvmPlug::handleSmallText(QDataStream &ds)
1867 {
1868 	QString  aTxt = "";
1869 	QPointF p1 = getPoint(ds);
1870 	if (currentDC.fontEnc == 0xFFFF)
1871 	{
1872 		quint32 numChar;
1873 		ds >> numChar;
1874 		for (uint i = 0; i < numChar; ++i)
1875 		{
1876 			quint16 ch;
1877 			ds >> ch;
1878 			aTxt += char(ch);
1879 		}
1880 	}
1881 	else
1882 	{
1883 		quint16 length;
1884 		ds >> length;
1885 		for (uint i = 0; i < length; ++i)
1886 		{
1887 			quint8 ch;
1888 			ds >> ch;
1889 			aTxt += char(ch);
1890 		}
1891 	}
1892 	if (aTxt.isEmpty())
1893 		return;
1894 	FPointArray textPath;
1895 	QPainterPath painterPath;
1896 	QFont font = QFont(currentDC.fontName, currentDC.fontSize);
1897 	font.setPixelSize(currentDC.fontSize);
1898 	font.setFixedPitch(currentDC.fontPit == PITCH_FIXED);
1899 	font.setItalic((currentDC.fontIta == ITALIC_OBLIQUE) || (currentDC.fontIta == ITALIC_NORMAL));
1900 	font.setBold(currentDC.fontWgt > WEIGHT_SEMIBOLD);
1901 	if (currentDC.fontWdt == WIDTH_ULTRA_CONDENSED)
1902 		font.setStretch(QFont::UltraCondensed);
1903 	else if (currentDC.fontWdt == WIDTH_EXTRA_CONDENSED)
1904 		font.setStretch(QFont::ExtraCondensed);
1905 	else if (currentDC.fontWdt == WIDTH_CONDENSED)
1906 		font.setStretch(QFont::Condensed);
1907 	else if (currentDC.fontWdt == WIDTH_SEMI_CONDENSED)
1908 		font.setStretch(QFont::SemiCondensed);
1909 	else if (currentDC.fontWdt == WIDTH_SEMI_EXPANDED)
1910 		font.setStretch(QFont::SemiExpanded);
1911 	else if (currentDC.fontWdt == WIDTH_EXPANDED)
1912 		font.setStretch(QFont::Expanded);
1913 	else if (currentDC.fontWdt == WIDTH_EXTRA_EXPANDED)
1914 		font.setStretch(QFont::ExtraExpanded);
1915 	else if (currentDC.fontWdt == WIDTH_ULTRA_EXPANDED)
1916 		font.setStretch(QFont::UltraExpanded);
1917 	font.setStrikeOut((currentDC.fontStk == STRIKEOUT_SINGLE) || (currentDC.fontStk == STRIKEOUT_DOUBLE) || (currentDC.fontStk > STRIKEOUT_DONTKNOW));
1918 	font.setUnderline((currentDC.fontUdl == UNDERLINE_SINGLE) || (currentDC.fontUdl == UNDERLINE_DOUBLE) || (currentDC.fontUdl == UNDERLINE_DOTTED) || (currentDC.fontUdl > UNDERLINE_DONTKNOW));
1919 	painterPath.addText(p1.x(), p1.y(), font, aTxt);
1920 	QFontMetricsF fm(font);
1921 	if (currentDC.textAlignment == ALIGN_TOP)
1922 		painterPath.translate(0, fm.ascent());
1923 	else if (currentDC.textAlignment == ALIGN_BOTTOM)
1924 		painterPath.translate(0, fm.descent());
1925 	textPath.fromQPainterPath(painterPath);
1926 	if (!textPath.empty())
1927 	{
1928 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorText, CommonStrings::None);
1929 		PageItem* ite = m_Doc->Items->at(z);
1930 		ite->PoLine = textPath.copy();
1931 		finishItem(ite);
1932 		if (currentDC.fontRotation != 0)
1933 			ite->setRotation(-currentDC.fontRotation, true);
1934 	}
1935 }
1936 
handleText(QDataStream & ds,quint16 version)1937 void SvmPlug::handleText(QDataStream &ds, quint16 version)
1938 {
1939 	QString  aTxt = "";
1940 	QPointF p1 = getPoint(ds);
1941 	if (currentDC.fontEnc == 0xFFFF)
1942 	{
1943 		quint32 numChar;
1944 		ds >> numChar;
1945 		for (uint i = 0; i < numChar; ++i)
1946 		{
1947 			quint16  ch;
1948 			ds >> ch;
1949 			aTxt += char(ch);
1950 		}
1951 	}
1952 	else
1953 	{
1954 		quint16 numChar;
1955 		ds >> numChar;
1956 		for (uint i = 0; i < numChar; ++i)
1957 		{
1958 			quint8  ch;
1959 			ds >> ch;
1960 			aTxt += char(ch);
1961 		}
1962 	}
1963 	if (aTxt.isEmpty())
1964 		return;
1965 	QList<double> dxTxt;
1966 	quint16 ind = 0;
1967 	quint16 len = 0;
1968 	if (version > 1)
1969 	{
1970 		quint32 dLen;
1971 		ds >> ind >> len;
1972 		ds >> dLen;
1973 		dxTxt.reserve(len);
1974 		for (quint16 aa = 0; aa < len; aa++)
1975 		{
1976 			quint32 ptyc;
1977 			ds >> ptyc;
1978 			dxTxt.append(convertLogical2Pts(ptyc));
1979 		}
1980 	}
1981 	QFont font = QFont(currentDC.fontName, currentDC.fontSize);
1982 	font.setPixelSize(currentDC.fontSize);
1983 	font.setFixedPitch(currentDC.fontPit == PITCH_FIXED);
1984 	font.setItalic((currentDC.fontIta == ITALIC_OBLIQUE) || (currentDC.fontIta == ITALIC_NORMAL));
1985 	font.setBold(currentDC.fontWgt > WEIGHT_SEMIBOLD);
1986 	if (currentDC.fontWdt == WIDTH_ULTRA_CONDENSED)
1987 		font.setStretch(QFont::UltraCondensed);
1988 	else if (currentDC.fontWdt == WIDTH_EXTRA_CONDENSED)
1989 		font.setStretch(QFont::ExtraCondensed);
1990 	else if (currentDC.fontWdt == WIDTH_CONDENSED)
1991 		font.setStretch(QFont::Condensed);
1992 	else if (currentDC.fontWdt == WIDTH_SEMI_CONDENSED)
1993 		font.setStretch(QFont::SemiCondensed);
1994 	else if (currentDC.fontWdt == WIDTH_SEMI_EXPANDED)
1995 		font.setStretch(QFont::SemiExpanded);
1996 	else if (currentDC.fontWdt == WIDTH_EXPANDED)
1997 		font.setStretch(QFont::Expanded);
1998 	else if (currentDC.fontWdt == WIDTH_EXTRA_EXPANDED)
1999 		font.setStretch(QFont::ExtraExpanded);
2000 	else if (currentDC.fontWdt == WIDTH_ULTRA_EXPANDED)
2001 		font.setStretch(QFont::UltraExpanded);
2002 	font.setStrikeOut((currentDC.fontStk == STRIKEOUT_SINGLE) || (currentDC.fontStk == STRIKEOUT_DOUBLE) || (currentDC.fontStk > STRIKEOUT_DONTKNOW));
2003 	font.setUnderline((currentDC.fontUdl == UNDERLINE_SINGLE) || (currentDC.fontUdl == UNDERLINE_DOUBLE) || (currentDC.fontUdl == UNDERLINE_DOTTED) || (currentDC.fontUdl > UNDERLINE_DONTKNOW));
2004 	QPainterPath painterPath;
2005 	if (len != 0)
2006 	{
2007 		double startX = p1.x();
2008 		for (quint32 a = 0; a < len; a++)
2009 		{
2010 			painterPath.addText(startX, p1.y(), font, aTxt.at(a + ind));
2011 			startX = p1.x() + dxTxt[a];
2012 		}
2013 	}
2014 	else
2015 		painterPath.addText(p1.x(), p1.y(), font, aTxt);
2016 	QFontMetricsF fm(font);
2017 	if (currentDC.textAlignment == ALIGN_TOP)
2018 		painterPath.translate(0, fm.ascent());
2019 	else if (currentDC.textAlignment == ALIGN_BOTTOM)
2020 		painterPath.translate(0, fm.descent());
2021 	FPointArray textPath;
2022 	textPath.fromQPainterPath(painterPath);
2023 	if (!textPath.empty())
2024 	{
2025 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorText, CommonStrings::None);
2026 		PageItem* ite = m_Doc->Items->at(z);
2027 		ite->PoLine = textPath.copy();
2028 		finishItem(ite);
2029 		if (currentDC.fontRotation != 0)
2030 			ite->setRotation(-currentDC.fontRotation, true);
2031 	}
2032 }
2033 
handleImage(QDataStream & ds,qint64 posi,quint32 totalSize)2034 void SvmPlug::handleImage(QDataStream &ds, qint64 posi, quint32 totalSize)
2035 {
2036 	// read Bitmap
2037 	QImage img;
2038 	img.load(ds.device(), "BMP");
2039 	img = img.convertToFormat(QImage::Format_ARGB32);
2040 	ds.device()->seek(posi + totalSize - 16);
2041 	QPointF p = getPoint(ds);
2042 	qint32 w, h;
2043 	ds >> w >> h;
2044 	double width = convertLogical2Pts(w);
2045 	double height = convertLogical2Pts(h);
2046 	int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX + p.x(), baseY + p.y(), width, height, 0, CommonStrings::None, CommonStrings::None);
2047 	PageItem* ite = m_Doc->Items->at(z);
2048 	finishItem(ite);
2049 	QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_svm_XXXXXX.png");
2050 	tempFile->setAutoRemove(false);
2051 	if (tempFile->open())
2052 	{
2053 		QString fileName = getLongPathName(tempFile->fileName());
2054 		if (!fileName.isEmpty())
2055 		{
2056 			tempFile->close();
2057 			img.save(fileName, "PNG");
2058 			ite->isInlineImage = true;
2059 			ite->isTempFile = true;
2060 			ite->AspectRatio = false;
2061 			ite->ScaleType   = false;
2062 			m_Doc->loadPict(fileName, ite);
2063 			ite->adjustPictScale();
2064 		}
2065 	}
2066 	delete tempFile;
2067 }
2068 
handleImageEX(QDataStream & ds,qint64 posi,quint32 totalSize)2069 void SvmPlug::handleImageEX(QDataStream &ds, qint64 posi, quint32 totalSize)
2070 {
2071 	// read Bitmap
2072 	QImage img;
2073 	img.load(ds.device(), "BMP");
2074 	img = img.convertToFormat(QImage::Format_ARGB32);
2075 	quint32 dummy;
2076 	quint8 dFlag;
2077 	ds >> dummy >> dummy;
2078 	ds >> dFlag;
2079 	// read Mask
2080 	QImage imgM;
2081 	imgM.load(ds.device(), "BMP");
2082 	imgM = imgM.convertToFormat(QImage::Format_ARGB32);
2083 	if (!imgM.isNull())
2084 	{
2085 		for (int ih = 0; ih < img.height(); ih++)
2086 		{
2087 			QRgb *src = (QRgb *)imgM.scanLine(ih);
2088 			QRgb *dst = (QRgb *)img.scanLine(ih);
2089 			for (int iw = 0; iw < img.width(); iw++)
2090 			{
2091 				*dst &= 0x00FFFFFF;
2092 				*dst++ |= (((0xFF - (*src++ & 0x000000FF)) << 24) & 0xFF000000);
2093 			}
2094 		}
2095 	}
2096 	ds.device()->seek(posi + totalSize - 16);
2097 	QPointF p = getPoint(ds);
2098 	qint32 w, h;
2099 	ds >> w >> h;
2100 	double width = convertLogical2Pts(w);
2101 	double height = convertLogical2Pts(h);
2102 	int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX + p.x(), baseY + p.y(), width, height, 0, CommonStrings::None, CommonStrings::None);
2103 	PageItem* ite = m_Doc->Items->at(z);
2104 	finishItem(ite);
2105 	QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_svm_XXXXXX.png");
2106 	tempFile->setAutoRemove(false);
2107 	if (tempFile->open())
2108 	{
2109 		QString fileName = getLongPathName(tempFile->fileName());
2110 		if (!fileName.isEmpty())
2111 		{
2112 			tempFile->close();
2113 			img.save(fileName, "PNG");
2114 			ite->isInlineImage = true;
2115 			ite->isTempFile = true;
2116 			ite->AspectRatio = false;
2117 			ite->ScaleType   = false;
2118 			m_Doc->loadPict(fileName, ite);
2119 			ite->adjustPictScale();
2120 		}
2121 	}
2122 	delete tempFile;
2123 }
2124 
handlePolygon(QDataStream & ds)2125 void SvmPlug::handlePolygon(QDataStream &ds)
2126 {
2127 	quint16   numPoints;
2128 	ds >> numPoints;
2129 	FPointArray poly = getPolyPoints(ds, numPoints, false);
2130 	if (poly.count() != 0)
2131 	{
2132 		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
2133 		PageItem* ite = m_Doc->Items->at(z);
2134 		ite->PoLine = poly.copy();
2135 		finishItem(ite, false);
2136 	}
2137 }
2138 
handlePolyPolygon(QDataStream & ds,quint16 version)2139 void SvmPlug::handlePolyPolygon(QDataStream &ds, quint16 version)
2140 {
2141 	FPointArray pointsPoly = getPolyPolygonPoints(ds, version);
2142 	if (pointsPoly.count() > 3)
2143 	{
2144 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
2145 		PageItem* ite = m_Doc->Items->at(z);
2146 		ite->PoLine = pointsPoly.copy();
2147 		finishItem(ite);
2148 	}
2149 }
2150 
handleTransparent(QDataStream & ds,quint16 version)2151 void SvmPlug::handleTransparent(QDataStream &ds, quint16 version)
2152 {
2153 	FPointArray pointsPoly = getPolyPolygonPoints(ds, version);
2154 	quint16 trans;
2155 	ds >> trans;
2156 	if (pointsPoly.count() > 3)
2157 	{
2158 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
2159 		PageItem* ite = m_Doc->Items->at(z);
2160 		ite->PoLine = pointsPoly.copy();
2161 		finishItem(ite);
2162 		ite->setFillTransparency(trans / 100.0);
2163 	}
2164 }
2165 
handleHatch(QDataStream & ds,quint16 version)2166 void SvmPlug::handleHatch(QDataStream &ds, quint16 version)
2167 {
2168 	FPointArray pointsPoly = getPolyPolygonPoints(ds, version);
2169 	quint16 ind, haStyle, haAngle, dum, colsR, colsG, colsB;
2170 	quint32 dLen, haDist;
2171 	ds >> ind >> dLen;
2172 	ds >> haStyle;
2173 	ds >> dum >> colsR >> colsG >> colsB;
2174 	ds >> haDist;
2175 	ds >> haAngle;
2176 	QColor colS = QColor(colsR >> 8, colsG >> 8, colsB >> 8, 255);
2177 	if (pointsPoly.count() > 3)
2178 	{
2179 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
2180 		PageItem* ite = m_Doc->Items->at(z);
2181 		ite->PoLine = pointsPoly.copy();
2182 		finishItem(ite);
2183 		QString haColor = handleColor(colS);
2184 		ite->setHatchParameters(haStyle, convertLogical2Pts(haDist), haAngle / 10.0, false, CommonStrings::None, haColor);
2185 		ite->GrType = Gradient_Hatch;
2186 	}
2187 }
2188 
handleGradient(QDataStream & ds)2189 void SvmPlug::handleGradient(QDataStream &ds)
2190 {
2191 	QPointF p1 = getPoint(ds);
2192 	QPointF p2 = getPoint(ds);
2193 	QRectF box = QRectF(p1, p2);
2194 	int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX, baseY, box.width(), box.height(), 0, currentDC.CurrColorFill, CommonStrings::None);
2195 	PageItem* ite = m_Doc->Items->at(z);
2196 	QTransform mm(1.0, 0.0, 0.0, 1.0, box.x(), box.y());
2197 	ite->PoLine.map(mm);
2198 	finishItem(ite);
2199 	commonGradient(ds, ite);
2200 }
2201 
handleGradientEX(QDataStream & ds,quint16 version)2202 void SvmPlug::handleGradientEX(QDataStream &ds, quint16 version)
2203 {
2204 	FPointArray pointsPoly = getPolyPolygonPoints(ds, version);
2205 	if (pointsPoly.count() > 3)
2206 	{
2207 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
2208 		PageItem* ite = m_Doc->Items->at(z);
2209 		ite->PoLine = pointsPoly.copy();
2210 		finishItem(ite);
2211 		commonGradient(ds, ite);
2212 	}
2213 }
2214 
commonGradient(QDataStream & ds,PageItem * ite)2215 void SvmPlug::commonGradient(QDataStream &ds, PageItem* ite)
2216 {
2217 	quint16 meStyle, mnAngle, mnBorder, mnOfsX, mnOfsY, gradientEndShade, gradientStartShade, mnStepCount;
2218 	quint16 ind;
2219 	quint32 dLen;
2220 	ds >> ind >> dLen;
2221 	ds >> meStyle;
2222 	quint16 dum, colsR, colsG, colsB;
2223 	quint16 coleR, coleG, coleB;
2224 	ds >> dum >> colsR >> colsG >> colsB;
2225 	ds >> dum >> coleR >> coleG >> coleB;
2226 	ds >> mnAngle >> mnBorder >> mnOfsX >> mnOfsY >> gradientStartShade >> gradientEndShade >> mnStepCount;
2227 	double gradientCenterX = mnOfsX / 100.0;
2228 	double gradientCenterY = mnOfsY / 100.0;
2229 	double gradientAngle = mnAngle / 10.0;
2230 	QColor colS = QColor(colsR >> 8, colsG >> 8, colsB >> 8, 255);
2231 	QColor colE = QColor(coleR >> 8, coleG >> 8, coleB >> 8, 255);
2232 	QString gradientEndColor = handleColor(colE);
2233 	QString gradientStartColor = handleColor(colS);
2234 	if (meStyle == GradientStyle_LINEAR)
2235 	{
2236 		double angle = (mnAngle / 10.0) + 90;
2237 		ite->fill_gradient = VGradient(VGradient::linear);
2238 		ite->fill_gradient.clearStops();
2239 		ite->fill_gradient.setRepeatMethod( VGradient::none );
2240 		ite->fill_gradient.addStop(colE, 0.0, 0.5, 1.0, gradientEndColor, gradientEndShade);
2241 		ite->fill_gradient.addStop(colS, 1.0 - (mnBorder / 100.0), 0.5, 1.0, gradientStartColor, gradientStartShade);
2242 		QLineF gradientVectorE;
2243 		gradientVectorE.setP1(QPointF(ite->width() / 2.0, ite->height() / 2.0));
2244 		gradientVectorE.setAngle(angle);
2245 		gradientVectorE.setLength(sqrt(ite->width() * ite->width() + ite->height() * ite->height()) / 2.0 + 1.0);
2246 		QPointF gradEnd = intersectBoundingRect(ite, gradientVectorE);
2247 		QLineF gradientVectorS;
2248 		gradientVectorS.setP1(QPointF(ite->width() / 2.0, ite->height() / 2.0));
2249 		gradientVectorS.setAngle(angle + 180);
2250 		gradientVectorS.setLength(sqrt(ite->width() * ite->width() + ite->height() * ite->height()) / 2.0 + 1.0);
2251 		QPointF gradStart = intersectBoundingRect(ite, gradientVectorS);
2252 		ite->setGradientVector(gradStart.x(), gradStart.y(), gradEnd.x(), gradEnd.y(), gradStart.x(), gradStart.y(), 1, 0);
2253 		ite->setGradientType(6);
2254 	}
2255 	else if (meStyle == GradientStyle_AXIAL)
2256 	{
2257 		double angle = gradientAngle + 90;
2258 		ite->fill_gradient = VGradient(VGradient::linear);
2259 		ite->fill_gradient.clearStops();
2260 		ite->fill_gradient.setRepeatMethod( VGradient::none );
2261 		ite->fill_gradient.addStop(colE, 0.0 + ((mnBorder / 100.0) / 2.0), 0.5, 1.0, gradientEndColor, gradientEndShade);
2262 		ite->fill_gradient.addStop(colS, 0.5, 0.5, 1.0, gradientStartColor, gradientStartShade);
2263 		ite->fill_gradient.addStop(colE, 1.0 - ((mnBorder / 100.0) / 2.0), 0.5, 1.0, gradientEndColor, gradientEndShade);
2264 		QLineF gradientVectorE;
2265 		gradientVectorE.setP1(QPointF(ite->width() / 2.0, ite->height() / 2.0));
2266 		gradientVectorE.setAngle(angle);
2267 		gradientVectorE.setLength(sqrt(ite->width() * ite->width() + ite->height() * ite->height()) / 2.0 + 1.0);
2268 		QPointF gradEnd = intersectBoundingRect(ite, gradientVectorE);
2269 		QLineF gradientVectorS;
2270 		gradientVectorS.setP1(QPointF(ite->width() / 2.0, ite->height() / 2.0));
2271 		gradientVectorS.setAngle(angle + 180);
2272 		gradientVectorS.setLength(sqrt(ite->width() * ite->width() + ite->height() * ite->height()) / 2.0 + 1.0);
2273 		QPointF gradStart = intersectBoundingRect(ite, gradientVectorS);
2274 		ite->setGradientVector(gradStart.x(), gradStart.y(), gradEnd.x(), gradEnd.y(), gradStart.x(), gradStart.y(), 1, 0);
2275 		ite->setGradientType(6);
2276 	}
2277 	else if (meStyle == GradientStyle_RADIAL)
2278 	{
2279 		ite->fill_gradient = VGradient(VGradient::radial);
2280 		ite->fill_gradient.clearStops();
2281 		ite->fill_gradient.setRepeatMethod( VGradient::none );
2282 		ite->fill_gradient.addStop(colE, 0.0, 0.5, 1.0, gradientEndColor, gradientEndShade);
2283 		ite->fill_gradient.addStop(colS, 1.0 - (mnBorder / 100.0), 0.5, 1.0, gradientStartColor, gradientStartShade);
2284 		ite->GrType = Gradient_Radial;
2285 		ite->GrStartX = ite->width() * gradientCenterX;
2286 		ite->GrStartY = ite->height()* gradientCenterY;
2287 		ite->GrFocalX = ite->width() * gradientCenterX;
2288 		ite->GrFocalY = ite->height()* gradientCenterY;
2289 		if (ite->width() >= ite->height())
2290 		{
2291 			ite->GrEndX = ite->width();
2292 			ite->GrEndY = ite->height() / 2.0;
2293 		}
2294 		else
2295 		{
2296 			ite->GrEndX = ite->width() / 2.0;
2297 			ite->GrEndY = ite->height();
2298 		}
2299 		ite->updateGradientVectors();
2300 	}
2301 	else if (meStyle == GradientStyle_ELLIPTICAL)
2302 	{
2303 		ite->fill_gradient = VGradient(VGradient::radial);
2304 		ite->fill_gradient.clearStops();
2305 		ite->fill_gradient.setRepeatMethod( VGradient::none );
2306 		ite->fill_gradient.addStop(colE, 0.0, 0.5, 1.0, gradientEndColor, gradientEndShade);
2307 		ite->fill_gradient.addStop(colS, 1.0 - (mnBorder / 100.0), 0.5, 1.0, gradientStartColor, gradientStartShade);
2308 		ite->GrType = Gradient_Radial;
2309 		ite->GrStartX = ite->width() * gradientCenterX;
2310 		ite->GrStartY = ite->height()* gradientCenterY;
2311 		ite->GrFocalX = ite->width() * gradientCenterX;
2312 		ite->GrFocalY = ite->height()* gradientCenterY;
2313 		if (ite->width() >= ite->height())
2314 		{
2315 			ite->GrEndX = ite->width();
2316 			ite->GrEndY = ite->height() / 2.0;
2317 		}
2318 		else
2319 		{
2320 			ite->GrEndX = ite->width() / 2.0;
2321 			ite->GrEndY = ite->height();
2322 		}
2323 		QLineF gradientVectorE = QLineF(ite->GrStartX, ite->GrStartY, ite->GrEndX, ite->GrEndY);
2324 		gradientVectorE.setAngle(gradientAngle);
2325 		ite->GrEndX = gradientVectorE.p2().x();
2326 		ite->GrEndY = gradientVectorE.p2().y();
2327 		ite->updateGradientVectors();
2328 	}
2329 	else if (meStyle == GradientStyle_SQUARE)
2330 	{
2331 		ite->fill_gradient = VGradient(VGradient::radial);
2332 		ite->fill_gradient.clearStops();
2333 		ite->fill_gradient.setRepeatMethod( VGradient::none );
2334 		ite->fill_gradient.addStop(colE, 0.0, 0.5, 1.0, gradientEndColor, gradientEndShade);
2335 		ite->fill_gradient.addStop(colS, 1.0 - (mnBorder / 100.0), 0.5, 1.0, gradientStartColor, gradientStartShade);
2336 		if (mnBorder != 0)
2337 			ite->fill_gradient.addStop(colS, 1.0, 0.5, 1.0, gradientStartColor, gradientStartShade);
2338 		FPoint cp = FPoint(ite->width() * gradientCenterX, ite->height()* gradientCenterY);
2339 		double gLen = qMin(ite->width(), ite->height()) / 2.0;
2340 		QLineF p1 = QLineF(cp.x(), cp.y(), cp.x() - gLen, cp.y() - gLen);
2341 		p1.setAngle(p1.angle() + gradientAngle);
2342 		QLineF p2 = QLineF(cp.x(), cp.y(), cp.x() + gLen, cp.y() - gLen);
2343 		p2.setAngle(p2.angle() + gradientAngle);
2344 		QLineF p3 = QLineF(cp.x(), cp.y(), cp.x() + gLen, cp.y() + gLen);
2345 		p3.setAngle(p3.angle() + gradientAngle);
2346 		QLineF p4 = QLineF(cp.x(), cp.y(), cp.x() - gLen, cp.y() + gLen);
2347 		p4.setAngle(p4.angle() + gradientAngle);
2348 		ite->setDiamondGeometry(FPoint(p1.p2().x(), p1.p2().y()), FPoint(p2.p2().x(), p2.p2().y()), FPoint(p3.p2().x(), p3.p2().y()), FPoint(p4.p2().x(), p4.p2().y()), cp);
2349 		ite->GrType = Gradient_Diamond;
2350 	}
2351 	else if (meStyle == GradientStyle_RECT)
2352 	{
2353 		ite->fill_gradient = VGradient(VGradient::radial);
2354 		ite->fill_gradient.clearStops();
2355 		ite->fill_gradient.setRepeatMethod( VGradient::none );
2356 		ite->fill_gradient.addStop(colE, 0.0, 0.5, 1.0, gradientEndColor, gradientEndShade);
2357 		ite->fill_gradient.addStop(colS, 1.0 - (mnBorder / 100.0), 0.5, 1.0, gradientStartColor, gradientStartShade);
2358 		if (mnBorder != 0)
2359 			ite->fill_gradient.addStop(colS, 1.0, 0.5, 1.0, gradientStartColor, gradientStartShade);
2360 		FPoint cp = FPoint(ite->width() * gradientCenterX, ite->height()* gradientCenterY);
2361 		double gLenW = ite->width() / 2.0;
2362 		double gLenH = ite->height() / 2.0;
2363 		QPointF P1 = QPointF(0.0, 0.0);
2364 		QPointF P2 = QPointF(ite->width(), 0.0);
2365 		QPointF P3 = QPointF(ite->width(), ite->height());
2366 		QPointF P4 = QPointF(0.0, ite->height());
2367 		QLineF L1 = QLineF(0.0, 0.0, ite->width(), 0.0);
2368 		L1.setAngle(-45);
2369 		QLineF LCW = QLineF(0.0, ite->height() / 2.0, ite->width(), ite->height() / 2.0);
2370 		QPointF P5;
2371 		LCW.intersects(L1, &P5);
2372 		QPointF P6 = QPointF(ite->width() - P5.x(), P5.y());
2373 		QPolygonF pPoints;
2374 		pPoints << P1 << P2 << P3 << P4 << P5 << P6;
2375 		QTransform mat;
2376 		pPoints.translate(-ite->width() / 2.0, -ite->height() / 2.0);
2377 		mat.translate(ite->width() * gradientCenterX, ite->height()* gradientCenterY);
2378 		mat.rotate(-gradientAngle);
2379 		mat.scale(1.0 - (mnBorder / 100.0), 1.0 - (mnBorder / 100.0));
2380 		pPoints = mat.map(pPoints);
2381 		P1 = pPoints[0];
2382 		P2 = pPoints[1];
2383 		P3 = pPoints[2];
2384 		P4 = pPoints[3];
2385 		P5 = pPoints[4];
2386 		P6 = pPoints[5];
2387 		QLineF p1 = QLineF(cp.x(), cp.y(), cp.x() - gLenW, cp.y() - gLenH);
2388 		p1.setAngle(p1.angle() + gradientAngle);
2389 		QLineF p2 = QLineF(cp.x(), cp.y(), cp.x() + gLenW, cp.y() - gLenH);
2390 		p2.setAngle(p2.angle() + gradientAngle);
2391 		QLineF p3 = QLineF(cp.x(), cp.y(), cp.x() + gLenW, cp.y() + gLenH);
2392 		p3.setAngle(p3.angle() + gradientAngle);
2393 		QLineF p4 = QLineF(cp.x(), cp.y(), cp.x() - gLenW, cp.y() + gLenH);
2394 		p4.setAngle(p4.angle() + gradientAngle);
2395 		ite->setDiamondGeometry(FPoint(p1.p2().x(), p1.p2().y()), FPoint(p2.p2().x(), p2.p2().y()), FPoint(p3.p2().x(), p3.p2().y()), FPoint(p4.p2().x(), p4.p2().y()), cp);
2396 		ite->GrType = Gradient_Diamond;
2397 	}
2398 }
2399 
handleColor(const QColor & col)2400 QString SvmPlug::handleColor(const QColor& col)
2401 {
2402 	ScColor tmp;
2403 	tmp.setRgbColor(col.red(), col.green(), col.blue());
2404 	tmp.setSpotColor(false);
2405 	tmp.setRegistrationColor(false);
2406 	QString tmpName = "FromSVM"+col.name().toUpper();
2407 	QString fNam = m_Doc->PageColors.tryAddColor(tmpName, tmp);
2408 	if (fNam == tmpName)
2409 		importedColors.append(tmpName);
2410 	return fNam;
2411 }
2412 
handleSetClipRegion(QDataStream & ds)2413 void SvmPlug::handleSetClipRegion(QDataStream &ds)
2414 {
2415 	quint32 dummy, mode, countRects;
2416 	ds >> dummy >> mode;
2417 	ds >> dummy >> dummy >> countRects;
2418 	ds >> dummy >> dummy >> dummy >> dummy >> dummy;
2419 }
2420 
handleComment(QDataStream & ds)2421 void SvmPlug::handleComment(QDataStream &ds)
2422 {
2423 	quint16 len;
2424 	ds >> len;
2425 	QString comment;
2426 	for (quint16 a = 0; a < len; a++)
2427 	{
2428 		quint8 cc;
2429 		ds >> cc;
2430 		comment.append(QChar(cc));
2431 	}
2432 	if (comment == "EMF_PLUS")
2433 	{
2434 		quint32 dcom, comLen;
2435 		ds >> dcom >> comLen;
2436 		handleEMFPlus(ds, comLen);
2437 	}
2438 	if (comment == "XGRAD_SEQ_BEGIN")
2439 		seen_XGRAD_SEQ_BEGIN = true;
2440 	if (comment == "XGRAD_SEQ_END")
2441 		seen_XGRAD_SEQ_BEGIN = false;
2442 }
2443 
handleEMFPlus(QDataStream & ds,quint32 dtaSize)2444 void SvmPlug::handleEMFPlus(QDataStream &ds, quint32 dtaSize)
2445 {
2446 	inEMFPlus = true;
2447 	quint16 id2, flagsHL;
2448 	quint8 flagsH, flagsL;
2449 	quint32 size2;
2450 	quint32 dummy;
2451 	quint32 dataSize;
2452 	qint32 xorg, yorg;
2453 	float m11, m12, m21, m22, dx, dy;
2454 	QTransform mm;
2455 	QByteArray emfRecords;
2456 	emfRecords.resize(dtaSize);
2457 	ds.readRawData(emfRecords.data(), dtaSize);
2458 	QDataStream dsEmf(emfRecords);
2459 	dsEmf.setByteOrder(QDataStream::LittleEndian);
2460 	dsEmf.setFloatingPointPrecision(QDataStream::SinglePrecision);
2461 	while (!dsEmf.atEnd())
2462 	{
2463 		qint64 posi2 = dsEmf.device()->pos();
2464 		dsEmf >> id2;
2465 		if ((id2 < 0x4000) || (id2 > 0x403A))
2466 			break;
2467 		dsEmf >> flagsHL;
2468 		flagsL = (flagsHL & 0xFF00) >> 8;
2469 		flagsH = (flagsHL & 0x00FF);
2470 		dsEmf >> size2 >> dataSize;
2471 		switch (id2)
2472 		{
2473 			case U_PMR_HEADER:
2474 				emfPlusDual = (flagsH == 1);
2475 				dsEmf >> dummy >> dummy;
2476 				dsEmf >> EmfPdpiX >> EmfPdpiY;
2477 				break;
2478 			case U_PMR_ENDOFFILE:
2479 				inEMFPlus = false;
2480 				break;
2481 			case U_PMR_GETDC:
2482 				if (emfPlusDual)
2483 					inEMFPlus = false;
2484 				break;
2485 			case U_PMR_OBJECT:
2486 				handleEMPObject(dsEmf, flagsH, flagsL, dataSize);
2487 				break;
2488 			case U_PMR_FILLRECTS:
2489 				handleEMFPFillRects(dsEmf, flagsL);
2490 				break;
2491 			case U_PMR_DRAWRECTS:
2492 				handleEMFPDrawRects(dsEmf, flagsL, flagsH);
2493 				break;
2494 			case U_PMR_FILLPOLYGON:
2495 				handleEMFPFillPolygon(dsEmf, flagsL);
2496 				break;
2497 			case U_PMR_DRAWLINES:
2498 				handleEMFPDrawLines(dsEmf, flagsL, flagsH);
2499 				break;
2500 			case U_PMR_FILLELLIPSE:
2501 				handleEMFPFillEllipse(dsEmf, flagsL);
2502 				break;
2503 			case U_PMR_DRAWELLIPSE:
2504 				handleEMFPDrawEllipse(dsEmf, flagsL, flagsH);
2505 				break;
2506 			case U_PMR_FILLPIE:
2507 				handleEMFPFillPie(dsEmf, flagsL);
2508 				break;
2509 			case U_PMR_DRAWPIE:
2510 				handleEMFPDrawPie(dsEmf, flagsL, flagsH);
2511 				break;
2512 			case U_PMR_DRAWARC:
2513 				handleEMFPDrawArc(dsEmf, flagsL, flagsH);
2514 				break;
2515 			case U_PMR_FILLREGION:
2516 				handleEMFPFillRegion(dsEmf, flagsL, flagsH);
2517 				break;
2518 			case U_PMR_FILLPATH:
2519 				handleEMFPFillPath(dsEmf, flagsL, flagsH);
2520 				break;
2521 			case U_PMR_DRAWPATH:
2522 				handleEMFPDrawPath(dsEmf, flagsH);
2523 				break;
2524 			case U_PMR_FILLCLOSEDCURVE:
2525 				handleEMFPFillClosedCurve(dsEmf, flagsL);
2526 				break;
2527 			case U_PMR_DRAWCLOSEDCURVE:
2528 				handleEMFPDrawClosedCurve(dsEmf, flagsL, flagsH);
2529 				break;
2530 			case U_PMR_DRAWCURVE:
2531 				handleEMFPDrawCurve(dsEmf, flagsL, flagsH);
2532 				break;
2533 			case U_PMR_DRAWBEZIERS:
2534 				handleEMFPDrawBezier(dsEmf, flagsL, flagsH);
2535 				break;
2536 			case U_PMR_DRAWIMAGE:
2537 				handleEMFPDrawImage(dsEmf, flagsL, flagsH);
2538 				break;
2539 			case U_PMR_DRAWIMAGEPOINTS:
2540 				handleEMFPDrawImagePoints(dsEmf, flagsL, flagsH);
2541 				break;
2542 			case U_PMR_DRAWSTRING:
2543 				handleEMFPDrawString(dsEmf, flagsL, flagsH);
2544 				break;
2545 			case U_PMR_SETRENDERINGORIGIN:
2546 				dsEmf >> xorg >> yorg;
2547 			//	currentDC.originEMFP = convertDevice2Pts(QPointF(xorg, yorg));
2548 				break;
2549 			case U_PMR_SETCOMPOSITINGMODE:
2550 				currentDC.alphaOn = (flagsH == 0);
2551 				break;
2552 			case U_PMR_SAVE:
2553 				dsEmf >> dummy;
2554 				dcStackEMP.insert(dummy, currentDC);
2555 				break;
2556 			case U_PMR_RESTORE:
2557 				dsEmf >> dummy;
2558 				if (dcStackEMP.contains(dummy))
2559 					currentDC = dcStackEMP[dummy];
2560 				break;
2561 			case U_PMR_SETWORLDTRANSFORM:
2562 				dsEmf >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
2563 				currentDC.m_WorldMapEMFP = QTransform(m11, m12, m21, m22, dx, dy);
2564 				break;
2565 			case U_PMR_RESETWORLDTRANSFORM:
2566 				currentDC.m_WorldMapEMFP = QTransform();
2567 				break;
2568 			case U_PMR_MULTIPLYWORLDTRANSFORM:
2569 				dsEmf >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
2570 				if (flagsL & 0x20)
2571 					currentDC.m_WorldMapEMFP = currentDC.m_WorldMapEMFP * QTransform(m11, m12, m21, m22, dx, dy);
2572 				else
2573 					currentDC.m_WorldMapEMFP = QTransform(m11, m12, m21, m22, dx, dy) * currentDC.m_WorldMapEMFP;
2574 				break;
2575 			case U_PMR_TRANSLATEWORLDTRANSFORM:
2576 				dsEmf >> dx >> dy;
2577 				mm = QTransform();
2578 				mm.translate(dx, dy);
2579 				if (flagsL & 0x20)
2580 					currentDC.m_WorldMapEMFP = currentDC.m_WorldMapEMFP * mm;
2581 				else
2582 					currentDC.m_WorldMapEMFP = mm * currentDC.m_WorldMapEMFP;
2583 				break;
2584 			case U_PMR_SCALEWORLDTRANSFORM:
2585 				dsEmf >> m11 >> m12;
2586 				mm = QTransform();
2587 				mm.scale(m11, m12);
2588 				if (flagsL & 0x20)
2589 					currentDC.m_WorldMapEMFP = currentDC.m_WorldMapEMFP * mm;
2590 				else
2591 					currentDC.m_WorldMapEMFP = mm * currentDC.m_WorldMapEMFP;
2592 				break;
2593 			case U_PMR_ROTATEWORLDTRANSFORM:
2594 				dsEmf >> m11;
2595 				mm = QTransform();
2596 				mm.rotate(m11);
2597 				if (flagsL & 0x20)
2598 					currentDC.m_WorldMapEMFP = currentDC.m_WorldMapEMFP * mm;
2599 				else
2600 					currentDC.m_WorldMapEMFP = mm * currentDC.m_WorldMapEMFP;
2601 				break;
2602 			case U_PMR_SETPAGETRANSFORM:
2603 				currentDC.emfPlusUnit = flagsH;
2604 				dsEmf >> emfPlusScale;
2605 				break;
2606 			case U_PMR_OFFSETCLIP:
2607 				if (!currentDC.clipPath.isEmpty())
2608 				{
2609 					double dx = getEMFPDistance(dsEmf, false);
2610 					double dy = getEMFPDistance(dsEmf, false);
2611 					currentDC.clipPath.translate(dx, dy);
2612 				}
2613 				break;
2614 			case U_PMR_RESETCLIP:
2615 				currentDC.clipPath.resize(0);
2616 				currentDC.clipPath.svgInit();
2617 				break;
2618 			case U_PMR_SETCLIPRECT:
2619 				handleEMFPSetClipRect(dsEmf, flagsL);
2620 				break;
2621 			case U_PMR_SETCLIPREGION:
2622 				handleEMFPSetClipRegion(dsEmf, flagsL, flagsH);
2623 				break;
2624 			case U_PMR_SETCLIPPATH:
2625 				handleEMFPSetClipPath(dsEmf, flagsL, flagsH);
2626 				break;
2627 			case U_PMR_DRAWDRIVERSTRING:
2628 				handleEMFPDrawDriverString(dsEmf, flagsL, flagsH);
2629 				break;
2630 			case U_PMR_STROKEFILLPATH:
2631 				{
2632 					qDebug() << "\tU_PMR_STROKEFILLPATH";
2633 				}
2634 				break;
2635 			case U_PMR_SERIALIZABLEOBJECT:
2636 				handleEMFPSerializableObject(dsEmf);
2637 				break;
2638 			case U_PMR_BEGINCONTAINER:
2639 			case U_PMR_BEGINCONTAINERNOPARAMS:
2640 			case U_PMR_ENDCONTAINER:
2641 			case U_PMR_COMMENT:
2642 			case U_PMR_SETANTIALIASMODE:
2643 			case U_PMR_SETTEXTRENDERINGHINT:
2644 			case U_PMR_SETTEXTCONTRAST:
2645 			case U_PMR_SETINTERPOLATIONMODE:
2646 			case U_PMR_SETPIXELOFFSETMODE:
2647 			case U_PMR_SETCOMPOSITINGQUALITY:
2648 			case U_PMR_SETTSGRAPHICS:
2649 			case U_PMR_SETTSCLIP:
2650 			case U_PMR_MULTIFORMATSTART:
2651 			case U_PMR_MULTIFORMATSECTION:
2652 			case U_PMR_MULTIFORMATEND:
2653 			case U_PMR_CLEAR:
2654 			//	qDebug() << "\tUnsupported Op-Code" << id2;
2655 				break;
2656 			default:
2657 				qDebug() << "\tUnknown Op-Code" << id2;
2658 				break;
2659 		}
2660 		dsEmf.device()->seek(posi2 + size2);
2661 	}
2662 }
2663 
handleEMPObject(QDataStream & ds,quint8 flagsH,quint8 flagsL,quint32 dataSize)2664 void SvmPlug::handleEMPObject(QDataStream &ds, quint8 flagsH, quint8 flagsL, quint32 dataSize)
2665 {
2666 	quint16 id = flagsH;
2667 	quint16 type = flagsL & 0x7F;
2668 	quint32 totalSize = 0;
2669 	bool cont = (flagsL & 0x80);
2670 	bool first = true;
2671 	if (!cont)
2672 	{
2673 		m_ObjSize = 0;
2674 		m_currObjSize = 0;
2675 	}
2676 	else
2677 	{
2678 		if (m_ObjSize != 0)
2679 			first = false;
2680 		if (m_objID != id)
2681 			first = true;
2682 		ds >> totalSize;
2683 		m_ObjSize = totalSize;
2684 	}
2685 	if (type == U_OT_Brush)
2686 		m_currObjSize += handleEMPBrush(ds, id, first, cont, dataSize);
2687 	else if (type == U_OT_Pen)
2688 		handleEMPPen(ds, id);
2689 	else if (type == U_OT_Path)
2690 		handleEMPPath(ds, id);
2691 	else if (type == U_OT_Region)
2692 		handleEMPRegion(ds, id);
2693 	else if (type == U_OT_Image)
2694 	{
2695 		quint32 lenS = 0;
2696 		if (cont)
2697 			lenS = 4;
2698 		m_currObjSize += handleEMPImage(ds, id, first, cont, dataSize - lenS);
2699 	}
2700 	else if (type == U_OT_Font)
2701 		handleEMPFont(ds, id);
2702 	else if (type == U_OT_StringFormat)
2703 		handleEMPSFormat(ds, id);
2704 	else if (type == U_OT_CustomLineCap)
2705 		handleEMPLineCap(ds, id);
2706 	if (m_currObjSize >= totalSize)
2707 	{
2708 		m_ObjSize = 0;
2709 		m_currObjSize = 0;
2710 	}
2711 	m_objID = id;
2712 }
2713 
handleEMPBrush(QDataStream & ds,quint16 id,bool first,bool cont,quint32 dataSize)2714 quint32 SvmPlug::handleEMPBrush(QDataStream &ds, quint16 id, bool first, bool cont, quint32 dataSize)
2715 {
2716 	emfStyle sty;
2717 	quint32 retVal = 0;
2718 	if (!first)
2719 	{
2720 		quint32 lenS = 0;
2721 		if (cont)
2722 			lenS = 4;
2723 		retVal += getImageData(ds, id, first, cont, dataSize - lenS, sty);
2724 		return retVal;
2725 	}
2726 	quint32 dummy;
2727 	quint32 brushType;
2728 	ds >> dummy;
2729 	ds >> brushType;
2730 	if (brushType == U_BT_SolidColor)
2731 	{
2732 		quint32 brush;
2733 		ds >> brush;
2734 		quint8 r = brush & 0xFF;
2735 		quint8 g = (brush >> 8) & 0xFF;
2736 		quint8 b = (brush >> 16) & 0xFF;
2737 		quint8 a = (brush >> 24) & 0xFF;
2738 		QColor col(b, g, r, a);
2739 		sty.brushColor = handleColor(col);
2740 		sty.penColor = CommonStrings::None;
2741 		sty.fillTrans = 1.0 - col.alphaF();
2742 		sty.brushStyle = U_BT_SolidColor;
2743 		sty.hatchStyle = 0;
2744 	}
2745 	else if (brushType == U_BT_HatchFill)
2746 	{
2747 		quint32 hatchStyle, fgColor, bgColor;
2748 		ds >> hatchStyle >> fgColor >> bgColor;
2749 		quint8 r = fgColor & 0xFF;
2750 		quint8 g = (fgColor >> 8) & 0xFF;
2751 		quint8 b = (fgColor >> 16) & 0xFF;
2752 		quint8 a = (fgColor >> 24) & 0xFF;
2753 		QColor col(b, g, r, a);
2754 		r = bgColor & 0xFF;
2755 		g = (bgColor >> 8) & 0xFF;
2756 		b = (bgColor >> 16) & 0xFF;
2757 		a = (bgColor >> 24) & 0xFF;
2758 		QColor col2(b, g, r, a);
2759 		sty.brushColor = handleColor(col);
2760 		sty.fillTrans = 1.0 - col.alphaF();
2761 		sty.penColor = handleColor(col2);
2762 		sty.penTrans = 1.0 - col2.alphaF();
2763 		if (sty.penTrans > 0.5)
2764 			sty.penColor = CommonStrings::None;
2765 		sty.hatchStyle = hatchStyle;
2766 		sty.brushStyle = U_BT_HatchFill;
2767 	}
2768 	else if (brushType == U_BT_TextureFill)
2769 	{
2770 		if (first)
2771 		{
2772 			quint32 lenS = 16;
2773 			if (cont)
2774 				lenS += 4;
2775 			quint32 gFlags, wrap;
2776 			ds >> gFlags >> wrap;
2777 			bool mTrans = (gFlags & 0x00000002);
2778 			if (mTrans)
2779 			{
2780 				lenS += 24;
2781 				float m11, m12, m21, m22, dx, dy;
2782 				ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
2783 				QLineF lin = QLineF(0, 0, 1, 0);
2784 				lin = QTransform(m11, m12, m21, m22, dx, dy).map(lin);
2785 				sty.gradientAngle = lin.angle();
2786 			}
2787 			sty.brushStyle = U_BT_TextureFill;
2788 			sty.patternMode = wrap;
2789 			retVal = getImageData(ds, id, first, cont, dataSize - lenS, sty);
2790 		}
2791 	}
2792 	else if (brushType == U_BT_PathGradient)
2793 	{
2794 		quint32 gFlags, wrap, startCol, cCount, endCol;
2795 		ds >> gFlags >> wrap;
2796 		ds >> startCol;
2797 		QPointF p1 = getEMFPPoint(ds, false);
2798 		ds >> cCount;
2799 		for (quint32 a = 0; a < cCount; a++)
2800 		{
2801 			ds >> endCol;
2802 		}
2803 		bool mPath  = (gFlags & 0x00000001);
2804 		bool mTrans = (gFlags & 0x00000002);
2805 		bool preCol = (gFlags & 0x00000004);
2806 		bool blFacH = (gFlags & 0x00000008);
2807 		sty.brushStyle = U_BT_PathGradient;
2808 		sty.gradientStart = p1;
2809 		if (mPath)
2810 		{
2811 			quint32 pCount;
2812 			ds >> pCount;
2813 			qint64 ppos = ds.device()->pos();
2814 			FPointArray polyline = getEMPPathData(ds);
2815 			sty.gradientPath = polyline.copy();
2816 			ds.device()->seek(ppos + pCount);
2817 		}
2818 		else
2819 		{
2820 			quint32 pCount;
2821 			ds >> pCount;
2822 			QPolygonF points = getEMFPCurvePoints(ds, 0, pCount);
2823 			QPainterPath path;
2824 			GdipAddPathClosedCurve(path, points, 0);
2825 			FPointArray polyline;
2826 			polyline.fromQPainterPath(path, true);
2827 			sty.gradientPath = polyline.copy();
2828 		}
2829 		if (mTrans)
2830 		{
2831 			float m11, m12, m21, m22, dx, dy;
2832 			ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
2833 			QLineF lin = QLineF(0, 0, 1, 0);
2834 			lin = QTransform(m11, m12, m21, m22, dx, dy).map(lin);
2835 			sty.gradientAngle = lin.angle() + 45;
2836 		}
2837 		if (blFacH && !preCol)
2838 		{
2839 			quint32 cCount;
2840 			ds >> cCount;
2841 			ds.skipRawData(8 * cCount);
2842 		}
2843 		sty.gradient = VGradient(VGradient::linear);
2844 		sty.gradient.clearStops();
2845 		sty.gradient.setRepeatMethod(VGradient::pad);
2846 		if (preCol)
2847 		{
2848 			quint32 cCount;
2849 			ds >> cCount;
2850 			QList<float> posit;
2851 			QList<quint32> facts;
2852 			posit.reserve(cCount);
2853 			facts.reserve(cCount);
2854 			for (quint32 c = 0; c < cCount; c++)
2855 			{
2856 				float fact;
2857 				ds >> fact;
2858 				posit.append(fact);
2859 			}
2860 			for (quint32 c = 0; c < cCount; c++)
2861 			{
2862 				quint32 fact;
2863 				ds >> fact;
2864 				facts.append(fact);
2865 			}
2866 			for (quint32 c = 0; c < cCount; c++)
2867 			{
2868 				quint8 r = facts[c] & 0xFF;
2869 				quint8 g = (facts[c] >> 8) & 0xFF;
2870 				quint8 b = (facts[c] >> 16) & 0xFF;
2871 				quint8 a = (facts[c] >> 24) & 0xFF;
2872 				QColor col(b, g, r, a);
2873 				QString stColor = handleColor(col);
2874 				sty.gradient.addStop(col, 1.0 - posit[c], 0.5, col.alphaF(), stColor, 100);
2875 			}
2876 		}
2877 		else
2878 		{
2879 			quint8 r = startCol & 0xFF;
2880 			quint8 g = (startCol >> 8) & 0xFF;
2881 			quint8 b = (startCol >> 16) & 0xFF;
2882 			quint8 a = (startCol >> 24) & 0xFF;
2883 			QColor col(b, g, r, a);
2884 			QString stColor = handleColor(col);
2885 			sty.gradient.addStop(col, 0.0, 0.5, col.alphaF(), stColor, 100);
2886 			r = endCol & 0xFF;
2887 			g = (endCol >> 8) & 0xFF;
2888 			b = (endCol >> 16) & 0xFF;
2889 			a = (endCol >> 24) & 0xFF;
2890 			QColor col2(b, g, r, a);
2891 			QString enColor = handleColor(col2);
2892 			sty.gradient.addStop(col2, 1.0, 0.5, col2.alphaF(), enColor, 100);
2893 		}
2894 	}
2895 	else if (brushType == U_BT_LinearGradient)
2896 	{
2897 		quint32 gFlags, wrap, startCol, endCol;
2898 		ds >> gFlags >> wrap;
2899 		QPolygonF rect = getEMFPRect(ds, false);
2900 		ds >> startCol >> endCol;
2901 		ds >> dummy >> dummy;
2902 		bool mTrans = (gFlags & 0x00000002);
2903 		bool preCol = (gFlags & 0x00000004);
2904 		bool blFacH = (gFlags & 0x00000008);
2905 		bool blFacV = (gFlags & 0x00000010);
2906 		sty.brushStyle = U_BT_LinearGradient;
2907 		sty.gradientStart = rect[0];
2908 		sty.gradientEnd = rect[2];
2909 		if (mTrans)
2910 		{
2911 			float m11, m12, m21, m22, dx, dy;
2912 			ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
2913 			QLineF lin = QLineF(rect[0], rect[2]);
2914 			lin = QTransform(m11, m12, m21, m22, dx, dy).map(lin);
2915 			sty.gradientAngle = lin.angle() + 45;
2916 		}
2917 		if ((blFacH || blFacV) && !preCol)
2918 		{
2919 			quint32 cCount;
2920 			ds >> cCount;
2921 			ds.skipRawData(8 * cCount);
2922 		}
2923 		sty.gradient = VGradient(VGradient::linear);
2924 		sty.gradient.clearStops();
2925 		sty.gradient.setRepeatMethod(VGradient::pad);
2926 		if (preCol)
2927 		{
2928 			quint32 cCount;
2929 			ds >> cCount;
2930 			QList<float> posit;
2931 			QList<quint32> facts;
2932 			posit.reserve(cCount);
2933 			facts.reserve(cCount);
2934 			for (quint32 c = 0; c < cCount; c++)
2935 			{
2936 				float fact;
2937 				ds >> fact;
2938 				posit.append(fact);
2939 			}
2940 			for (quint32 c = 0; c < cCount; c++)
2941 			{
2942 				quint32 fact;
2943 				ds >> fact;
2944 				facts.append(fact);
2945 			}
2946 			for (quint32 c = 0; c < cCount; c++)
2947 			{
2948 				quint8 r = facts[c] & 0xFF;
2949 				quint8 g = (facts[c] >> 8) & 0xFF;
2950 				quint8 b = (facts[c] >> 16) & 0xFF;
2951 				quint8 a = (facts[c] >> 24) & 0xFF;
2952 				QColor col(b, g, r, a);
2953 				QString stColor = handleColor(col);
2954 				sty.gradient.addStop(col, posit[c], 0.5, col.alphaF(), stColor, 100);
2955 			}
2956 		}
2957 		else
2958 		{
2959 			quint8 r = startCol & 0xFF;
2960 			quint8 g = (startCol >> 8) & 0xFF;
2961 			quint8 b = (startCol >> 16) & 0xFF;
2962 			quint8 a = (startCol >> 24) & 0xFF;
2963 			QColor col(b, g, r, a);
2964 			QString stColor = handleColor(col);
2965 			sty.gradient.addStop(col, 1.0, 0.5, col.alphaF(), stColor, 100);
2966 			r = endCol & 0xFF;
2967 			g = (endCol >> 8) & 0xFF;
2968 			b = (endCol >> 16) & 0xFF;
2969 			a = (endCol >> 24) & 0xFF;
2970 			QColor col2(b, g, r, a);
2971 			QString enColor = handleColor(col2);
2972 			sty.gradient.addStop(col2, 0.0, 0.5, col2.alphaF(), enColor, 100);
2973 		}
2974 	}
2975 	sty.styType = U_OT_Brush;
2976 	emfStyleMapEMP.insert(id, sty);
2977 	return retVal;
2978 }
2979 
handleEMPPen(QDataStream & ds,quint16 id)2980 void SvmPlug::handleEMPPen(QDataStream &ds, quint16 id)
2981 {
2982 	emfStyle sty;
2983 	quint32 dummy;
2984 	quint32 penData, penUnit;
2985 	float penWidth;
2986 	ds >> dummy;
2987 	ds >> dummy;
2988 	ds >> penData >> penUnit >> penWidth;
2989 	sty.penCap = Qt::RoundCap;
2990 	sty.penJoin = Qt::RoundJoin;
2991 	sty.penStyle = Qt::SolidLine;
2992 	if (penData & U_PD_Transform)
2993 	{
2994 		float m11, m12, m21, m22, dx, dy;
2995 		ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
2996 	}
2997 	if (penData & U_PD_StartCap)
2998 	{
2999 		qint32 startCap;
3000 		ds >> startCap;
3001 		if (startCap == U_LCT_Square)
3002 			sty.penCap = Qt::SquareCap;
3003 		if (startCap == U_LCT_Flat)
3004 			sty.penCap = Qt::FlatCap;
3005 		else if (startCap == U_LCT_Round)
3006 			sty.penCap = Qt::RoundCap;
3007 		else
3008 			sty.penCap = Qt::RoundCap;
3009 	}
3010 	if (penData & U_PD_EndCap)
3011 	{
3012 		qint32 endCap;
3013 		ds >> endCap;
3014 		if (endCap == U_LCT_Square)
3015 			sty.penCap = Qt::SquareCap;
3016 		if (endCap == U_LCT_Flat)
3017 			sty.penCap = Qt::FlatCap;
3018 		else if (endCap == U_LCT_Round)
3019 			sty.penCap = Qt::RoundCap;
3020 		else
3021 			sty.penCap = Qt::RoundCap;
3022 	}
3023 	if (penData & U_PD_Join)
3024 	{
3025 		qint32 join;
3026 		ds >> join;
3027 		if (join == U_LJT_Bevel)
3028 			sty.penJoin = Qt::BevelJoin;
3029 		else if (join == U_LJT_Miter)
3030 			sty.penJoin = Qt::MiterJoin;
3031 		else if (join == U_LJT_Round)
3032 			sty.penJoin = Qt::RoundJoin;
3033 		else
3034 			sty.penJoin = Qt::RoundJoin;
3035 	}
3036 	if (penData & U_PD_MiterLimit)
3037 	{
3038 		float data;
3039 		ds >> data;
3040 	}
3041 	if (penData & U_PD_LineStyle)
3042 	{
3043 		qint32 penStyle;
3044 		ds >> penStyle;
3045 		if ((penStyle) == U_LS_Solid)
3046 			sty.penStyle = Qt::SolidLine;
3047 		else if ((penStyle) == U_LS_Dash)
3048 			sty.penStyle = Qt::DashLine;
3049 		else if ((penStyle) == U_LS_Dot)
3050 			sty.penStyle = Qt::DotLine;
3051 		else if ((penStyle) == U_LS_DashDot)
3052 			sty.penStyle = Qt::DashDotLine;
3053 		else if ((penStyle) == U_LS_DashDotDot)
3054 			sty.penStyle = Qt::DashDotDotLine;
3055 		else if ((penStyle) == 5)
3056 			sty.penStyle = Qt::SolidLine;
3057 		else
3058 			sty.penStyle = Qt::SolidLine;
3059 	}
3060 	if (penData & U_PD_DLCap)
3061 	{
3062 		qint32 data;
3063 		ds >> data;
3064 	}
3065 	if (penData & U_PD_DLOffset)
3066 	{
3067 		float data;
3068 		ds >> data;
3069 		sty.dashOffset = data;
3070 	}
3071 	if (penData & U_PD_DLData)
3072 	{
3073 		quint32 data;
3074 		ds >> data;
3075 		for (quint32 a = 0; a < data; a++)
3076 		{
3077 			float dData;
3078 			ds >> dData;
3079 			sty.dashArray.append(dData);
3080 		}
3081 	}
3082 	if (penData & U_PD_NonCenter)
3083 	{
3084 		float data;
3085 		ds >> data;
3086 	//	qDebug() << QString("\n\t\t\tPenAlignment");
3087 	}
3088 	if (penData & U_PD_CLData)
3089 	{
3090 		quint32 data;
3091 		ds >> data;
3092 		for (quint32 a = 0; a < data; a++)
3093 		{
3094 			float dData;
3095 			ds >> dData;
3096 		}
3097 	//	qDebug() << QString("\n\t\t\tCompoundLine");
3098 	}
3099 	if (penData & U_PD_CustomStartCap)
3100 	{
3101 		quint32 data;
3102 		ds >> data;
3103 		ds.skipRawData(data);
3104 	//	qDebug() << QString("\n\t\t\tCustomStartCap");
3105 	}
3106 	if (penData & U_PD_CustomEndCap)
3107 	{
3108 		quint32 data;
3109 		ds >> data;
3110 		ds.skipRawData(data);
3111 	//	qDebug() << QString("\n\t\t\tCustomEndCap");
3112 	}
3113 	quint32 brushType;
3114 	ds >> dummy;
3115 	ds >> brushType;
3116 	if (brushType == U_BT_SolidColor)
3117 	{
3118 		quint32 brush;
3119 		ds >> brush;
3120 		quint8 r = brush & 0xFF;
3121 		quint8 g = (brush >> 8) & 0xFF;
3122 		quint8 b = (brush >> 16) & 0xFF;
3123 		quint8 a = (brush >> 24) & 0xFF;
3124 		QColor col(b, g, r, a);
3125 		sty.penColor = handleColor(col);
3126 		sty.penTrans = 1.0 - col.alphaF();
3127 	}
3128 	else
3129 		sty.penColor = "Black";
3130 	sty.styType = U_OT_Pen;
3131 	sty.brushColor = CommonStrings::None;
3132 	if ((penUnit == U_UT_World) || (penUnit == U_UT_Display))
3133 		sty.penWidth = convertEMFPLogical2Pts(penWidth, currentDC.emfPlusUnit);
3134 	else
3135 		sty.penWidth = convertEMFPLogical2Pts(penWidth, penUnit);
3136 	emfStyleMapEMP.insert(id, sty);
3137 }
3138 
handleEMPPath(QDataStream & ds,quint16 id)3139 void SvmPlug::handleEMPPath(QDataStream &ds, quint16 id)
3140 {
3141 	FPointArray polyline = getEMPPathData(ds);
3142 	if (polyline.count() > 0)
3143 	{
3144 		emfStyle sty;
3145 		sty.styType = U_OT_Path;
3146 		sty.Coords = polyline.copy();
3147 		emfStyleMapEMP.insert(id, sty);
3148 	}
3149 }
3150 
handleEMPRegion(QDataStream & ds,quint16 id)3151 void SvmPlug::handleEMPRegion(QDataStream &ds, quint16 id)
3152 {
3153 	emfStyle sty;
3154 	sty.styType = U_OT_Region;
3155 	quint32 nPoints, rgnType, dummy;
3156 	ds >> dummy;
3157 	ds >> nPoints;
3158 	ds >> rgnType;
3159 	if (rgnType <= U_RNDT_Complement)
3160 	{
3161 		QPainterPath pathL, pathR, resultPath;
3162 		quint32 rgnTypeL, rgnTypeR;
3163 		ds >> rgnTypeL;
3164 		if (rgnTypeL == U_RNDT_Rect)
3165 		{
3166 			QPolygonF rect = getEMFPRect(ds, false);
3167 			pathL.addPolygon(rect);
3168 		}
3169 		else if (rgnTypeL == U_RNDT_Path)
3170 		{
3171 			quint32 rLen;
3172 			ds >> rLen;
3173 			qint64 ppos = ds.device()->pos();
3174 			FPointArray polyline = getEMPPathData(ds);
3175 			ds.device()->seek(ppos + rLen);
3176 			pathL = polyline.toQPainterPath(true);
3177 		}
3178 		ds >> rgnTypeR;
3179 		if (rgnTypeR == U_RNDT_Rect)
3180 		{
3181 			QPolygonF rect = getEMFPRect(ds, false);
3182 			pathR.addPolygon(rect);
3183 		}
3184 		else if (rgnTypeR == U_RNDT_Path)
3185 		{
3186 			quint32 rLen;
3187 			ds >> rLen;
3188 			qint64 ppos = ds.device()->pos();
3189 			FPointArray polyline = getEMPPathData(ds);
3190 			ds.device()->seek(ppos + rLen);
3191 			pathR = polyline.toQPainterPath(true);
3192 		}
3193 		if (rgnType == U_RNDT_And)
3194 			resultPath = pathL.intersected(pathR);
3195 		else if (rgnType == U_RNDT_Or)
3196 			resultPath = pathL.united(pathR);
3197 		else if (rgnType == U_RNDT_Exclude)
3198 		{
3199 			QPainterPath part1 = pathL.subtracted(pathR);
3200 			QPainterPath part2 = pathR.subtracted(pathL);
3201 			resultPath.addPath(part1);
3202 			resultPath.addPath(part2);
3203 		}
3204 		if (!resultPath.isEmpty())
3205 		{
3206 			FPointArray polyline;
3207 			polyline.resize(0);
3208 			polyline.fromQPainterPath(resultPath, true);
3209 			polyline.svgClosePath();
3210 			sty.Coords = polyline.copy();
3211 			emfStyleMapEMP.insert(id, sty);
3212 		}
3213 	}
3214 	else
3215 	{
3216 		if (rgnType == U_RNDT_Rect)
3217 		{
3218 			QPolygonF rect = getEMFPRect(ds, false);
3219 			FPointArray polyline;
3220 			polyline.resize(0);
3221 			polyline.svgInit();
3222 			polyline.svgMoveTo(rect[0].x(), rect[0].y());
3223 			polyline.svgLineTo(rect[1].x(), rect[1].y());
3224 			polyline.svgLineTo(rect[2].x(), rect[2].y());
3225 			polyline.svgLineTo(rect[3].x(), rect[3].y());
3226 			polyline.svgClosePath();
3227 			sty.Coords = polyline.copy();
3228 			emfStyleMapEMP.insert(id, sty);
3229 		}
3230 		else if (rgnType == U_RNDT_Path)
3231 		{
3232 			quint32 rLen;
3233 			ds >> rLen;
3234 			qint64 ppos = ds.device()->pos();
3235 			FPointArray polyline = getEMPPathData(ds);
3236 			ds.device()->seek(ppos + rLen);
3237 			sty.Coords = polyline.copy();
3238 			emfStyleMapEMP.insert(id, sty);
3239 		}
3240 	}
3241 }
3242 
handleEMPImage(QDataStream & ds,quint16 id,bool first,bool cont,quint32 dataSize)3243 quint32 SvmPlug::handleEMPImage(QDataStream &ds, quint16 id, bool first, bool cont, quint32 dataSize)
3244 {
3245 	emfStyle sty;
3246 	sty.styType = U_OT_Image;
3247 	quint32 retVal = getImageData(ds, id, first, cont, dataSize, sty);
3248 	if (first)
3249 		emfStyleMapEMP.insert(id, sty);
3250 	return retVal;
3251 }
3252 
getImageData(QDataStream & ds,quint16 id,bool first,bool cont,quint32 dataSize,emfStyle & sty)3253 quint32 SvmPlug::getImageData(QDataStream &ds, quint16 id, bool first, bool cont, quint32 dataSize, emfStyle &sty)
3254 {
3255 	quint32 retVal = 0;
3256 	if (first)
3257 	{
3258 		quint32 dataV, dummy;
3259 		ds >> dummy;
3260 		ds >> dataV;
3261 		if (dataV == U_IDT_Bitmap)
3262 		{
3263 			qint32 w, h;
3264 			quint32 pixelFormat, imgType;
3265 			ds >> w >> h >> dummy;
3266 			ds >> pixelFormat >> imgType;
3267 			sty.MetaFile = false;
3268 			sty.imageType = imgType;
3269 			sty.imageWidth = w;
3270 			sty.imageHeight = h;
3271 			sty.imagePixelFormat = pixelFormat;
3272 			sty.imageData.resize(dataSize - 28);
3273 			retVal = ds.readRawData(sty.imageData.data(), dataSize - 28);
3274 		}
3275 		else if (dataV == U_IDT_Metafile)
3276 		{
3277 			quint32 imgType, imgSize;
3278 			ds >> imgType >> imgSize;
3279 			if (imgType == U_MDT_WmfPlaceable)
3280 			{
3281 				QByteArray hea;
3282 				hea.resize(22);
3283 				ds.readRawData(hea.data(), 22);
3284 				ds.skipRawData(2);
3285 				QByteArray dta;
3286 				dta.resize(dataSize - 40);
3287 				retVal = ds.readRawData(dta.data(), dataSize - 40);
3288 				retVal += 24;
3289 				sty.imageData = hea;
3290 				sty.imageData += dta;
3291 			}
3292 			else
3293 			{
3294 				sty.imageData.resize(dataSize - 16);
3295 				retVal = ds.readRawData(sty.imageData.data(), dataSize - 16);
3296 			}
3297 			sty.imageType = imgType;
3298 			sty.MetaFile = true;
3299 		}
3300 	}
3301 	else
3302 	{
3303 		if (emfStyleMapEMP.contains(id))
3304 		{
3305 			QByteArray hea;
3306 			hea.resize(dataSize);
3307 			retVal = ds.readRawData(hea.data(), dataSize);
3308 			emfStyleMapEMP[id].imageData += hea;
3309 		}
3310 	}
3311 	return retVal;
3312 }
3313 
handleEMPFont(QDataStream & ds,quint16 id)3314 void SvmPlug::handleEMPFont(QDataStream &ds, quint16 id)
3315 {
3316 	quint32 dummy, unit, flags, length;
3317 	float emSize;
3318 	ds >> dummy;
3319 	ds >> emSize;
3320 	ds >> unit >> flags >> dummy >> length;
3321 	QString fontName = "";
3322 	for (quint32 a = 0; a < length; a++)
3323 	{
3324 		quint16 cc;
3325 		ds >> cc;
3326 		fontName.append(QChar(cc));
3327 	}
3328 	emfStyle sty;
3329 	sty.styType = U_OT_Font;
3330 	sty.fontSize = emSize;
3331 	sty.fontName = fontName;
3332 	sty.fontUnit = unit;
3333 	emfStyleMapEMP.insert(id, sty);
3334 }
3335 
handleEMPSFormat(QDataStream & ds,quint16 id)3336 void SvmPlug::handleEMPSFormat(QDataStream &ds, quint16 id)
3337 {
3338 	quint32 dummy, flags, hAlign, vAlign;
3339 	ds >> dummy >> flags >> dummy >> hAlign >> vAlign;
3340 	emfStyle sty;
3341 	sty.styType = U_OT_StringFormat;
3342 	sty.hAlign = hAlign;
3343 	sty.vAlign = vAlign;
3344 	sty.verticalText = (flags & 0x00000002);
3345 	emfStyleMapEMP.insert(id, sty);
3346 }
3347 
handleEMPLineCap(QDataStream & ds,quint16 id)3348 void SvmPlug::handleEMPLineCap(QDataStream &ds, quint16 id)
3349 {
3350 	qDebug() << "\t\tLine Cap";
3351 }
3352 
handleEMFPFillClosedCurve(QDataStream & ds,quint8 flagsL)3353 void SvmPlug::handleEMFPFillClosedCurve(QDataStream &ds, quint8 flagsL)
3354 {
3355 	quint32 brushID, count;
3356 	float tension;
3357 	ds >> brushID;
3358 	ds >> tension;
3359 	ds >> count;
3360 	bool directBrush = (flagsL & 0x80);
3361 	currentDC.fillRule = !(flagsL & 0x20);
3362 	getEMFPBrush(brushID, directBrush);
3363 	QPolygonF points = getEMFPCurvePoints(ds, flagsL, count);
3364 	QPainterPath path;
3365 	GdipAddPathClosedCurve(path, points, tension);
3366 	FPointArray polyline;
3367 	polyline.fromQPainterPath(path);
3368 	if (polyline.size() > 3)
3369 	{
3370 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
3371 		PageItem* ite = m_Doc->Items->at(z);
3372 		ite->PoLine = polyline.copy();
3373 		finishItem(ite);
3374 	}
3375 }
3376 
handleEMFPFillEllipse(QDataStream & ds,quint8 flagsL)3377 void SvmPlug::handleEMFPFillEllipse(QDataStream &ds, quint8 flagsL)
3378 {
3379 	quint32 brushID;
3380 	ds >> brushID;
3381 	bool directBrush = (flagsL & 0x80);
3382 	bool compressedRects = (flagsL & 0x40);
3383 	getEMFPBrush(brushID, directBrush);
3384 	QPointF p = getEMFPPoint(ds, compressedRects);
3385 	double w = getEMFPDistance(ds, compressedRects);
3386 	double h = getEMFPDistance(ds, compressedRects);
3387 	int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX, baseY, w, h, 0, currentDC.CurrColorFill, CommonStrings::None);
3388 	PageItem* ite = m_Doc->Items->at(z);
3389 	QTransform mm(1.0, 0.0, 0.0, 1.0, p.x(), p.y());
3390 	ite->PoLine.map(mm);
3391 	finishItem(ite);
3392 }
3393 
handleEMFPFillPath(QDataStream & ds,quint8 flagsL,quint8 flagsH)3394 void SvmPlug::handleEMFPFillPath(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3395 {
3396 	quint32 brushID;
3397 	ds >> brushID;
3398 	bool directBrush = (flagsL & 0x80);
3399 	getEMFPBrush(brushID, directBrush);
3400 	if (emfStyleMapEMP.contains(flagsH))
3401 	{
3402 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
3403 		PageItem* ite = m_Doc->Items->at(z);
3404 		ite->PoLine = emfStyleMapEMP[flagsH].Coords.copy();
3405 		finishItem(ite);
3406 	}
3407 }
3408 
handleEMFPFillPie(QDataStream & ds,quint8 flagsL)3409 void SvmPlug::handleEMFPFillPie(QDataStream &ds, quint8 flagsL)
3410 {
3411 	quint32 brushID;
3412 	float startA, sweepA;
3413 	ds >> brushID;
3414 	ds >> startA >> sweepA;
3415 	bool directBrush    = (flagsL & 0x80);
3416 	bool rectCompressed = (flagsL & 0x40);
3417 	getEMFPBrush(brushID, directBrush);
3418 	QRectF rect = getEMFPRect(ds, rectCompressed).boundingRect();
3419 	FPointArray  pointArray;
3420 	QPainterPath painterPath;
3421 	painterPath.arcMoveTo(rect, -startA);
3422 	QPointF firstPoint = painterPath.currentPosition();
3423 	painterPath.arcTo(rect, -startA, -sweepA);
3424 	painterPath.lineTo(rect.center());
3425 	painterPath.lineTo(firstPoint);
3426 	pointArray.fromQPainterPath(painterPath);
3427 	if (pointArray.size() > 3)
3428 	{
3429 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
3430 		PageItem* ite = m_Doc->Items->at(z);
3431 		ite->PoLine = pointArray.copy();
3432 		finishItem(ite);
3433 	}
3434 }
3435 
handleEMFPFillPolygon(QDataStream & ds,quint8 flagsL)3436 void SvmPlug::handleEMFPFillPolygon(QDataStream &ds, quint8 flagsL)
3437 {
3438 	quint32 brushID, count;
3439 	ds >> brushID >> count;
3440 	bool directBrush         = (flagsL & 0x80);
3441 	bool compressedPoints    = (flagsL & 0x40);
3442 	bool relativeCoordinates = (flagsL & 0x08);
3443 	getEMFPBrush(brushID, directBrush);
3444 	if (!relativeCoordinates)
3445 	{
3446 		bool bFirst = true;
3447 		FPointArray polyline;
3448 		polyline.svgInit();
3449 		for (quint32 a = 0; a < count; a++)
3450 		{
3451 			QPointF p = getEMFPPoint(ds, compressedPoints);
3452 			if (bFirst)
3453 			{
3454 				polyline.svgMoveTo(p.x(), p.y());
3455 				bFirst = false;
3456 			}
3457 			else
3458 				polyline.svgLineTo(p.x(), p.y());
3459 		}
3460 		if (polyline.size() > 3)
3461 		{
3462 			polyline.svgClosePath();
3463 			int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
3464 			PageItem* ite = m_Doc->Items->at(z);
3465 			ite->PoLine = polyline.copy();
3466 			finishItem(ite);
3467 		}
3468 	}
3469 }
3470 
handleEMFPFillRects(QDataStream & ds,quint8 flagsL)3471 void SvmPlug::handleEMFPFillRects(QDataStream &ds, quint8 flagsL)
3472 {
3473 	quint32 brushID, count;
3474 	ds >> brushID >> count;
3475 	bool directBrush = (flagsL & 0x80);
3476 	bool compressedRects = (flagsL & 0x40);
3477 	getEMFPBrush(brushID, directBrush);
3478 	for (quint32 a = 0; a < count; a++)
3479 	{
3480 		QPolygonF rect = getEMFPRect(ds, compressedRects);
3481 		FPointArray polyline;
3482 		polyline.svgInit();
3483 		polyline.svgMoveTo(rect[0].x(), rect[0].y());
3484 		polyline.svgLineTo(rect[1].x(), rect[1].y());
3485 		polyline.svgLineTo(rect[2].x(), rect[2].y());
3486 		polyline.svgLineTo(rect[3].x(), rect[3].y());
3487 		polyline.svgClosePath();
3488 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
3489 		PageItem* ite = m_Doc->Items->at(z);
3490 		ite->PoLine = polyline.copy();
3491 		finishItem(ite);
3492 	}
3493 }
3494 
handleEMFPFillRegion(QDataStream & ds,quint8 flagsL,quint8 flagsH)3495 void SvmPlug::handleEMFPFillRegion(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3496 {
3497 	quint32 brushID;
3498 	ds >> brushID;
3499 	bool directBrush = (flagsL & 0x80);
3500 	getEMFPBrush(brushID, directBrush);
3501 	if (emfStyleMapEMP.contains(flagsH))
3502 	{
3503 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
3504 		PageItem* ite = m_Doc->Items->at(z);
3505 		ite->PoLine = emfStyleMapEMP[flagsH].Coords.copy();
3506 		finishItem(ite);
3507 	}
3508 }
3509 
handleEMFPDrawArc(QDataStream & ds,quint8 flagsL,quint8 flagsH)3510 void SvmPlug::handleEMFPDrawArc(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3511 {
3512 	float startA, sweepA;
3513 	bool compressedRects = (flagsL & 0x40);
3514 	getEMFPPen(flagsH);
3515 	ds >> startA >> sweepA;
3516 	QRectF rect = getEMFPRect(ds, compressedRects).boundingRect();
3517 	FPointArray  pointArray;
3518 	QPainterPath painterPath;
3519 	painterPath.arcMoveTo(rect, -startA);
3520 	painterPath.arcTo(rect, -startA, -sweepA);
3521 	pointArray.fromQPainterPath(painterPath);
3522 	if (pointArray.size() > 3)
3523 	{
3524 		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3525 		PageItem* ite = m_Doc->Items->at(z);
3526 		ite->PoLine = pointArray.copy();
3527 		finishItem(ite, false);
3528 	}
3529 }
3530 
handleEMFPDrawBezier(QDataStream & ds,quint8 flagsL,quint8 flagsH)3531 void SvmPlug::handleEMFPDrawBezier(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3532 {
3533 	quint32 count;
3534 	ds >> count;
3535 	getEMFPPen(flagsH);
3536 	bool compressedPoints    = (flagsL & 0x40);
3537 	bool closedPolyline      = (flagsL & 0x20);
3538 	bool relativeCoordinates = (flagsL & 0x08);
3539 	if (!relativeCoordinates)
3540 	{
3541 		FPointArray polyline;
3542 		polyline.svgInit();
3543 		QPointF p1 = getEMFPPoint(ds, compressedPoints);
3544 		polyline.svgMoveTo(p1.x(), p1.y());
3545 		for (quint32 a = 1; a < count; a += 3)
3546 		{
3547 			QPointF p2 = getEMFPPoint(ds, compressedPoints);
3548 			QPointF p3 = getEMFPPoint(ds, compressedPoints);
3549 			QPointF p4 = getEMFPPoint(ds, compressedPoints);
3550 			polyline.svgCurveToCubic(p2.x(), p2.y(), p3.x(), p3.y(), p4.x(), p4.y());
3551 		}
3552 		if (polyline.size() > 3)
3553 		{
3554 			if (closedPolyline)
3555 				polyline.svgClosePath();
3556 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3557 			PageItem* ite = m_Doc->Items->at(z);
3558 			ite->PoLine = polyline.copy();
3559 			finishItem(ite, false);
3560 		}
3561 	}
3562 }
3563 
handleEMFPDrawClosedCurve(QDataStream & ds,quint8 flagsL,quint8 flagsH)3564 void SvmPlug::handleEMFPDrawClosedCurve(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3565 {
3566 	quint32 count;
3567 	float tension;
3568 	ds >> tension;
3569 	ds >> count;
3570 	getEMFPPen(flagsH);
3571 	QPolygonF points = getEMFPCurvePoints(ds, flagsL, count);
3572 	QPainterPath path;
3573 	GdipAddPathClosedCurve(path, points, tension);
3574 	FPointArray polyline;
3575 	polyline.fromQPainterPath(path);
3576 	if (polyline.size() > 3)
3577 	{
3578 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3579 		PageItem* ite = m_Doc->Items->at(z);
3580 		ite->PoLine = polyline.copy();
3581 		finishItem(ite, false);
3582 	}
3583 }
3584 
handleEMFPDrawCurve(QDataStream & ds,quint8 flagsL,quint8 flagsH)3585 void SvmPlug::handleEMFPDrawCurve(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3586 {
3587 	quint32 count, offset, numSegs;
3588 	float tension;
3589 	ds >> tension;
3590 	ds >> offset >> numSegs >> count;
3591 	getEMFPPen(flagsH);
3592 	QPolygonF points = getEMFPCurvePoints(ds, flagsL, count);
3593 	QPainterPath path;
3594 	GdipAddPathCurve(path, points, tension);
3595 	FPointArray polyline;
3596 	polyline.fromQPainterPath(path);
3597 	if (polyline.size() > 3)
3598 	{
3599 		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3600 		PageItem* ite = m_Doc->Items->at(z);
3601 		ite->PoLine = polyline.copy();
3602 		finishItem(ite, false);
3603 	}
3604 }
3605 
handleEMFPDrawEllipse(QDataStream & ds,quint8 flagsL,quint8 flagsH)3606 void SvmPlug::handleEMFPDrawEllipse(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3607 {
3608 	bool compressedRects = (flagsL & 0x40);
3609 	getEMFPPen(flagsH);
3610 	QPointF p = getEMFPPoint(ds, compressedRects);
3611 	double w = getEMFPDistance(ds, compressedRects);
3612 	double h = getEMFPDistance(ds, compressedRects);
3613 	int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX, baseY, w, h, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3614 	PageItem* ite = m_Doc->Items->at(z);
3615 	QTransform mm(1.0, 0.0, 0.0, 1.0, p.x(), p.y());
3616 	ite->PoLine.map(mm);
3617 	finishItem(ite, false);
3618 }
3619 
handleEMFPDrawImage(QDataStream & ds,quint8 flagsL,quint8 flagsH)3620 void SvmPlug::handleEMFPDrawImage(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3621 {
3622 	if (!emfStyleMapEMP.contains(flagsH))
3623 		return;
3624 	quint32 imgAttrs, dummy;
3625 	ds >> imgAttrs;
3626 	bool compressedPoints    = (flagsL & 0x40);
3627 	bool relativeCoordinates = (flagsL & 0x08);
3628 	currentDC.CurrFillTrans = 0.0;
3629 	if (!relativeCoordinates)
3630 	{
3631 		ds >> dummy >> dummy >> dummy >> dummy >> dummy;
3632 		QPolygonF rect = getEMFPRect(ds, compressedPoints);
3633 		QPointF p1 = rect[0];
3634 		QPointF p2 = rect[1];
3635 		QPointF p3 = rect[3];
3636 		handleEMFPDrawImageData(p1, p2, p3, flagsH);
3637 	}
3638 }
3639 
handleEMFPDrawImagePoints(QDataStream & ds,quint8 flagsL,quint8 flagsH)3640 void SvmPlug::handleEMFPDrawImagePoints(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3641 {
3642 	if (!emfStyleMapEMP.contains(flagsH))
3643 		return;
3644 	quint32 imgAttrs, dummy, count;
3645 	ds >> imgAttrs;
3646 	bool compressedPoints    = (flagsL & 0x40);
3647 	bool relativeCoordinates = (flagsL & 0x08);
3648 	currentDC.CurrFillTrans = 0.0;
3649 	if (!relativeCoordinates)
3650 	{
3651 		ds >> dummy >> dummy >> dummy >> dummy >> dummy;
3652 		ds >> count;
3653 		QPointF p1 = getEMFPPoint(ds, compressedPoints);
3654 		QPointF p2 = getEMFPPoint(ds, compressedPoints);
3655 		QPointF p3 = getEMFPPoint(ds, compressedPoints);
3656 		handleEMFPDrawImageData(p1, p2, p3, flagsH);
3657 	}
3658 }
3659 
handleEMFPDrawLines(QDataStream & ds,quint8 flagsL,quint8 flagsH)3660 void SvmPlug::handleEMFPDrawLines(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3661 {
3662 	quint32 count;
3663 	ds >> count;
3664 	getEMFPPen(flagsH);
3665 	bool compressedPoints    = (flagsL & 0x40);
3666 	bool closedPolyline      = (flagsL & 0x20);
3667 	bool relativeCoordinates = (flagsL & 0x08);
3668 	if (!relativeCoordinates)
3669 	{
3670 		bool bFirst = true;
3671 		FPointArray polyline;
3672 		polyline.svgInit();
3673 		for (quint32 a = 0; a < count; a++)
3674 		{
3675 			QPointF p = getEMFPPoint(ds, compressedPoints);
3676 			if (bFirst)
3677 			{
3678 				polyline.svgMoveTo(p.x(), p.y());
3679 				bFirst = false;
3680 			}
3681 			else
3682 				polyline.svgLineTo(p.x(), p.y());
3683 		}
3684 		if (polyline.size() > 3)
3685 		{
3686 			if (closedPolyline)
3687 				polyline.svgClosePath();
3688 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3689 			PageItem* ite = m_Doc->Items->at(z);
3690 			ite->PoLine = polyline.copy();
3691 			finishItem(ite, false);
3692 		}
3693 	}
3694 }
3695 
handleEMFPDrawPath(QDataStream & ds,quint8 flagsH)3696 void SvmPlug::handleEMFPDrawPath(QDataStream &ds, quint8 flagsH)
3697 {
3698 	quint32 penID;
3699 	ds >> penID;
3700 	getEMFPPen(penID);
3701 	if (emfStyleMapEMP.contains(flagsH))
3702 	{
3703 		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3704 		PageItem* ite = m_Doc->Items->at(z);
3705 		ite->PoLine = emfStyleMapEMP[flagsH].Coords.copy();
3706 		finishItem(ite, false);
3707 	}
3708 }
3709 
handleEMFPDrawPie(QDataStream & ds,quint8 flagsL,quint8 flagsH)3710 void SvmPlug::handleEMFPDrawPie(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3711 {
3712 	float startA, sweepA;
3713 	bool compressedRects = (flagsL & 0x40);
3714 	getEMFPPen(flagsH);
3715 	ds >> startA >> sweepA;
3716 	QRectF rect = getEMFPRect(ds, compressedRects).boundingRect();
3717 	FPointArray  pointArray;
3718 	QPainterPath painterPath;
3719 	painterPath.arcMoveTo(rect, -startA);
3720 	QPointF firstPoint = painterPath.currentPosition();
3721 	painterPath.arcTo(rect, -startA, -sweepA);
3722 	painterPath.lineTo(rect.center());
3723 	painterPath.lineTo(firstPoint);
3724 	pointArray.fromQPainterPath(painterPath);
3725 	if (pointArray.size() > 3)
3726 	{
3727 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3728 		PageItem* ite = m_Doc->Items->at(z);
3729 		ite->PoLine = pointArray.copy();
3730 		finishItem(ite, false);
3731 	}
3732 }
3733 
handleEMFPDrawRects(QDataStream & ds,quint8 flagsL,quint8 flagsH)3734 void SvmPlug::handleEMFPDrawRects(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3735 {
3736 	quint32 count;
3737 	ds >> count;
3738 	bool compressedRects = (flagsL & 0x40);
3739 	getEMFPPen(flagsH);
3740 	for (quint32 a = 0; a < count; a++)
3741 	{
3742 		QPolygonF rect = getEMFPRect(ds, compressedRects);
3743 		FPointArray polyline;
3744 		polyline.svgInit();
3745 		polyline.svgMoveTo(rect[0].x(), rect[0].y());
3746 		polyline.svgLineTo(rect[1].x(), rect[1].y());
3747 		polyline.svgLineTo(rect[2].x(), rect[2].y());
3748 		polyline.svgLineTo(rect[3].x(), rect[3].y());
3749 		polyline.svgClosePath();
3750 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3751 		PageItem* ite = m_Doc->Items->at(z);
3752 		ite->PoLine = polyline.copy();
3753 		finishItem(ite, false);
3754 	}
3755 }
3756 
handleEMFPDrawDriverString(QDataStream & ds,quint8 flagsL,quint8 flagsH)3757 void SvmPlug::handleEMFPDrawDriverString(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3758 {
3759 	quint32 brushID, txOpts, matrix, numChars;
3760 	ds >> brushID >> txOpts >> matrix >> numChars;
3761 	bool directBrush = (flagsL & 0x80);
3762 	getEMFPBrush(brushID, directBrush);
3763 	getEMFPFont(flagsH);
3764 	quint32 unit = currentDC.fontUnit;
3765 	if ((unit == U_UT_World) || (unit == U_UT_Display))
3766 		unit = U_UT_Pixel;
3767 	double fSize = convertEMFPLogical2Pts(currentDC.fontSize, unit);
3768 	fSize *= 10.0;
3769 	QFont font = QFont(currentDC.fontName, fSize);
3770 	font.setPixelSize(fSize);
3771 	QList<QChar> stringData;
3772 	QList<quint32> glyphs;
3773 	QTransform txTrans = QTransform();
3774 	if (txOpts & 0x00000001)
3775 	{
3776 		for (quint32 a = 0; a < numChars; a++)
3777 		{
3778 			quint16 cc;
3779 			ds >> cc;
3780 			stringData.append(QChar(cc));
3781 		}
3782 	}
3783 	else
3784 	{
3785 		for (quint32 a = 0; a < numChars; a++)
3786 		{
3787 			quint16 cc;
3788 			ds >> cc;
3789 			glyphs.append(cc);
3790 		}
3791 	}
3792 	QList<QPointF> dxTxt;
3793 	for (quint32 a = 0; a < numChars; a++)
3794 	{
3795 		QPointF p = getEMFPPoint(ds, false);
3796 		dxTxt.append(p);
3797 	}
3798 	if (matrix == 1)
3799 	{
3800 		float m11, m12, m21, m22, dx, dy;
3801 		ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
3802 		txTrans = QTransform(m11, m12, m21, m22, dx, dy);
3803 	}
3804 	QPainterPath painterPath;
3805 	if (txOpts & 0x00000001)
3806 	{
3807 		for (quint32 a = 0; a < numChars; a++)
3808 		{
3809 			QPainterPath gPath;
3810 			gPath.addText(0, 0, font, stringData[a]);
3811 			QTransform mm;
3812 			mm.scale(0.1, 0.1);
3813 			gPath = mm.map(gPath);
3814 			gPath.translate(dxTxt[a].x(), dxTxt[a].y());
3815 			gPath = txTrans.map(gPath);
3816 			painterPath.addPath(gPath);
3817 		}
3818 	}
3819 	else
3820 	{
3821 		QRawFont rFont = QRawFont::fromFont(font);
3822 		for (quint32 a = 0; a < numChars; a++)
3823 		{
3824 			QPainterPath gPath = rFont.pathForGlyph(glyphs[a]);
3825 			QTransform mm;
3826 			mm.scale(0.1, 0.1);
3827 			gPath = mm.map(gPath);
3828 			gPath.translate(dxTxt[a].x(), dxTxt[a].y());
3829 			gPath = txTrans.map(gPath);
3830 			painterPath.addPath(gPath);
3831 		}
3832 	}
3833 	FPointArray textPath;
3834 	textPath.fromQPainterPath(painterPath);
3835 	if (!textPath.empty())
3836 	{
3837 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
3838 		PageItem* ite = m_Doc->Items->at(z);
3839 		ite->PoLine = textPath.copy();
3840 		finishItem(ite);
3841 	}
3842 }
3843 
handleEMFPDrawString(QDataStream & ds,quint8 flagsL,quint8 flagsH)3844 void SvmPlug::handleEMFPDrawString(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3845 {
3846 	quint32 brushID, formatID, numChars;
3847 	FPointArray textPath;
3848 	QPainterPath painterPath;
3849 	ds >> brushID >> formatID >> numChars;
3850 	QPolygonF rect = getEMFPRect(ds, false);
3851 	QString stringData = "";
3852 	for (quint32 a = 0; a < numChars; a++)
3853 	{
3854 		quint16 cc;
3855 		ds >> cc;
3856 		stringData.append(QChar(cc));
3857 	}
3858 	bool directBrush = (flagsL & 0x80);
3859 	getEMFPBrush(brushID, directBrush);
3860 	getEMFPFont(flagsH);
3861 	getEMFPStringFormat(formatID);
3862 	quint32 unit = currentDC.fontUnit;
3863 	if ((unit == U_UT_World) || (unit == U_UT_Display))
3864 		unit = U_UT_Pixel;
3865 	double fSize = convertEMFPLogical2Pts(currentDC.fontSize, unit);
3866 	if (fSize < 5)
3867 	{
3868 		QFont font = QFont(currentDC.fontName, fSize * 10);
3869 		font.setPixelSize(fSize * 10);
3870 		painterPath.addText(0, 0, font, stringData);
3871 		QTransform mm;
3872 		mm.scale(0.1, 0.1);
3873 		painterPath = mm.map(painterPath);
3874 	}
3875 	else
3876 	{
3877 		QFont font = QFont(currentDC.fontName, fSize);
3878 		font.setPixelSize(fSize);
3879 		painterPath.addText(0, 0, font, stringData);
3880 	}
3881 	painterPath.translate(0, -painterPath.boundingRect().y());
3882 	if (currentDC.verticalText)
3883 	{
3884 		QTransform vm;
3885 		vm.rotate(90);
3886 		painterPath = vm.map(painterPath);
3887 		painterPath.translate(-painterPath.boundingRect().x(), 0);
3888 	}
3889 	double sh = rect.boundingRect().height();
3890 	double sw = rect.boundingRect().width();
3891 	if (currentDC.verticalText)
3892 	{
3893 		if (sh > 0)
3894 		{
3895 			if (currentDC.hAlign == U_SA_Center)
3896 				painterPath.translate(0, (sh - painterPath.boundingRect().height()) / 2.0);
3897 			else if (currentDC.hAlign == U_SA_Far)
3898 				painterPath.translate(0, sh - painterPath.boundingRect().height());
3899 		}
3900 		if (sw > 0)
3901 		{
3902 			if (currentDC.vAlign == U_SA_Center)
3903 				painterPath.translate((sw - painterPath.boundingRect().width()) / 2.0, 0);
3904 			else if (currentDC.vAlign == U_SA_Far)
3905 				painterPath.translate(sw - painterPath.boundingRect().width(), 0);
3906 		}
3907 	}
3908 	else
3909 	{
3910 		if (sw > 0)
3911 		{
3912 			if (currentDC.hAlign == U_SA_Center)
3913 				painterPath.translate((sw - painterPath.boundingRect().width()) / 2.0, 0);
3914 			else if (currentDC.hAlign == U_SA_Far)
3915 				painterPath.translate(sw - painterPath.boundingRect().width(), 0);
3916 		}
3917 		if (sh > 0)
3918 		{
3919 			if (currentDC.vAlign == U_SA_Center)
3920 				painterPath.translate(0, (sh - painterPath.boundingRect().height()) / 2.0);
3921 			else if (currentDC.vAlign == U_SA_Far)
3922 				painterPath.translate(0, sh - painterPath.boundingRect().height());
3923 		}
3924 	}
3925 	QTransform bm = currentDC.m_WorldMapEMFP;
3926 	bm = QTransform(bm.m11(), bm.m12(), bm.m21(), bm.m22(), 0, 0);
3927 	painterPath = bm.map(painterPath);
3928 	painterPath.translate(rect[0].x(), rect[0].y());
3929 	textPath.fromQPainterPath(painterPath);
3930 	if (!textPath.empty())
3931 	{
3932 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
3933 		PageItem* ite = m_Doc->Items->at(z);
3934 		ite->PoLine = textPath.copy();
3935 		finishItem(ite);
3936 	}
3937 }
3938 
handleEMFPSetClipRect(QDataStream & ds,quint8 flagsL)3939 void SvmPlug::handleEMFPSetClipRect(QDataStream &ds, quint8 flagsL)
3940 {
3941 	quint8 mode = flagsL & 0x0F;
3942 	QPolygonF rect = getEMFPRect(ds, false);
3943 	FPointArray clipPath;
3944 	clipPath.resize(0);
3945 	clipPath.svgInit();
3946 	clipPath.svgMoveTo(rect[0].x(), rect[0].y());
3947 	clipPath.svgLineTo(rect[1].x(), rect[1].y());
3948 	clipPath.svgLineTo(rect[2].x(), rect[2].y());
3949 	clipPath.svgLineTo(rect[3].x(), rect[3].y());
3950 	clipPath.svgClosePath();
3951 	if ((mode == 0) || (currentDC.clipPath.isEmpty()))
3952 		currentDC.clipPath = clipPath.copy();
3953 	else
3954 	{
3955 		QPainterPath pathN = clipPath.toQPainterPath(true);
3956 		QPainterPath pathA = currentDC.clipPath.toQPainterPath(true);
3957 		QPainterPath resultPath;
3958 		if (mode == 1)
3959 			resultPath = pathA.intersected(pathN);
3960 		else if (mode == 2)
3961 			resultPath = pathA.united(pathN);
3962 		else if (mode == 3)
3963 		{
3964 			QPainterPath part1 = pathA.subtracted(pathN);
3965 			QPainterPath part2 = pathN.subtracted(pathA);
3966 			resultPath.addPath(part1);
3967 			resultPath.addPath(part2);
3968 		}
3969 		if (!resultPath.isEmpty())
3970 		{
3971 			FPointArray polyline;
3972 			polyline.resize(0);
3973 			polyline.fromQPainterPath(resultPath, true);
3974 			polyline.svgClosePath();
3975 			currentDC.clipPath = polyline.copy();
3976 		}
3977 	}
3978 }
3979 
handleEMFPSetClipRegion(QDataStream & ds,quint8 flagsL,quint8 flagsH)3980 void SvmPlug::handleEMFPSetClipRegion(QDataStream &ds, quint8 flagsL, quint8 flagsH)
3981 {
3982 	if (emfStyleMapEMP.contains(flagsH))
3983 	{
3984 		if (emfStyleMapEMP[flagsH].Coords.isEmpty())
3985 		{
3986 			currentDC.clipPath.resize(0);
3987 			currentDC.clipPath.svgInit();
3988 			return;
3989 		}
3990 		quint8 mode = flagsL & 0x0F;
3991 		if ((mode == 0) || (currentDC.clipPath.isEmpty()))
3992 			currentDC.clipPath = emfStyleMapEMP[flagsH].Coords.copy();
3993 		else
3994 		{
3995 			FPointArray clipPath = emfStyleMapEMP[flagsH].Coords.copy();
3996 			QPainterPath pathN = clipPath.toQPainterPath(true);
3997 			QPainterPath pathA = currentDC.clipPath.toQPainterPath(true);
3998 			QPainterPath resultPath;
3999 			if (mode == 1)
4000 				resultPath = pathA.intersected(pathN);
4001 			else if (mode == 2)
4002 				resultPath = pathA.united(pathN);
4003 			else if (mode == 3)
4004 			{
4005 				QPainterPath part1 = pathA.subtracted(pathN);
4006 				QPainterPath part2 = pathN.subtracted(pathA);
4007 				resultPath.addPath(part1);
4008 				resultPath.addPath(part2);
4009 			}
4010 			if (!resultPath.isEmpty())
4011 			{
4012 				FPointArray polyline;
4013 				polyline.resize(0);
4014 				polyline.fromQPainterPath(resultPath, true);
4015 				polyline.svgClosePath();
4016 				currentDC.clipPath = polyline.copy();
4017 			}
4018 		}
4019 	}
4020 	else
4021 	{
4022 		currentDC.clipPath.resize(0);
4023 		currentDC.clipPath.svgInit();
4024 	}
4025 }
4026 
handleEMFPSetClipPath(QDataStream & ds,quint8 flagsL,quint8 flagsH)4027 void SvmPlug::handleEMFPSetClipPath(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4028 {
4029 	if (emfStyleMapEMP.contains(flagsH))
4030 	{
4031 		quint8 mode = flagsL & 0x0F;
4032 		if ((mode == 0) || (currentDC.clipPath.isEmpty()))
4033 			currentDC.clipPath = emfStyleMapEMP[flagsH].Coords.copy();
4034 		else
4035 		{
4036 			FPointArray clipPath = emfStyleMapEMP[flagsH].Coords.copy();
4037 			QPainterPath pathN = clipPath.toQPainterPath(true);
4038 			QPainterPath pathA = currentDC.clipPath.toQPainterPath(true);
4039 			QPainterPath resultPath;
4040 			if (mode == 1)
4041 				resultPath = pathA.intersected(pathN);
4042 			else if (mode == 2)
4043 				resultPath = pathA.united(pathN);
4044 			else if (mode == 3)
4045 			{
4046 				QPainterPath part1 = pathA.subtracted(pathN);
4047 				QPainterPath part2 = pathN.subtracted(pathA);
4048 				resultPath.addPath(part1);
4049 				resultPath.addPath(part2);
4050 			}
4051 			if (!resultPath.isEmpty())
4052 			{
4053 				FPointArray polyline;
4054 				polyline.resize(0);
4055 				polyline.fromQPainterPath(resultPath, true);
4056 				polyline.svgClosePath();
4057 				currentDC.clipPath = polyline.copy();
4058 			}
4059 		}
4060 	}
4061 }
4062 
handleEMFPSerializableObject(QDataStream & ds)4063 void SvmPlug::handleEMFPSerializableObject(QDataStream &ds)
4064 {
4065 	quint32 l;
4066 	quint16 w1, w2;
4067 	quint8 b1, b2, b3, b4, b5, b6, b7, b8;
4068 	ds >> l;
4069 	ds >> w1 >> w2;
4070 	ds >> b1 >> b2 >> b3 >> b4 >> b5 >> b6 >> b7 >> b8;
4071 	QString effID = QUuid(l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8).toString().toUpper();
4072 	m_Effects.clear();
4073 	SerializableObject_Valid = false;
4074 	if (effID == U_IE_BlurEffectGuid)
4075 	{
4076 		SerializableObject_Valid = true;
4077 		float edge;
4078 		ds >> edge;
4079 		ImageEffect ef;
4080 		ef.effectCode = ImageEffect::EF_BLUR;
4081 		ef.effectParameters = QString("%1 1.0").arg(edge / 255.0 * 30.0);
4082 		m_Effects.append(ef);
4083 	}
4084 	else if (effID == U_IE_BrightnessContrastEffectGuid)
4085 	{
4086 		SerializableObject_Valid = true;
4087 		qint32 brightness, contrast;
4088 		ds >> brightness >> contrast;
4089 		if (brightness != 0)
4090 		{
4091 			ImageEffect ef;
4092 			ef.effectCode = ImageEffect::EF_BRIGHTNESS;
4093 			ef.effectParameters = QString("%1").arg(brightness);
4094 			m_Effects.append(ef);
4095 		}
4096 		if (contrast != 0)
4097 		{
4098 			ImageEffect ef;
4099 			ef.effectCode = ImageEffect::EF_CONTRAST;
4100 			ef.effectParameters = QString("%1").arg(qMin(qMax(qRound(contrast * 1.27), -127), 127));
4101 			m_Effects.append(ef);
4102 		}
4103 	}
4104 	else if (effID == U_IE_ColorBalanceEffectGuid)
4105 		qDebug() << "ImageEffect\tColorbalance";
4106 	else if (effID == U_IE_ColorCurveEffectGuid)
4107 		qDebug() << "ImageEffect\tColorCurve";
4108 	else if (effID == U_IE_ColorLookupTableEffectGuid)
4109 		qDebug() << "ImageEffect\tColorLookupTable";
4110 	else if (effID == U_IE_ColorMatrixEffectGuid)
4111 		qDebug() << "ImageEffect\tColorMatrix";
4112 	else if (effID == U_IE_HueSaturationLightnessEffectGuid)
4113 		qDebug() << "ImageEffect\tHSL";
4114 	else if (effID == U_IE_LevelsEffectGuid)
4115 		qDebug() << "ImageEffect\tLevels";
4116 	else if (effID == U_IE_RedEyeCorrectionEffectGuid)
4117 		qDebug() << "ImageEffect\tRedEye";
4118 	else if (effID == U_IE_SharpenEffectGuid)
4119 	{
4120 		SerializableObject_Valid = true;
4121 		float radius, amount;
4122 		ds >> radius >> amount;
4123 		double amo = amount;
4124 		double rad = radius;
4125 		ImageEffect ef;
4126 		ef.effectCode = ImageEffect::EF_SHARPEN;
4127 		ef.effectParameters = QString("%1 %2").arg(qMin(rad, 10.0)).arg(qMin(amo / 100.0 * 5.0, 5.0));
4128 		m_Effects.append(ef);
4129 	}
4130 	else if (effID == U_IE_TintEffectGuid)
4131 		qDebug() << "ImageEffect\tTint";
4132 	else
4133 		SerializableObject_Valid = false;
4134 }
4135 
getEMFPBrush(quint32 brushID,bool directBrush)4136 void SvmPlug::getEMFPBrush(quint32 brushID, bool directBrush)
4137 {
4138 	if (directBrush)
4139 	{
4140 		quint8 r = brushID & 0xFF;
4141 		quint8 g = (brushID >> 8) & 0xFF;
4142 		quint8 b = (brushID >> 16) & 0xFF;
4143 		quint8 a = (brushID >> 24) & 0xFF;
4144 		QColor col(b, g, r, a);
4145 		currentDC.CurrColorFill = handleColor(col);
4146 		currentDC.CurrFillTrans = 1.0 - col.alphaF();
4147 		currentDC.brushStyle = U_BT_SolidColor;
4148 	}
4149 	else
4150 	{
4151 		if (emfStyleMapEMP.contains(brushID))
4152 		{
4153 			emfStyle sty = emfStyleMapEMP[brushID];
4154 			currentDC.CurrColorFill = sty.brushColor;
4155 			currentDC.brushStyle = sty.brushStyle;
4156 			currentDC.hatchStyle = sty.hatchStyle;
4157 			currentDC.CurrFillTrans = sty.fillTrans;
4158 			if (sty.brushStyle == U_BT_HatchFill)
4159 			{
4160 				currentDC.backColor = sty.penColor;
4161 				currentDC.backgroundMode = true;
4162 			}
4163 			else if (sty.brushStyle == U_BT_LinearGradient)
4164 			{
4165 				currentDC.gradientStart = sty.gradientStart;
4166 				currentDC.gradientEnd = sty.gradientEnd;
4167 				currentDC.gradientAngle = sty.gradientAngle;
4168 				currentDC.gradient = sty.gradient;
4169 			}
4170 			else if (sty.brushStyle == U_BT_PathGradient)
4171 			{
4172 				currentDC.gradientStart = sty.gradientStart;
4173 				currentDC.gradientAngle = sty.gradientAngle;
4174 				currentDC.gradient = sty.gradient;
4175 				currentDC.gradientPath = sty.gradientPath.copy();
4176 			}
4177 			else if (sty.brushStyle == U_BT_TextureFill)
4178 			{
4179 				currentDC.patternMode = sty.patternMode;
4180 				if (sty.patternName.isEmpty())
4181 				{
4182 					if (!emfStyleMapEMP[brushID].MetaFile)
4183 					{
4184 						QImage img = getImageDataFromStyle(brushID);
4185 						if (!img.isNull())
4186 						{
4187 							QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_emf_XXXXXX.png");
4188 							tempFile->setAutoRemove(false);
4189 							if (tempFile->open())
4190 							{
4191 								QString fileName = getLongPathName(tempFile->fileName());
4192 								if (!fileName.isEmpty())
4193 								{
4194 									tempFile->close();
4195 									img.save(fileName, "PNG");
4196 									ScPattern pat = ScPattern();
4197 									pat.setDoc(m_Doc);
4198 									int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, 0, 0, 1, 1, 0, CommonStrings::None, CommonStrings::None);
4199 									PageItem* newItem = m_Doc->Items->at(z);
4200 									m_Doc->loadPict(fileName, newItem);
4201 									m_Doc->Items->takeAt(z);
4202 									newItem->isInlineImage = true;
4203 									newItem->isTempFile = true;
4204 									pat.width = newItem->pixm.qImage().width();
4205 									pat.height = newItem->pixm.qImage().height();
4206 									pat.scaleX = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
4207 									pat.scaleY = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
4208 									pat.pattern = newItem->pixm.qImage().copy();
4209 									newItem->setWidth(pat.pattern.width());
4210 									newItem->setHeight(pat.pattern.height());
4211 									newItem->SetRectFrame();
4212 									newItem->gXpos = 0.0;
4213 									newItem->gYpos = 0.0;
4214 									newItem->gWidth = pat.pattern.width();
4215 									newItem->gHeight = pat.pattern.height();
4216 									pat.items.append(newItem);
4217 									QString patternName = "Pattern_"+newItem->itemName();
4218 									m_Doc->addPattern(patternName, pat);
4219 									emfStyleMapEMP[brushID].patternName = patternName;
4220 									importedPatterns.append(patternName);
4221 									currentDC.patternName = patternName;
4222 								}
4223 							}
4224 						}
4225 					}
4226 				}
4227 				else
4228 					currentDC.patternName = sty.patternName;
4229 			}
4230 		}
4231 	}
4232 }
4233 
getEMFPPen(quint32 penID)4234 void SvmPlug::getEMFPPen(quint32 penID)
4235 {
4236 	if (emfStyleMapEMP.contains(penID))
4237 	{
4238 		emfStyle sty = emfStyleMapEMP[penID];
4239 		currentDC.CurrColorStroke = sty.penColor;
4240 		currentDC.CurrStrokeTrans = sty.penTrans;
4241 		currentDC.LineW = sty.penWidth;
4242 		currentDC.penCap = sty.penCap;
4243 		currentDC.penJoin = sty.penJoin;
4244 		currentDC.penStyle = sty.penStyle;
4245 		currentDC.dashArray = sty.dashArray;
4246 		currentDC.dashOffset = sty.dashOffset;
4247 	}
4248 }
4249 
getEMFPFont(quint32 fontID)4250 void SvmPlug::getEMFPFont(quint32 fontID)
4251 {
4252 	if (emfStyleMapEMP.contains(fontID))
4253 	{
4254 		emfStyle sty = emfStyleMapEMP[fontID];
4255 		currentDC.fontName = sty.fontName;
4256 		currentDC.fontSize = sty.fontSize;
4257 		currentDC.fontUnit = sty.fontUnit;
4258 	}
4259 }
4260 
getEMFPStringFormat(quint32 fontID)4261 void SvmPlug::getEMFPStringFormat(quint32 fontID)
4262 {
4263 	if (emfStyleMapEMP.contains(fontID))
4264 	{
4265 		emfStyle sty = emfStyleMapEMP[fontID];
4266 		currentDC.hAlign = sty.hAlign;
4267 		currentDC.vAlign = sty.vAlign;
4268 		currentDC.verticalText = sty.verticalText;
4269 	}
4270 }
4271 
getEMPPathData(QDataStream & ds)4272 FPointArray SvmPlug::getEMPPathData(QDataStream &ds)
4273 {
4274 	FPointArray polyline;
4275 	polyline.resize(0);
4276 	polyline.svgInit();
4277 	quint32 dummy, count;
4278 	quint16 flags, dummy2;
4279 	ds >> dummy >> count;
4280 	ds >> flags >> dummy2;
4281 	bool compressedPoints    = (flags & 0x4000);
4282 	bool rleEncodedType      = (flags & 0x1000);
4283 	bool relativeCoordinates = (flags & 0x0800);
4284 	QList<QPointF> points;
4285 	QList<quint8> pTypes;
4286 	if (!relativeCoordinates)
4287 	{
4288 		for (quint32 a = 0; a < count; a++)
4289 		{
4290 			QPointF p = getEMFPPoint(ds, compressedPoints);
4291 			points.append(p);
4292 		}
4293 		for (quint32 b = 0; b < count; b++)
4294 		{
4295 			if (rleEncodedType)
4296 			{
4297 				quint8 cc, flg;
4298 				ds >> cc >> flg;
4299 				cc = cc & 0x3F;
4300 				for (quint8 ccc = 0; ccc < cc; ccc++)
4301 				{
4302 					pTypes.append(flg);
4303 				}
4304 				b += cc;
4305 			}
4306 			else
4307 			{
4308 				quint8 val;
4309 				ds >> val;
4310 				pTypes.append(val);
4311 			}
4312 		}
4313 		for (quint32 c = 0; c < count; c++)
4314 		{
4315 			QPointF p = points[c];
4316 			quint8 pfl = (pTypes[c] & 0xF0) >> 4;
4317 			quint8 pty = pTypes[c] & 0x0F;
4318 			if (pty == U_PPT_Start)
4319 				polyline.svgMoveTo(p.x(), p.y());
4320 			else if (pty == U_PPT_Line)
4321 				polyline.svgLineTo(p.x(), p.y());
4322 			else if (pty == U_PPT_Bezier)
4323 			{
4324 				QPointF p2 = points[c+1];
4325 				QPointF p3 = points[c+2];
4326 				polyline.svgCurveToCubic(p.x(), p.y(), p2.x(), p2.y(), p3.x(), p3.y());
4327 				c += 2;
4328 				pfl = (pTypes[c] & 0xF0) >> 4;
4329 			}
4330 			if (pfl & 0x08)
4331 				polyline.svgClosePath();
4332 		}
4333 	}
4334 	return polyline;
4335 }
4336 
getEMFPCurvePoints(QDataStream & ds,quint8 flagsL,quint32 count)4337 QPolygonF SvmPlug::getEMFPCurvePoints(QDataStream &ds, quint8 flagsL, quint32 count)
4338 {
4339 	bool compressedPoints    = (flagsL & 0x40);
4340 	bool relativeCoordinates = (flagsL & 0x08);
4341 	QPolygonF points;
4342 	if (!relativeCoordinates)
4343 	{
4344 		for (quint32 a = 0; a < count; a++)
4345 		{
4346 			QPointF p = getEMFPPoint(ds, compressedPoints);
4347 			points.append(p);
4348 		}
4349 	}
4350 	return points;
4351 }
4352 
getEMFPRect(QDataStream & ds,bool size)4353 QPolygonF SvmPlug::getEMFPRect(QDataStream &ds, bool size)
4354 {
4355 	QPolygonF result;
4356 	QPointF p1, p2, p3, p4;
4357 	if (size)
4358 	{
4359 		qint16 x1, y1, w, h;
4360 		ds >> x1 >> y1 >> w >> h;
4361 		p1 = QPointF(x1, y1);
4362 		p2 = QPointF(p1.x() + w, p1.y());
4363 		p3 = QPointF(p1.x() + w, p1.y() + h);
4364 		p4 = QPointF(p1.x(), p1.y() + h);
4365 	}
4366 	else
4367 	{
4368 		float x1, y1, w, h;
4369 		ds >> x1 >> y1 >> w >> h;
4370 		p1 = QPointF(x1, y1);
4371 		p2 = QPointF(p1.x() + w, p1.y());
4372 		p3 = QPointF(p1.x() + w, p1.y() + h);
4373 		p4 = QPointF(p1.x(), p1.y() + h);
4374 	}
4375 	result.append(convertEMFPLogical2Pts(p1, currentDC.emfPlusUnit));
4376 	result.append(convertEMFPLogical2Pts(p2, currentDC.emfPlusUnit));
4377 	result.append(convertEMFPLogical2Pts(p3, currentDC.emfPlusUnit));
4378 	result.append(convertEMFPLogical2Pts(p4, currentDC.emfPlusUnit));
4379 //	result.translate(-currentDC.originEMFP);
4380 	result.translate(currentDC.viewOrigin);
4381 	return result;
4382 }
4383 
getEMFPPoint(QDataStream & ds,bool size)4384 QPointF SvmPlug::getEMFPPoint(QDataStream &ds, bool size)
4385 {
4386 	QPointF p;
4387 	if (size)
4388 	{
4389 		qint16 x1, y1;
4390 		ds >> x1 >> y1;
4391 		p = QPointF(x1, y1);
4392 	}
4393 	else
4394 	{
4395 		float x1, y1;
4396 		ds >> x1 >> y1;
4397 		p = QPointF(x1, y1);
4398 	}
4399 	p = convertEMFPLogical2Pts(p, currentDC.emfPlusUnit);
4400 //	p -= currentDC.originEMFP;
4401 	p += currentDC.viewOrigin;
4402 	return p;
4403 }
4404 
getEMFPDistance(QDataStream & ds,bool size)4405 double SvmPlug::getEMFPDistance(QDataStream &ds, bool size)
4406 {
4407 	double p;
4408 	if (size)
4409 	{
4410 		qint16 x1;
4411 		ds >> x1;
4412 		p = x1;
4413 	}
4414 	else
4415 	{
4416 		float x1;
4417 		ds >> x1;
4418 		p = x1;
4419 	}
4420 	p = convertEMFPLogical2Pts(p, currentDC.emfPlusUnit);
4421 	return p;
4422 }
4423 
convertEMFPLogical2Pts(QPointF in,quint16 unit)4424 QPointF SvmPlug::convertEMFPLogical2Pts(QPointF in, quint16 unit)
4425 {
4426 	QPointF out = currentDC.m_WorldMapEMFP.map(in);
4427 	switch (unit)
4428 	{
4429 		case U_UT_World:
4430 		case U_UT_Display:
4431 			break;
4432 		case U_UT_Pixel:
4433 			out.setX(out.x() / static_cast<double>(EmfPdpiX) * 72.0);
4434 			out.setY(out.y() / static_cast<double>(EmfPdpiY) * 72.0);
4435 			break;
4436 		case U_UT_Point:
4437 			break;
4438 		case U_UT_Inch:
4439 			out.setX(out.x() * 72.0);
4440 			out.setY(out.y() * 72.0);
4441 			break;
4442 		case U_UT_Document:
4443 			out.setX(out.x() / 300.0 * 72.0);
4444 			out.setY(out.y() / 300.0 * 72.0);
4445 			break;
4446 		case U_UT_Millimeter:
4447 			out.setX(out.x() / 10.0 / 2.54 * 72.0);
4448 			out.setY(out.y() / 10.0 / 2.54 * 72.0);
4449 			break;
4450 		default:
4451 			break;
4452 	}
4453 	return out;
4454 }
4455 
convertEMFPLogical2Pts(double in,quint16 unit)4456 double SvmPlug::convertEMFPLogical2Pts(double in, quint16 unit)
4457 {
4458 	QLineF dist = QLineF(0, 0, in, 0);
4459 	dist = currentDC.m_WorldMapEMFP.map(dist);
4460 	double out = dist.length();
4461 	switch (unit)
4462 	{
4463 		case U_UT_World:
4464 		case U_UT_Display:
4465 			break;
4466 		case U_UT_Pixel:
4467 			out = out / static_cast<double>(EmfPdpiX) * 72.0;
4468 			break;
4469 		case U_UT_Point:
4470 			break;
4471 		case U_UT_Inch:
4472 			out = out * 72.0;
4473 			break;
4474 		case U_UT_Document:
4475 			out = out / 300 * 72.0;
4476 			break;
4477 		case U_UT_Millimeter:
4478 			out = out / 10.0 / 2.54 * 72.0;
4479 			break;
4480 		default:
4481 			break;
4482 	}
4483 	return out;
4484 }
4485 
gdip_open_curve_tangents(QPolygonF & points,double tension)4486 QPolygonF SvmPlug::gdip_open_curve_tangents(QPolygonF &points, double tension)
4487 {
4488 	double coefficient = tension / 3.0;
4489 	int i;
4490 	int count = points.count();
4491 	QPolygonF tangents;
4492 	tangents.fill(QPointF(0,0), count);
4493 	if (count <= 2)
4494 		return tangents;
4495 	for (i = 0; i < count; i++)
4496 	{
4497 		int r = i + 1;
4498 		int s = i - 1;
4499 		if (r >= count)
4500 			r = count - 1;
4501 		if (s < 0)
4502 			s = 0;
4503 		tangents[i] += QPointF(coefficient * (points[r].x() - points[s].x()), coefficient * (points[r].y() - points[s].y()));
4504 	}
4505 	return tangents;
4506 }
4507 
gdip_closed_curve_tangents(QPolygonF & points,double tension)4508 QPolygonF SvmPlug::gdip_closed_curve_tangents(QPolygonF &points, double tension)
4509 {
4510 	double coefficient = tension / 3.0;
4511 	int i;
4512 	int count = points.count();
4513 	QPolygonF tangents;
4514 	tangents.fill(QPointF(0,0), count);
4515 	if (count <= 2)
4516 		return tangents;
4517 	for (i = 0; i < count; i++)
4518 	{
4519 		int r = i + 1;
4520 		int s = i - 1;
4521 		if (r >= count)
4522 			r -= count;
4523 		if (s < 0)
4524 			s += count;
4525 		tangents[i] += QPointF(coefficient * (points[r].x() - points[s].x()), coefficient * (points[r].y() - points[s].y()));
4526 	}
4527 	return tangents;
4528 }
4529 
append_curve(QPainterPath & path,QPolygonF & points,QPolygonF & tangents,bool type)4530 void SvmPlug::append_curve(QPainterPath &path, QPolygonF &points, QPolygonF &tangents, bool type)
4531 {
4532 	int i;
4533 	path.moveTo(points[0]);
4534 	for (i = 0; i < points.count() - 1; i++)
4535 	{
4536 		int j = i + 1;
4537 		path.cubicTo(points[i] + tangents[i], points[j] - tangents[j], points[j]);
4538 	}
4539 	if (type)
4540 	{
4541 		path.cubicTo(points[i] + tangents[i], points[0] - tangents[0], points[0]);
4542 		path.closeSubpath();
4543 	}
4544 }
4545 
GdipAddPathCurve(QPainterPath & path,QPolygonF & points,float tension)4546 void SvmPlug::GdipAddPathCurve(QPainterPath &path, QPolygonF &points, float tension)
4547 {
4548 	QPolygonF tangents = gdip_open_curve_tangents(points, tension);
4549 	append_curve(path, points, tangents, false);
4550 }
4551 
GdipAddPathClosedCurve(QPainterPath & path,QPolygonF & points,float tension)4552 void SvmPlug::GdipAddPathClosedCurve(QPainterPath &path, QPolygonF &points, float tension)
4553 {
4554 	QPolygonF tangents = gdip_closed_curve_tangents(points, tension);
4555 	append_curve(path, points, tangents, true);
4556 }
4557 
handleEMFPDrawImageData(QPointF p1,QPointF p2,QPointF p3,quint8 flagsH)4558 void SvmPlug::handleEMFPDrawImageData(QPointF p1, QPointF p2, QPointF p3, quint8 flagsH)
4559 {
4560 	if (emfStyleMapEMP[flagsH].MetaFile)
4561 	{
4562 		QString ext = "emf";
4563 		if (emfStyleMapEMP[flagsH].imageType < U_MDT_Emf)
4564 			ext = "wmf";
4565 		PageItem* ite = getVectorFileFromData(m_Doc, emfStyleMapEMP[flagsH].imageData, ext, baseX + p1.x(), baseY + p1.y(), QLineF(p1, p2).length(), QLineF(p1, p3).length());
4566 		if (ite != nullptr)
4567 		{
4568 			if (QLineF(p1, p2).angle() != 0)
4569 				ite->setRotation(-QLineF(p1, p2).angle(), true);
4570 			finishItem(ite, false);
4571 		}
4572 	}
4573 	else
4574 	{
4575 		QImage img = getImageDataFromStyle(flagsH);
4576 		if (!img.isNull())
4577 		{
4578 			QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_emf_XXXXXX.png");
4579 			tempFile->setAutoRemove(false);
4580 			if (tempFile->open())
4581 			{
4582 				QString fileName = getLongPathName(tempFile->fileName());
4583 				if (!fileName.isEmpty())
4584 				{
4585 					tempFile->close();
4586 					img.save(fileName, "PNG");
4587 					int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Rectangle, baseX + p1.x(), baseY + p1.y(), QLineF(p1, p2).length(), QLineF(p1, p3).length(), 0, CommonStrings::None, CommonStrings::None);
4588 					PageItem* ite = m_Doc->Items->at(z);
4589 					finishItem(ite, false);
4590 					if (QLineF(p1, p2).angle() != 0)
4591 						ite->setRotation(-QLineF(p1, p2).angle(), true);
4592 					ite->isInlineImage = true;
4593 					ite->isTempFile = true;
4594 					if (SerializableObject_Valid)
4595 					{
4596 						ite->effectsInUse = m_Effects;
4597 						SerializableObject_Valid = false;
4598 						m_Effects.clear();
4599 					}
4600 					m_Doc->loadPict(fileName, ite);
4601 					ite->setImageScalingMode(false, false);
4602 					ite->updateClip();
4603 					if (currentDC.clipPath.count() != 0)
4604 					{
4605 						FPointArray cp = currentDC.clipPath.copy();
4606 						cp.translate(baseX, baseY);
4607 						cp.translate(-docX, -docY);
4608 						cp.translate(-ite->xPos(), -ite->yPos());
4609 						ite->PoLine = cp.copy();
4610 						FPoint wh = getMaxClipF(&ite->PoLine);
4611 						ite->setWidthHeight(wh.x(),wh.y());
4612 						ite->setTextFlowMode(PageItem::TextFlowDisabled);
4613 						m_Doc->adjustItemSize(ite);
4614 						ite->OldB2 = ite->width();
4615 						ite->OldH2 = ite->height();
4616 						ite->updateClip();
4617 					}
4618 				}
4619 			}
4620 			delete tempFile;
4621 		}
4622 	}
4623 }
4624 
getImageDataFromStyle(quint8 flagsH)4625 QImage SvmPlug::getImageDataFromStyle(quint8 flagsH)
4626 {
4627 	QImage img;
4628 	if (emfStyleMapEMP[flagsH].imageType == 1)
4629 		img.loadFromData(emfStyleMapEMP[flagsH].imageData);
4630 	else
4631 	{
4632 		int hWidth = qAbs(emfStyleMapEMP[flagsH].imageWidth);
4633 		int hHeight = qAbs(emfStyleMapEMP[flagsH].imageHeight);
4634 		QDataStream dsB(emfStyleMapEMP[flagsH].imageData);
4635 		dsB.setByteOrder(QDataStream::LittleEndian);
4636 		img = QImage(hWidth, hHeight, QImage::Format_ARGB32);
4637 		img.fill(0);
4638 		if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_32bppARGB)
4639 		{
4640 			for (qint32 yy = 0; yy < hHeight; yy++)
4641 			{
4642 				QRgb *dst = (QRgb*)img.scanLine(yy);
4643 				for (qint32 xx = 0; xx < hWidth; xx++)
4644 				{
4645 					quint8 r, g, b, a;
4646 					dsB >> b >> g >> r >> a;
4647 					*dst = qRgba(r, g, b, a);
4648 					dst++;
4649 				}
4650 			}
4651 		}
4652 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_32bppRGB)
4653 		{
4654 			for (qint32 yy = 0; yy < hHeight; yy++)
4655 			{
4656 				QRgb *dst = (QRgb*)img.scanLine(yy);
4657 				for (qint32 xx = 0; xx < hWidth; xx++)
4658 				{
4659 					quint8 r, g, b, a;
4660 					dsB >> b >> g >> r >> a;
4661 					*dst = qRgba(r, g, b, 255);
4662 					dst++;
4663 				}
4664 			}
4665 		}
4666 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_24bppRGB)
4667 		{
4668 			for (qint32 yy = 0; yy < hHeight; yy++)
4669 			{
4670 				QRgb *dst = (QRgb*)img.scanLine(yy);
4671 				for (qint32 xx = 0; xx < hWidth; xx++)
4672 				{
4673 					quint8 r, g, b;
4674 					dsB >> b >> g >> r;
4675 					*dst = qRgba(r, g, b, 255);
4676 					dst++;
4677 				}
4678 				aligntoQuadWord(dsB);
4679 			}
4680 		}
4681 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_16bppRGB555)
4682 		{
4683 			for (qint32 yy = 0; yy < hHeight; yy++)
4684 			{
4685 				QRgb *dst = (QRgb*)img.scanLine(yy);
4686 				for (qint32 xx = 0; xx < hWidth; xx++)
4687 				{
4688 					quint16 dt;
4689 					quint8 r, g, b;
4690 					dsB >> dt;
4691 					b = (dt & 0x1F) * 8;
4692 					g = ((dt >> 5) & 0x1F) * 8;
4693 					r = ((dt >> 10) & 0x1F) * 8;
4694 					*dst = qRgba(r, g, b, 255);
4695 					dst++;
4696 				}
4697 				aligntoQuadWord(dsB);
4698 			}
4699 		}
4700 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_16bppGrayScale)
4701 		{
4702 			for (qint32 yy = 0; yy < hHeight; yy++)
4703 			{
4704 				QRgb *dst = (QRgb*)img.scanLine(yy);
4705 				for (qint32 xx = 0; xx < hWidth; xx++)
4706 				{
4707 					quint16 r;
4708 					dsB >> r;
4709 					r = r >> 8;
4710 					*dst = qRgba(r, r, r, 255);
4711 					dst++;
4712 				}
4713 				aligntoQuadWord(dsB);
4714 			}
4715 		}
4716 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_8bppIndexed)
4717 		{
4718 			QVector<QRgb> colorTbl;
4719 			quint32 palFlags, colorsUsed;
4720 			dsB >> palFlags >> colorsUsed;
4721 			colorTbl.reserve(colorsUsed);
4722 			for (quint32 pa = 0; pa < colorsUsed; pa++)
4723 			{
4724 				quint32 brushID;
4725 				dsB >> brushID;
4726 				quint8 r = brushID & 0xFF;
4727 				quint8 g = (brushID >> 8) & 0xFF;
4728 				quint8 b = (brushID >> 16) & 0xFF;
4729 				quint8 a = (brushID >> 24) & 0xFF;
4730 				if (palFlags & 0x00000001)
4731 					colorTbl.append(qRgba(b, g, r, a));
4732 				else
4733 					colorTbl.append(qRgba(b, g, r, 255));
4734 			}
4735 			img = QImage(hWidth, hHeight, QImage::Format_Indexed8);
4736 			img.fill(0);
4737 			img.setColorTable(colorTbl);
4738 			for (qint32 yy = 0; yy < hHeight; yy++)
4739 			{
4740 				char *dst = (char*)img.scanLine(yy);
4741 				dsB.readRawData(dst, hWidth);
4742 				aligntoQuadWord(dsB);
4743 			}
4744 			img = img.convertToFormat(QImage::Format_ARGB32);
4745 		}
4746 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_4bppIndexed)
4747 		{
4748 			QVector<QRgb> colorTbl;
4749 			quint32 palFlags, colorsUsed;
4750 			dsB >> palFlags >> colorsUsed;
4751 			colorTbl.reserve(colorsUsed);
4752 			for (quint32 pa = 0; pa < colorsUsed; pa++)
4753 			{
4754 				quint32 brushID;
4755 				dsB >> brushID;
4756 				quint8 r = brushID & 0xFF;
4757 				quint8 g = (brushID >> 8) & 0xFF;
4758 				quint8 b = (brushID >> 16) & 0xFF;
4759 				quint8 a = (brushID >> 24) & 0xFF;
4760 				if (palFlags & 0x00000001)
4761 					colorTbl.append(qRgba(b, g, r, a));
4762 				else
4763 					colorTbl.append(qRgba(b, g, r, 255));
4764 			}
4765 			for (qint32 yy = 0; yy < hHeight; yy++)
4766 			{
4767 				QRgb *dst = (QRgb*)img.scanLine(yy);
4768 				for (qint32 xx = 0; xx < hWidth; xx += 2)
4769 				{
4770 					quint8 r, rh, rl;
4771 					dsB >> r;
4772 					rh = (r >> 4) & 0xF;
4773 					rl = r & 0xF;
4774 					if (rh < colorTbl.count())
4775 						*dst = colorTbl[rh];
4776 					dst++;
4777 					if (xx == hWidth - 1)
4778 						break;
4779 					if (rl < colorTbl.count())
4780 						*dst = colorTbl[rl];
4781 					dst++;
4782 				}
4783 				aligntoQuadWord(dsB);
4784 			}
4785 		}
4786 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_1bppIndexed)
4787 		{
4788 			QVector<QRgb> colorTbl;
4789 			quint32 palFlags, colorsUsed;
4790 			dsB >> palFlags >> colorsUsed;
4791 			colorTbl.reserve(colorsUsed);
4792 			for (quint32 pa = 0; pa < colorsUsed; pa++)
4793 			{
4794 				quint32 brushID;
4795 				dsB >> brushID;
4796 				quint8 r = brushID & 0xFF;
4797 				quint8 g = (brushID >> 8) & 0xFF;
4798 				quint8 b = (brushID >> 16) & 0xFF;
4799 				quint8 a = (brushID >> 24) & 0xFF;
4800 				if (palFlags & 0x00000001)
4801 					colorTbl.append(qRgba(b, g, r, a));
4802 				else
4803 					colorTbl.append(qRgba(b, g, r, 255));
4804 			}
4805 			img = QImage(hWidth, hHeight, QImage::Format_Mono);
4806 			img.fill(0);
4807 			img.setColorTable(colorTbl);
4808 			int bpl = img.bytesPerLine();
4809 			for (qint32 yy = 0; yy < hHeight; yy++)
4810 			{
4811 				char *dst = (char*)img.scanLine(yy);
4812 				dsB.readRawData(dst, bpl);
4813 			}
4814 			img = img.convertToFormat(QImage::Format_ARGB32);
4815 		}
4816 		else
4817 		{
4818 			qDebug() << QString("Format 0x%1").arg(emfStyleMapEMP[flagsH].imagePixelFormat, 8, 16, QChar('0'));
4819 			return img;
4820 		}
4821 	}
4822 	return img;
4823 }
4824