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