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                : Sun Jan 11 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 "importemf.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_EMR_HEADER                   1
62 #define U_EMR_POLYBEZIER               2
63 #define U_EMR_POLYGON                  3
64 #define U_EMR_POLYLINE                 4
65 #define U_EMR_POLYBEZIERTO             5
66 #define U_EMR_POLYLINETO               6
67 #define U_EMR_POLYPOLYLINE             7
68 #define U_EMR_POLYPOLYGON              8
69 #define U_EMR_SETWINDOWEXTEX           9
70 #define U_EMR_SETWINDOWORGEX          10
71 #define U_EMR_SETVIEWPORTEXTEX        11
72 #define U_EMR_SETVIEWPORTORGEX        12
73 #define U_EMR_SETBRUSHORGEX           13
74 #define U_EMR_EOF                     14
75 #define U_EMR_SETPIXELV               15
76 #define U_EMR_SETMAPPERFLAGS          16
77 #define U_EMR_SETMAPMODE              17
78 #define U_EMR_SETBKMODE               18
79 #define U_EMR_SETPOLYFILLMODE         19
80 #define U_EMR_SETROP2                 20
81 #define U_EMR_SETSTRETCHBLTMODE       21
82 #define U_EMR_SETTEXTALIGN            22
83 #define U_EMR_SETCOLORADJUSTMENT      23
84 #define U_EMR_SETTEXTCOLOR            24
85 #define U_EMR_SETBKCOLOR              25
86 #define U_EMR_OFFSETCLIPRGN           26
87 #define U_EMR_MOVETOEX                27
88 #define U_EMR_SETMETARGN              28
89 #define U_EMR_EXCLUDECLIPRECT         29
90 #define U_EMR_INTERSECTCLIPRECT       30
91 #define U_EMR_SCALEVIEWPORTEXTEX      31
92 #define U_EMR_SCALEWINDOWEXTEX        32
93 #define U_EMR_SAVEDC                  33
94 #define U_EMR_RESTOREDC               34
95 #define U_EMR_SETWORLDTRANSFORM       35
96 #define U_EMR_MODIFYWORLDTRANSFORM    36
97 #define U_EMR_SELECTOBJECT            37
98 #define U_EMR_CREATEPEN               38
99 #define U_EMR_CREATEBRUSHINDIRECT     39
100 #define U_EMR_DELETEOBJECT            40
101 #define U_EMR_ANGLEARC                41
102 #define U_EMR_ELLIPSE                 42
103 #define U_EMR_RECTANGLE               43
104 #define U_EMR_ROUNDRECT               44
105 #define U_EMR_ARC                     45
106 #define U_EMR_CHORD                   46
107 #define U_EMR_PIE                     47
108 #define U_EMR_SELECTPALETTE           48
109 #define U_EMR_CREATEPALETTE           49
110 #define U_EMR_SETPALETTEENTRIES       50
111 #define U_EMR_RESIZEPALETTE           51
112 #define U_EMR_REALIZEPALETTE          52
113 #define U_EMR_EXTFLOODFILL            53
114 #define U_EMR_LINETO                  54
115 #define U_EMR_ARCTO                   55
116 #define U_EMR_POLYDRAW                56
117 #define U_EMR_SETARCDIRECTION         57
118 #define U_EMR_SETMITERLIMIT           58
119 #define U_EMR_BEGINPATH               59
120 #define U_EMR_ENDPATH                 60
121 #define U_EMR_CLOSEFIGURE             61
122 #define U_EMR_FILLPATH                62
123 #define U_EMR_STROKEANDFILLPATH       63
124 #define U_EMR_STROKEPATH              64
125 #define U_EMR_FLATTENPATH             65
126 #define U_EMR_WIDENPATH               66
127 #define U_EMR_SELECTCLIPPATH          67
128 #define U_EMR_ABORTPATH               68
129 #define U_EMR_UNDEF69                 69
130 #define U_EMR_COMMENT                 70
131 #define U_EMR_FILLRGN                 71
132 #define U_EMR_FRAMERGN                72
133 #define U_EMR_INVERTRGN               73
134 #define U_EMR_PAINTRGN                74
135 #define U_EMR_EXTSELECTCLIPRGN        75
136 #define U_EMR_BITBLT                  76
137 #define U_EMR_STRETCHBLT              77
138 #define U_EMR_MASKBLT                 78
139 #define U_EMR_PLGBLT                  79
140 #define U_EMR_SETDIBITSTODEVICE       80
141 #define U_EMR_STRETCHDIBITS           81
142 #define U_EMR_EXTCREATEFONTINDIRECTW  82
143 #define U_EMR_EXTTEXTOUTA             83
144 #define U_EMR_EXTTEXTOUTW             84
145 #define U_EMR_POLYBEZIER16            85
146 #define U_EMR_POLYGON16               86
147 #define U_EMR_POLYLINE16              87
148 #define U_EMR_POLYBEZIERTO16          88
149 #define U_EMR_POLYLINETO16            89
150 #define U_EMR_POLYPOLYLINE16          90
151 #define U_EMR_POLYPOLYGON16           91
152 #define U_EMR_POLYDRAW16              92
153 #define U_EMR_CREATEMONOBRUSH         93
154 #define U_EMR_CREATEDIBPATTERNBRUSHPT 94
155 #define U_EMR_EXTCREATEPEN            95
156 #define U_EMR_POLYTEXTOUTA            96
157 #define U_EMR_POLYTEXTOUTW            97
158 #define U_EMR_SETICMMODE              98
159 #define U_EMR_CREATECOLORSPACE        99
160 #define U_EMR_SETCOLORSPACE          100
161 #define U_EMR_DELETECOLORSPACE       101
162 #define U_EMR_GLSRECORD              102
163 #define U_EMR_GLSBOUNDEDRECORD       103
164 #define U_EMR_PIXELFORMAT            104
165 #define U_EMR_DRAWESCAPE             105
166 #define U_EMR_EXTESCAPE              106
167 #define U_EMR_UNDEF107               107
168 #define U_EMR_SMALLTEXTOUT           108
169 #define U_EMR_FORCEUFIMAPPING        109
170 #define U_EMR_NAMEDESCAPE            110
171 #define U_EMR_COLORCORRECTPALETTE    111
172 #define U_EMR_SETICMPROFILEA         112
173 #define U_EMR_SETICMPROFILEW         113
174 #define U_EMR_ALPHABLEND             114
175 #define U_EMR_SETLAYOUT              115
176 #define U_EMR_TRANSPARENTBLT         116
177 #define U_EMR_UNDEF117               117
178 #define U_EMR_GRADIENTFILL           118
179 #define U_EMR_SETLINKEDUFIS          119
180 #define U_EMR_SETTEXTJUSTIFICATION   120
181 #define U_EMR_COLORMATCHTOTARGETW    121
182 #define U_EMR_CREATECOLORSPACEW      122
183 
184 #define U_STOCK_OBJECT          0x80000000
185 #define U_WHITE_BRUSH           0x80000000
186 #define U_LTGRAY_BRUSH          0x80000001
187 #define U_GRAY_BRUSH            0x80000002
188 #define U_DKGRAY_BRUSH          0x80000003
189 #define U_BLACK_BRUSH           0x80000004
190 #define U_NULL_BRUSH            0x80000005
191 #define U_WHITE_PEN             0x80000006
192 #define U_BLACK_PEN             0x80000007
193 #define U_NULL_PEN              0x80000008
194 #define U_OEM_FIXED_FONT        0x8000000A
195 #define U_ANSI_FIXED_FONT       0x8000000B
196 #define U_ANSI_VAR_FONT         0x8000000C
197 #define U_SYSTEM_FONT           0x8000000D
198 #define U_DEVICE_DEFAULT_FONT   0x8000000E
199 #define U_DEFAULT_PALETTE       0x8000000F
200 #define U_SYSTEM_FIXED_FONT     0x80000010
201 #define U_DEFAULT_GUI_FONT      0x80000011
202 #define U_DC_BRUSH              0x80000012
203 #define U_DC_PEN                0x80000013
204 
205 #define U_PMR_HEADER                  0x4001
206 #define U_PMR_ENDOFFILE               0x4002
207 #define U_PMR_COMMENT                 0x4003
208 #define U_PMR_GETDC                   0x4004
209 #define U_PMR_MULTIFORMATSTART        0x4005
210 #define U_PMR_MULTIFORMATSECTION      0x4006
211 #define U_PMR_MULTIFORMATEND          0x4007
212 #define U_PMR_OBJECT                  0x4008
213 #define U_PMR_CLEAR                   0x4009
214 #define U_PMR_FILLRECTS               0x400A
215 #define U_PMR_DRAWRECTS               0x400B
216 #define U_PMR_FILLPOLYGON             0x400C
217 #define U_PMR_DRAWLINES               0x400D
218 #define U_PMR_FILLELLIPSE             0x400E
219 #define U_PMR_DRAWELLIPSE             0x400F
220 #define U_PMR_FILLPIE                 0x4010
221 #define U_PMR_DRAWPIE                 0x4011
222 #define U_PMR_DRAWARC                 0x4012
223 #define U_PMR_FILLREGION              0x4013
224 #define U_PMR_FILLPATH                0x4014
225 #define U_PMR_DRAWPATH                0x4015
226 #define U_PMR_FILLCLOSEDCURVE         0x4016
227 #define U_PMR_DRAWCLOSEDCURVE         0x4017
228 #define U_PMR_DRAWCURVE               0x4018
229 #define U_PMR_DRAWBEZIERS             0x4019
230 #define U_PMR_DRAWIMAGE               0x401A
231 #define U_PMR_DRAWIMAGEPOINTS         0x401B
232 #define U_PMR_DRAWSTRING              0x401C
233 #define U_PMR_SETRENDERINGORIGIN      0x401D
234 #define U_PMR_SETANTIALIASMODE        0x401E
235 #define U_PMR_SETTEXTRENDERINGHINT    0x401F
236 #define U_PMR_SETTEXTCONTRAST         0x4020
237 #define U_PMR_SETINTERPOLATIONMODE    0x4021
238 #define U_PMR_SETPIXELOFFSETMODE      0x4022
239 #define U_PMR_SETCOMPOSITINGMODE      0x4023
240 #define U_PMR_SETCOMPOSITINGQUALITY   0x4024
241 #define U_PMR_SAVE                    0x4025
242 #define U_PMR_RESTORE                 0x4026
243 #define U_PMR_BEGINCONTAINER          0x4027
244 #define U_PMR_BEGINCONTAINERNOPARAMS  0x4028
245 #define U_PMR_ENDCONTAINER            0x4029
246 #define U_PMR_SETWORLDTRANSFORM       0x402A
247 #define U_PMR_RESETWORLDTRANSFORM     0x402B
248 #define U_PMR_MULTIPLYWORLDTRANSFORM  0x402C
249 #define U_PMR_TRANSLATEWORLDTRANSFORM 0x402D
250 #define U_PMR_SCALEWORLDTRANSFORM     0x402E
251 #define U_PMR_ROTATEWORLDTRANSFORM    0x402F
252 #define U_PMR_SETPAGETRANSFORM        0x4030
253 #define U_PMR_RESETCLIP               0x4031
254 #define U_PMR_SETCLIPRECT             0x4032
255 #define U_PMR_SETCLIPPATH             0x4033
256 #define U_PMR_SETCLIPREGION           0x4034
257 #define U_PMR_OFFSETCLIP              0x4035
258 #define U_PMR_DRAWDRIVERSTRING        0x4036
259 #define U_PMR_STROKEFILLPATH          0x4037
260 #define U_PMR_SERIALIZABLEOBJECT      0x4038
261 #define U_PMR_SETTSGRAPHICS           0x4039
262 #define U_PMR_SETTSCLIP               0x403A
263 
264 #define   U_BT_SolidColor               0x00
265 #define   U_BT_HatchFill                0x01
266 #define   U_BT_TextureFill              0x02
267 #define   U_BT_PathGradient             0x03
268 #define   U_BT_LinearGradient           0x04
269 
270 #define   U_OT_Invalid                  0x00
271 #define   U_OT_Brush                    0x01
272 #define   U_OT_Pen                      0x02
273 #define   U_OT_Path                     0x03
274 #define   U_OT_Region                   0x04
275 #define   U_OT_Image                    0x05
276 #define   U_OT_Font                     0x06
277 #define   U_OT_StringFormat             0x07
278 #define   U_OT_ImageAttributes          0x08
279 #define   U_OT_CustomLineCap            0x09
280 
281 #define   U_UT_World                    0x00
282 #define   U_UT_Display                  0x01
283 #define   U_UT_Pixel                    0x02
284 #define   U_UT_Point                    0x03
285 #define   U_UT_Inch                     0x04
286 #define   U_UT_Document                 0x05
287 #define   U_UT_Millimeter               0x06
288 
289 #define   U_PD_Transform                0x0001
290 #define   U_PD_StartCap                 0x0002
291 #define   U_PD_EndCap                   0x0004
292 #define   U_PD_Join                     0x0008
293 #define   U_PD_MiterLimit               0x0010
294 #define   U_PD_LineStyle                0x0020
295 #define   U_PD_DLCap                    0x0040
296 #define   U_PD_DLOffset                 0x0080
297 #define   U_PD_DLData                   0x0100
298 #define   U_PD_NonCenter                0x0200
299 #define   U_PD_CLData                   0x0400
300 #define   U_PD_CustomStartCap           0x0800
301 #define   U_PD_CustomEndCap             0x1000
302 
303 #define   U_PPT_Start                   0x00
304 #define   U_PPT_Line                    0x01
305 #define   U_PPT_Bezier                  0x03
306 
307 #define   U_SA_Near                     0x00
308 #define   U_SA_Center                   0x01
309 #define   U_SA_Far                      0x02
310 
311 #define   U_HSP_Horizontal              0x00000000
312 #define   U_HSP_Vertical                0x00000001
313 #define   U_HSP_ForwardDiagonal         0x00000002
314 #define   U_HSP_BackwardDiagonal        0x00000003
315 #define   U_HSP_LargeGrid               0x00000004
316 #define   U_HSP_DiagonalCross           0x00000005
317 #define   U_HSP_05Percent               0x00000006
318 #define   U_HSP_10Percent               0x00000007
319 #define   U_HSP_20Percent               0x00000008
320 #define   U_HSP_25Percent               0x00000009
321 #define   U_HSP_30Percent               0x0000000A
322 #define   U_HSP_40Percent               0x0000000B
323 #define   U_HSP_50Percent               0x0000000C
324 #define   U_HSP_60Percent               0x0000000D
325 #define   U_HSP_70Percent               0x0000000E
326 #define   U_HSP_75Percent               0x0000000F
327 #define   U_HSP_80Percent               0x00000010
328 #define   U_HSP_90Percent               0x00000011
329 #define   U_HSP_LightDownwardDiagonal   0x00000012
330 #define   U_HSP_LightUpwardDiagonal     0x00000013
331 #define   U_HSP_DarkDownwardDiagonal    0x00000014
332 #define   U_HSP_DarkUpwardDiagonal      0x00000015
333 #define   U_HSP_WideDownwardDiagonal    0x00000016
334 #define   U_HSP_WideUpwardDiagonal      0x00000017
335 #define   U_HSP_LightVertical           0x00000018
336 #define   U_HSP_LightHorizontal         0x00000019
337 #define   U_HSP_NarrowVertical          0x0000001A
338 #define   U_HSP_NarrowHorizontal        0x0000001B
339 #define   U_HSP_DarkVertical            0x0000001C
340 #define   U_HSP_DarkHorizontal          0x0000001D
341 #define   U_HSP_DashedDownwardDiagonal  0x0000001E
342 #define   U_HSP_DashedUpwardDiagonal    0x0000001F
343 #define   U_HSP_DashedHorizontal        0x00000020
344 #define   U_HSP_DashedVertical          0x00000021
345 #define   U_HSP_SmallConfetti           0x00000022
346 #define   U_HSP_LargeConfetti           0x00000023
347 #define   U_HSP_ZigZag                  0x00000024
348 #define   U_HSP_Wave                    0x00000025
349 #define   U_HSP_DiagonalBrick           0x00000026
350 #define   U_HSP_HorizontalBrick         0x00000027
351 #define   U_HSP_Weave                   0x00000028
352 #define   U_HSP_Plaid                   0x00000029
353 #define   U_HSP_Divot                   0x0000002A
354 #define   U_HSP_DottedGrid              0x0000002B
355 #define   U_HSP_DottedDiamond           0x0000002C
356 #define   U_HSP_Shingle                 0x0000002D
357 #define   U_HSP_Trellis                 0x0000002E
358 #define   U_HSP_Sphere                  0x0000002F
359 #define   U_HSP_SmallGrid               0x00000030
360 #define   U_HSP_SmallCheckerBoard       0x00000031
361 #define   U_HSP_LargeCheckerBoard       0x00000032
362 #define   U_HSP_OutlinedDiamond         0x00000033
363 #define   U_HSP_SolidDiamond            0x00000034
364 
365 #define   U_LS_Solid                    0x00
366 #define   U_LS_Dash                     0x01
367 #define   U_LS_Dot                      0x02
368 #define   U_LS_DashDot                  0x03
369 #define   U_LS_DashDotDot               0x04
370 #define   U_LS_Custom                   0x05
371 
372 #define   U_LJT_Miter                   0x00
373 #define   U_LJT_Bevel                   0x01
374 #define   U_LJT_Round                   0x02
375 #define   U_LJT_MiterClipped            0x03
376 
377 #define   U_LCT_Flat                    0x00
378 #define   U_LCT_Square                  0x01
379 #define   U_LCT_Round                   0x02
380 
381 #define   U_MDT_Wmf                     0x01
382 #define   U_MDT_WmfPlaceable            0x02
383 #define   U_MDT_Emf                     0x03
384 #define   U_MDT_EmfPlusOnly             0x04
385 #define   U_MDT_EmfPlusDual             0x05
386 
387 #define   U_IDT_Bitmap                  0x01
388 #define   U_IDT_Metafile                0x02
389 
390 #define   U_PF_1bppIndexed              0x00030101
391 #define   U_PF_4bppIndexed              0x00030402
392 #define   U_PF_8bppIndexed              0x00030803
393 #define   U_PF_16bppGrayScale           0x00101004
394 #define   U_PF_16bppRGB555              0x00021005
395 #define   U_PF_16bppRGB565              0x00021006
396 #define   U_PF_16bppARGB1555            0x00061007
397 #define   U_PF_24bppRGB                 0x00021808
398 #define   U_PF_32bppRGB                 0x00022009
399 #define   U_PF_32bppARGB                0x0026200A
400 #define   U_PF_32bppPARGB               0x000E200B
401 #define   U_PF_48bppRGB                 0x0010300C
402 #define   U_PF_64bppARGB                0x0034400D
403 #define   U_PF_64bppPARGB               0x001A400E
404 
405 #define   U_IE_BlurEffectGuid                     "{633C80A4-1843-482B-9EF2-BE2834C5FDD4}"
406 #define   U_IE_BrightnessContrastEffectGuid       "{D3A1DBE1-8EC4-4C17-9F4C-EA97AD1C343D}"
407 #define   U_IE_ColorBalanceEffectGuid             "{537E597D-251E-48DA-9664-29CA496B70F8}"
408 #define   U_IE_ColorCurveEffectGuid               "{DD6A0022-58E4-4A67-9D9B-D48EB881A53D}"
409 #define   U_IE_ColorLookupTableEffectGuid         "{A7CE72A9-0F7F-40D7-B3CC-D0C02D5C3212}"
410 #define   U_IE_ColorMatrixEffectGuid              "{718F2615-7933-40E3-A511-5F68FE14DD74}"
411 #define   U_IE_HueSaturationLightnessEffectGuid   "{8B2DD6C3-EB07-4D87-A5F0-7108E26A9C5F}"
412 #define   U_IE_LevelsEffectGuid                   "{99C354EC-2A31-4F3A-8C34-17A803B33A25}"
413 #define   U_IE_RedEyeCorrectionEffectGuid         "{74D29D05-69A4-4266-9549-3CC52836B632}"
414 #define   U_IE_SharpenEffectGuid                  "{63CBF3EE-C526-402C-8F71-62C540BF5142}"
415 #define   U_IE_TintEffectGuid                     "{1077AF00-2848-4441-9489-44AD4C2D7A2C}"
416 
417 #define   U_RNDT_Kids                   0x00000000
418 #define   U_RNDT_And                    0x00000001
419 #define   U_RNDT_Or                     0x00000002
420 #define   U_RNDT_Xor                    0x00000003
421 #define   U_RNDT_Exclude                0x00000004
422 #define   U_RNDT_Complement             0x00000005
423 #define   U_RNDT_Rect                   0x10000000
424 #define   U_RNDT_Path                   0x10000001
425 #define   U_RNDT_Empty                  0x10000002
426 #define   U_RNDT_Infinite               0x10000003
427 
EmfPlug(ScribusDoc * doc,int flags)428 EmfPlug::EmfPlug(ScribusDoc* doc, int flags)
429 	: clipGroup(nullptr),
430 	  docWidth(0.0),
431 	  docHeight(0.0),
432 	  baseX(0.0),
433 	  baseY(0.0),
434 	  docX(0.0),
435 	  docY(0.0),
436 	  dpiX(0.0),
437 	  dpiY(0.0),
438 	  EmfPdpiX(0),
439 	  EmfPdpiY(0.0),
440 	  m_records(0),
441 	  recordCount(0),
442 	  viewPextendX(0),
443 	  viewPextendY(0),
444 	  winPextendX(0),
445 	  winPextendY(0),
446 	  winOrigX(0),
447 	  winOrigY(0),
448 	  progressDialog(nullptr),
449 	  cancel(false),
450 	  m_Doc(doc),
451 	  importerFlags(flags),
452 	  inPath(false),
453 	  inEMFPlus(false),
454 	  emfPlusDual(false),
455 	  emfMixed(false),
456 	  emfPlusScale(0.0),
457 	  SerializableObject_Valid(false),
458 	  m_ObjSize(0),
459 	  m_currObjSize(0),
460 	  m_objID(0)
461 {
462 	tmpSel=new Selection(this, false);
463 	interactive = (flags & LoadSavePlugin::lfInteractive);
464 }
465 
readThumbnail(const QString & fName)466 QImage EmfPlug::readThumbnail(const QString& fName)
467 {
468 	QFileInfo fi = QFileInfo(fName);
469 	baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
470 	double b = 0;
471 	double h = 0;
472 	double x = 0;
473 	double y = 0;
474 	parseHeader(fName, x, y, b, h);
475 	if (b == 0.0)
476 		b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
477 	if (h == 0.0)
478 		h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
479 	docWidth = b;
480 	docHeight = h;
481 	docX = x;
482 	docY = y;
483 	baseX = 0;
484 	baseY = 0;
485 	progressDialog = nullptr;
486 	m_Doc = new ScribusDoc();
487 	m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
488 	m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
489 	m_Doc->addPage(0);
490 	m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
491 	baseX = m_Doc->currentPage()->xOffset();
492 	baseY = m_Doc->currentPage()->yOffset();
493 	Elements.clear();
494 	m_Doc->setLoading(true);
495 	m_Doc->DoDrawing = false;
496 	m_Doc->scMW()->setScriptRunning(true);
497 	QString CurDirP = QDir::currentPath();
498 	QDir::setCurrent(fi.path());
499 	if (convert(fName))
500 	{
501 		tmpSel->clear();
502 		QDir::setCurrent(CurDirP);
503 		if (Elements.count() > 0)
504 		{
505 			m_Doc->m_Selection->delaySignalsOn();
506 			m_Doc->m_Selection->clear();
507 			for (int dre=0; dre<Elements.count(); ++dre)
508 			{
509 				m_Doc->m_Selection->addItem(Elements.at(dre), true);
510 			}
511 			m_Doc->m_Selection->setGroupRect();
512 			double gx, gy, gh, gw;
513 			m_Doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
514 			m_Doc->moveGroup(baseX - gx, baseY - gy);
515 			m_Doc->m_Selection->clear();
516 			m_Doc->m_Selection->delaySignalsOff();
517 			m_Doc->currentPage()->setInitialHeight(gh);
518 			m_Doc->currentPage()->setInitialWidth(gw);
519 			m_Doc->currentPage()->setHeight(gh);
520 			m_Doc->currentPage()->setWidth(gw);
521 			m_Doc->setPageHeight(gh);
522 			m_Doc->setPageWidth(gw);
523 			m_Doc->setPageSize("Custom");
524 			m_Doc->currentPage()->setSize("Custom");
525 			m_Doc->reformPages(true);
526 		}
527 		if (Elements.count() > 1)
528 		{
529 			PageItem* grItem = m_Doc->groupObjectsList(Elements);
530 			grItem->setXYPos(baseX, baseY, true);
531 		}
532 		else if (Elements.count() == 1)
533 			Elements.at(0)->setXYPos(baseX, baseY, true);
534 		m_Doc->DoDrawing = true;
535 		m_Doc->m_Selection->delaySignalsOn();
536 		QImage tmpImage;
537 		if (Elements.count() > 0)
538 		{
539 			for (int dre=0; dre<Elements.count(); ++dre)
540 			{
541 				tmpSel->addItem(Elements.at(dre), true);
542 			}
543 			tmpSel->setGroupRect();
544 			double xs = tmpSel->width();
545 			double ys = tmpSel->height();
546 			tmpImage = Elements.at(0)->DrawObj_toImage(500);
547 			tmpImage.setText("XSize", QString("%1").arg(xs));
548 			tmpImage.setText("YSize", QString("%1").arg(ys));
549 		}
550 		m_Doc->scMW()->setScriptRunning(false);
551 		m_Doc->setLoading(false);
552 		m_Doc->m_Selection->delaySignalsOff();
553 		delete m_Doc;
554 		return tmpImage;
555 	}
556 	QDir::setCurrent(CurDirP);
557 	m_Doc->DoDrawing = true;
558 	m_Doc->scMW()->setScriptRunning(false);
559 	delete m_Doc;
560 	return QImage();
561 }
562 
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)563 bool EmfPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
564 {
565 	bool success = false;
566 	interactive = (flags & LoadSavePlugin::lfInteractive);
567 	importerFlags = flags;
568 	cancel = false;
569 	double x, y, b, h;
570 	bool ret = false;
571 	QFileInfo fi = QFileInfo(fNameIn);
572 	if ( !ScCore->usingGUI() )
573 	{
574 		interactive = false;
575 		showProgress = false;
576 	}
577 	baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
578 	if ( showProgress )
579 	{
580 		ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
581 		progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
582 		QStringList barNames, barTexts;
583 		barNames << "GI";
584 		barTexts << tr("Analyzing File:");
585 		QList<bool> barsNumeric;
586 		barsNumeric << false;
587 		progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
588 		progressDialog->setOverallTotalSteps(3);
589 		progressDialog->setOverallProgress(0);
590 		progressDialog->setProgress("GI", 0);
591 		progressDialog->show();
592 		connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
593 		qApp->processEvents();
594 	}
595 	else
596 		progressDialog = nullptr;
597 /* Set default Page to size defined in Preferences */
598 	x = 0.0;
599 	y = 0.0;
600 	b = 0.0;
601 	h = 0.0;
602 	if (progressDialog)
603 	{
604 		progressDialog->setOverallProgress(1);
605 		qApp->processEvents();
606 	}
607 	parseHeader(fNameIn, x, y, b, h);
608 	if (b == 0.0)
609 		b = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
610 	if (h == 0.0)
611 		h = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
612 	docWidth = b;
613 	docHeight = h;
614 	docX = x;
615 	docY = y;
616 	baseX = 0;
617 	baseY = 0;
618 	if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
619 	{
620 		m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
621 		m_Doc->addPage(0);
622 		m_Doc->view()->addPage(0, true);
623 		m_Doc->currentPage()->setInitialWidth(docWidth);
624 		m_Doc->currentPage()->setInitialHeight(docHeight);
625 		m_Doc->currentPage()->setWidth(docWidth);
626 		m_Doc->currentPage()->setHeight(docHeight);
627 		m_Doc->currentPage()->setMasterPageNameNormal();
628 		m_Doc->currentPage()->setSize("Custom");
629 		m_Doc->reformPages(true);
630 		baseX = m_Doc->currentPage()->xOffset();
631 		baseY = m_Doc->currentPage()->yOffset();
632 	}
633 	else
634 	{
635 		if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
636 		{
637 			m_Doc = ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
638 			ScCore->primaryMainWindow()->HaveNewDoc();
639 			m_Doc->setPageHeight(docHeight);
640 			m_Doc->setPageWidth(docWidth);
641 			m_Doc->currentPage()->setInitialWidth(docWidth);
642 			m_Doc->currentPage()->setInitialHeight(docHeight);
643 			m_Doc->currentPage()->setWidth(docWidth);
644 			m_Doc->currentPage()->setHeight(docHeight);
645 			ret = true;
646 			baseX = m_Doc->currentPage()->xOffset();
647 			baseY = m_Doc->currentPage()->yOffset();
648 		}
649 	}
650 	if ((!ret) && (interactive))
651 	{
652 		baseX = m_Doc->currentPage()->xOffset();
653 		baseY = m_Doc->currentPage()->yOffset();
654 	}
655 	if ((ret) || (!interactive))
656 	{
657 		if (docWidth > docHeight)
658 			m_Doc->setPageOrientation(1);
659 		else
660 			m_Doc->setPageOrientation(0);
661 		m_Doc->setPageSize("Custom");
662 	}
663 	if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
664 		m_Doc->view()->deselectItems();
665 	Elements.clear();
666 	m_Doc->setLoading(true);
667 	m_Doc->DoDrawing = false;
668 	if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
669 		m_Doc->view()->updatesOn(false);
670 	m_Doc->scMW()->setScriptRunning(true);
671 	qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
672 	QString CurDirP = QDir::currentPath();
673 	QDir::setCurrent(fi.path());
674 	if (convert(fNameIn))
675 	{
676 		tmpSel->clear();
677 		QDir::setCurrent(CurDirP);
678 		if (Elements.count() > 0)
679 		{
680 			m_Doc->m_Selection->delaySignalsOn();
681 			m_Doc->m_Selection->clear();
682 			for (int dre=0; dre<Elements.count(); ++dre)
683 			{
684 				m_Doc->m_Selection->addItem(Elements.at(dre), true);
685 			}
686 			m_Doc->m_Selection->setGroupRect();
687 			double gx, gy, gh, gw;
688 			m_Doc->m_Selection->getVisualGroupRect(&gx, &gy, &gw, &gh);
689 			m_Doc->moveGroup(baseX - gx, baseY - gy);
690 			m_Doc->m_Selection->clear();
691 			m_Doc->m_Selection->delaySignalsOff();
692 			if (importerFlags & LoadSavePlugin::lfCreateDoc)
693 			{
694 				m_Doc->currentPage()->setInitialHeight(gh);
695 				m_Doc->currentPage()->setInitialWidth(gw);
696 				m_Doc->currentPage()->setHeight(gh);
697 				m_Doc->currentPage()->setWidth(gw);
698 				m_Doc->setPageHeight(gh);
699 				m_Doc->setPageWidth(gw);
700 				m_Doc->setPageSize("Custom");
701 				m_Doc->currentPage()->setSize("Custom");
702 				m_Doc->reformPages(true);
703 			}
704 		}
705 		if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
706 			m_Doc->groupObjectsList(Elements);
707 		m_Doc->DoDrawing = true;
708 		m_Doc->scMW()->setScriptRunning(false);
709 		m_Doc->setLoading(false);
710 		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
711 		if ((Elements.count() > 0) && (!ret) && (interactive))
712 		{
713 			if (flags & LoadSavePlugin::lfScripted)
714 			{
715 				bool loadF = m_Doc->isLoading();
716 				m_Doc->setLoading(false);
717 				m_Doc->changed();
718 				m_Doc->setLoading(loadF);
719 				if (!(flags & LoadSavePlugin::lfLoadAsPattern))
720 				{
721 					m_Doc->m_Selection->delaySignalsOn();
722 					for (int dre=0; dre<Elements.count(); ++dre)
723 					{
724 						m_Doc->m_Selection->addItem(Elements.at(dre), true);
725 					}
726 					m_Doc->m_Selection->delaySignalsOff();
727 					m_Doc->m_Selection->setGroupRect();
728 					if (m_Doc->view() != nullptr)
729 						m_Doc->view()->updatesOn(true);
730 				}
731 			}
732 			else
733 			{
734 				m_Doc->DragP = true;
735 				m_Doc->DraggedElem = nullptr;
736 				m_Doc->DragElements.clear();
737 				m_Doc->m_Selection->delaySignalsOn();
738 				for (int dre=0; dre<Elements.count(); ++dre)
739 				{
740 					tmpSel->addItem(Elements.at(dre), true);
741 				}
742 				tmpSel->setGroupRect();
743 				ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
744 				m_Doc->itemSelection_DeleteItem(tmpSel);
745 				m_Doc->view()->updatesOn(true);
746 				if (importedColors.count() != 0)
747 				{
748 					for (int cd = 0; cd < importedColors.count(); cd++)
749 					{
750 						m_Doc->PageColors.remove(importedColors[cd]);
751 					}
752 				}
753 				if (importedPatterns.count() != 0)
754 				{
755 					for (int cd = 0; cd < importedPatterns.count(); cd++)
756 					{
757 						m_Doc->docPatterns.remove(importedPatterns[cd]);
758 					}
759 				}
760 				m_Doc->m_Selection->delaySignalsOff();
761 				// We must copy the TransationSettings object as it is owned
762 				// by handleObjectImport method afterwards
763 				TransactionSettings* transacSettings = new TransactionSettings(trSettings);
764 				m_Doc->view()->handleObjectImport(md, transacSettings);
765 				m_Doc->DragP = false;
766 				m_Doc->DraggedElem = nullptr;
767 				m_Doc->DragElements.clear();
768 			}
769 		}
770 		else
771 		{
772 			m_Doc->changed();
773 			m_Doc->reformPages();
774 			if (!(flags & LoadSavePlugin::lfLoadAsPattern))
775 				m_Doc->view()->updatesOn(true);
776 		}
777 		success = true;
778 	}
779 	else
780 	{
781 		QDir::setCurrent(CurDirP);
782 		m_Doc->DoDrawing = true;
783 		m_Doc->scMW()->setScriptRunning(false);
784 		if (m_Doc->view() != nullptr)
785 			m_Doc->view()->updatesOn(true);
786 		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
787 	}
788 	if (interactive)
789 		m_Doc->setLoading(false);
790 	//CB If we have a gui we must refresh it if we have used the progressbar
791 	if (!(flags & LoadSavePlugin::lfLoadAsPattern))
792 	{
793 		if ((showProgress) && (!interactive))
794 			m_Doc->view()->DrawNew();
795 	}
796 	qApp->restoreOverrideCursor();
797 	return success;
798 }
799 
~EmfPlug()800 EmfPlug::~EmfPlug()
801 {
802 	delete progressDialog;
803 	delete tmpSel;
804 }
805 
parseHeader(const QString & fName,double & x,double & y,double & b,double & h)806 void EmfPlug::parseHeader(const QString& fName, double &x, double &y, double &b, double &h)
807 {
808 	inEMFPlus = false;
809 	emfMixed = false;
810 	bool hasEMF = false;
811 	bool hasEMFPlus = false;
812 	QFile f(fName);
813 	if (f.open(QIODevice::ReadOnly))
814 	{
815 		QDataStream ds(&f);
816 		ds.setByteOrder(QDataStream::LittleEndian);
817 		quint32 id, size;
818 		while (!ds.atEnd())
819 		{
820 			ds >> id >> size;
821 			size -= 8;        // Subtract id and size entry to get real data size
822 			qint64 posi = ds.device()->pos();
823 			if (inEMFPlus)
824 			{
825 				switch (id)
826 				{
827 					case U_EMR_EOF:
828 						break;
829 					case U_EMR_COMMENT:
830 					{
831 						quint32 commTyp, dtaSize;
832 						ds >> dtaSize;
833 						ds >> commTyp;
834 						if (commTyp == 0x2B464D45)
835 						{
836 							inEMFPlus = true;
837 							hasEMFPlus = true;
838 							quint16 id2, flagsHL;
839 							quint32 size2;
840 							QByteArray emfRecords;
841 							emfRecords.resize(dtaSize);
842 							ds.readRawData(emfRecords.data(), dtaSize);
843 							QDataStream dsEmf(emfRecords);
844 							dsEmf.setByteOrder(QDataStream::LittleEndian);
845 							dsEmf.setFloatingPointPrecision(QDataStream::SinglePrecision);
846 							while (!dsEmf.atEnd())
847 							{
848 								qint64 posi2 = dsEmf.device()->pos();
849 								dsEmf >> id2;
850 								dsEmf >> flagsHL;
851 								dsEmf >> size2;
852 								if ((id2 < 0x4000) || (id2 > 0x403A))
853 									break;
854 								switch (id2)
855 								{
856 									case U_PMR_HEADER:
857 										emfPlusDual = (flagsHL & 1);
858 										break;
859 									case U_PMR_ENDOFFILE:
860 										inEMFPlus = false;
861 										break;
862 									case U_PMR_GETDC:
863 										if (emfPlusDual)
864 											inEMFPlus = false;
865 										break;
866 									default:
867 										break;
868 								}
869 								dsEmf.device()->seek(posi2 + size2);
870 							}
871 						}
872 					}
873 				}
874 			}
875 			else
876 			{
877 				switch (id)
878 				{
879 					case U_EMR_HEADER:
880 						{
881 							qint32 bLeft, bTop, bRight, bBottom;
882 							ds >> bLeft >> bTop >> bRight >> bBottom;
883 							qint32 pLeft, pTop, pRight, pBottom;
884 							ds >> pLeft >> pTop >> pRight >> pBottom;
885 							quint32 sign, vers, bytes;
886 							ds >> sign >> vers >> bytes >> m_records;
887 							bBoxDev = QRectF(QPointF(bLeft, bTop), QPointF(bRight, bBottom)).normalized();
888 							bBoxMM = QRectF(QPointF(pLeft, pTop), QPointF(pRight, pBottom)).normalized();
889 						//	dpiX = bBoxDev.width() / (bBoxMM.width() / 100.0) * 25.4;
890 						//	dpiY = bBoxDev.height() / (bBoxMM.height() / 100.0) * 25.4;
891 							dpiX = bRight / (pRight / 100.0) * 25.4;
892 							dpiY = bBottom / (pBottom / 100.0) * 25.4;
893 							b = bBoxMM.width() / 1000.0 / 2.54 * 72.0;
894 							h = bBoxMM.height() / 1000.0 / 2.54 * 72.0;
895 							x = bBoxMM.x() / 1000.0 / 2.54 * 72.0;
896 							y = bBoxMM.y() / 1000.0 / 2.54 * 72.0;
897 						}
898 						break;
899 					case U_EMR_EOF:
900 						break;
901 					case U_EMR_COMMENT:
902 						{
903 							quint32 commTyp, dtaSize;
904 							ds >> dtaSize;
905 							ds >> commTyp;
906 							if (commTyp == 0x2B464D45)
907 							{
908 								inEMFPlus = true;
909 								hasEMFPlus = true;
910 								quint16 id2, flagsHL;
911 								quint32 size2;
912 								QByteArray emfRecords;
913 								emfRecords.resize(dtaSize);
914 								ds.readRawData(emfRecords.data(), dtaSize);
915 								QDataStream dsEmf(emfRecords);
916 								dsEmf.setByteOrder(QDataStream::LittleEndian);
917 								dsEmf.setFloatingPointPrecision(QDataStream::SinglePrecision);
918 								while (!dsEmf.atEnd())
919 								{
920 									qint64 posi2 = dsEmf.device()->pos();
921 									dsEmf >> id2;
922 									dsEmf >> flagsHL;
923 									dsEmf >> size2;
924 									if ((id2 < 0x4000) || (id2 > 0x403A))
925 										break;
926 									switch (id2)
927 									{
928 										case U_PMR_HEADER:
929 											emfPlusDual = (flagsHL & 1);
930 											break;
931 										case U_PMR_ENDOFFILE:
932 											inEMFPlus = false;
933 											break;
934 										case U_PMR_GETDC:
935 											if (emfPlusDual)
936 												inEMFPlus = false;
937 											break;
938 										default:
939 											break;
940 									}
941 									dsEmf.device()->seek(posi2 + size2);
942 								}
943 							}
944 						}
945 						break;
946 					default:
947 						hasEMF = true;
948 						break;
949 				}
950 			}
951 			ds.device()->seek(posi + size);
952 		}
953 		f.close();
954 	}
955 	inEMFPlus = false;
956 	if (hasEMF && hasEMFPlus)
957 		emfMixed = true;
958 }
959 
convert(const QString & fn)960 bool EmfPlug::convert(const QString& fn)
961 {
962 	importedColors.clear();
963 	importedPatterns.clear();
964 	currentDC.CurrColorFill = "White";
965 	currentDC.CurrFillTrans = 0.0;
966 	currentDC.CurrColorStroke = "Black";
967 	currentDC.CurrStrokeTrans = 0.0;
968 	currentDC.CurrColorText = "Black";
969 	currentDC.backColor = CommonStrings::None;
970 	currentDC.LineW = 1.0;
971 	currentDC.penStyle = Qt::SolidLine;
972 	currentDC.penCap = Qt::RoundCap;
973 	currentDC.penJoin = Qt::RoundJoin;
974 	currentDC.m_mapMode = 1;
975 	currentDC.backgroundMode = false;
976 	currentDC.arcDirection = true;
977 	currentDC.alphaOn = true;
978 	currentDC.fillRule = true;
979 	currentDC.textAlignment = 0;
980 	currentDC.brushStyle = U_BT_SolidColor;
981 	currentDC.hatchStyle = 0;
982 	currentDC.m_WorldMap = QTransform();
983 	currentDC.m_WorldMapEMFP = QTransform();
984 	currentDC.Coords.resize(0);
985 	currentDC.Coords.svgInit();
986 	currentDC.clipPath.resize(0);
987 	currentDC.clipPath.svgInit();
988 	currentDC.clipValid = false;
989 	currentDC.fontSize = 12;
990 	currentDC.fontName = "Arial";
991 	currentDC.fontRotation = 0;
992 	currentDC.viewOrigin = QPointF(0, 0);
993 	currentDC.winOrigin = QPointF(0, 0);
994 	currentDC.currentPoint = QPointF();
995 	currentDC.originEMFP = QPointF(0, 0);
996 	currentDC.patternName = "";
997 	currentDC.emfPlusUnit = 2;
998 	inPath = false;
999 	inEMFPlus = false;
1000 	emfPlusDual = false;
1001 	SerializableObject_Valid = false;
1002 	m_Effects.clear();
1003 	emfPlusScale = 1.0;
1004 	m_ObjSize = 0;
1005 	m_currObjSize = 0;
1006 	QColor col;
1007 	emfStyle sty;
1008 	// WHITE_BRUSH
1009 	sty.styType = U_OT_Brush;
1010 	sty.brushColor = "White";
1011 	emfStyleMap.insert(U_WHITE_BRUSH, sty);
1012 	// LTGRAY_BRUSH
1013 	col = QColor(Qt::lightGray);
1014 	sty.brushColor = handleColor(col);
1015 	emfStyleMap.insert(U_LTGRAY_BRUSH, sty);
1016 	// GRAY_BRUSH
1017 	col = QColor(Qt::gray);
1018 	sty.brushColor = handleColor(col);
1019 	emfStyleMap.insert(U_GRAY_BRUSH, sty);
1020 	// DKGRAY_BRUSH
1021 	col = QColor(Qt::darkGray);
1022 	sty.brushColor = handleColor(col);
1023 	emfStyleMap.insert(U_DKGRAY_BRUSH, sty);
1024 	// BLACK_BRUSH
1025 	sty.brushColor = "Black";
1026 	emfStyleMap.insert(U_BLACK_BRUSH, sty);
1027 	// NULL_BRUSH
1028 	sty.brushColor = CommonStrings::None;
1029 	emfStyleMap.insert(U_NULL_BRUSH, sty);
1030 	// WHITE_PEN
1031 	sty.styType = U_OT_Pen;
1032 	sty.brushColor = CommonStrings::None;
1033 	sty.penColor = "White";
1034 	emfStyleMap.insert(U_WHITE_PEN, sty);
1035 	// BLACK_PEN
1036 	sty.penColor = "Black";
1037 	emfStyleMap.insert(U_BLACK_PEN, sty);
1038 	// NULL_PEN
1039 	sty.penColor = CommonStrings::None;
1040 	emfStyleMap.insert(U_NULL_PEN, sty);
1041 	sty.styType = U_OT_Font;
1042 	// OEM_FIXED_FONT
1043 	emfStyleMap.insert(U_OEM_FIXED_FONT, sty);
1044 	// ANSI_FIXED_FONT
1045 	emfStyleMap.insert(U_ANSI_FIXED_FONT, sty);
1046 	// ANSI_VAR_FONT
1047 	emfStyleMap.insert(U_ANSI_VAR_FONT, sty);
1048 	// SYSTEM_FONT
1049 	emfStyleMap.insert(U_SYSTEM_FONT, sty);
1050 	// DEVICE_DEFAULT_FONT
1051 	emfStyleMap.insert(U_DEVICE_DEFAULT_FONT, sty);
1052 	// DEFAULT_PALETTE
1053 	emfStyleMap.insert(U_DEFAULT_PALETTE, sty);
1054 	// SYSTEM_FIXED_FONT
1055 	emfStyleMap.insert(U_SYSTEM_FIXED_FONT, sty);
1056 	// DEFAULT_GUI_FONT
1057 	emfStyleMap.insert(U_DEFAULT_GUI_FONT, sty);
1058 	// DC_BRUSH
1059 	sty.styType = U_OT_Brush;
1060 	emfStyleMap.insert(U_DC_BRUSH, sty);
1061 	// DC_PEN
1062 	sty.styType = U_OT_Pen;
1063 	emfStyleMap.insert(U_DC_PEN, sty);
1064 	emfStyleMapEMP.clear();
1065 	clipGroup = nullptr;
1066 	if (progressDialog)
1067 	{
1068 		progressDialog->setOverallProgress(2);
1069 		progressDialog->setLabel("GI", tr("Generating Items"));
1070 		qApp->processEvents();
1071 	}
1072 	QFile f(fn);
1073 	if (f.open(QIODevice::ReadOnly))
1074 	{
1075 		if (progressDialog)
1076 		{
1077 			progressDialog->setTotalSteps("GI", m_records);
1078 			qApp->processEvents();
1079 		}
1080 		QDataStream ds(&f);
1081 		ds.setByteOrder(QDataStream::LittleEndian);
1082 		ds.setFloatingPointPrecision(QDataStream::SinglePrecision);
1083 		quint32 id, size;
1084 		recordCount = 0;
1085 		while (!ds.atEnd())
1086 		{
1087 			qint64 posi = ds.device()->pos();
1088 			ds >> id >> size;
1089 			recordCount++;
1090 			if (inEMFPlus)
1091 			{
1092 				if (id == U_EMR_EOF)
1093 					break;
1094 				handleComment(ds);
1095 			}
1096 			else
1097 			{
1098 				switch (id)
1099 				{
1100 					case U_EMR_HEADER:
1101 						{
1102 							qint32 bLeft, bTop, bRight, bBottom;
1103 							ds >> bLeft >> bTop >> bRight >> bBottom;
1104 							qint32 pLeft, pTop, pRight, pBottom;
1105 							ds >> pLeft >> pTop >> pRight >> pBottom;
1106 							quint32 sign, vers, bytes, records, dummy;
1107 							ds >> sign >> vers >> bytes >> records >> dummy >> dummy >> dummy >> dummy;
1108 							quint32 sxDev, syDev;
1109 							ds >> sxDev >> syDev;
1110 							quint32 sxMM, syMM;
1111 							ds >> sxMM >> syMM;
1112 							viewPextendX = bBoxDev.width();
1113 							viewPextendY = bBoxDev.height();
1114 						}
1115 						break;
1116 					case U_EMR_POLYBEZIER:
1117 						handleBezier(ds, true);
1118 						break;
1119 					case U_EMR_POLYGON:
1120 						handlePolygon(ds, true, true);
1121 						break;
1122 					case U_EMR_POLYLINE:
1123 						handlePolygon(ds, true, false);
1124 						break;
1125 					case U_EMR_POLYBEZIERTO:
1126 						handlePolyBezierTo(ds, true);
1127 						break;
1128 					case U_EMR_POLYLINETO:
1129 						handlePolylineTo(ds, true);
1130 						break;
1131 					case U_EMR_POLYPOLYLINE:
1132 						handlePolyPolygon(ds, true, false);
1133 						break;
1134 					case U_EMR_POLYPOLYGON:
1135 						handlePolyPolygon(ds, true, true);
1136 						break;
1137 					case U_EMR_SETWINDOWEXTEX:
1138 						ds >> winPextendX >> winPextendY;
1139 						currentDC.winOrigin = convertLogical2Pts(QPointF(winOrigX, winOrigY));
1140 						break;
1141 					case U_EMR_SETWINDOWORGEX:
1142 						ds >> winOrigX >> winOrigY;
1143 						if ((viewPextendX != 0) && (viewPextendY != 0))
1144 							currentDC.winOrigin = convertLogical2Pts(QPointF(winOrigX, winOrigY));
1145 						break;
1146 					case U_EMR_SETVIEWPORTEXTEX:
1147 						ds >> viewPextendX >> viewPextendY;
1148 						break;
1149 					case U_EMR_SETVIEWPORTORGEX:
1150 						{
1151 							qint32 w, h;
1152 							ds >> w >> h;
1153 							currentDC.viewOrigin = convertDevice2Pts(QPointF(w, h));
1154 						}
1155 						break;
1156 					case U_EMR_SETMAPMODE:
1157 						ds >> currentDC.m_mapMode;
1158 						break;
1159 					case U_EMR_SETBKMODE:
1160 						{
1161 							quint32 fm;
1162 							ds >> fm;
1163 							currentDC.backgroundMode = (fm == 2);
1164 						}
1165 						break;
1166 					case U_EMR_SETPOLYFILLMODE:
1167 						{
1168 							quint32 fm;
1169 							ds >> fm;
1170 							currentDC.fillRule = (fm == 1);
1171 						}
1172 						break;
1173 					case U_EMR_SETTEXTALIGN:
1174 						ds >> currentDC.textAlignment;
1175 						break;
1176 					case U_EMR_SETTEXTCOLOR:
1177 						{
1178 							quint32 brColor = getColor(ds);
1179 							QColor col((QRgb)brColor);
1180 							currentDC.CurrColorText = handleColor(col);
1181 						}
1182 						break;
1183 					case U_EMR_SETBKCOLOR:
1184 						{
1185 							quint32 brColor = getColor(ds);
1186 							QColor col((QRgb)brColor);
1187 							currentDC.backColor = handleColor(col);
1188 						}
1189 						break;
1190 					case U_EMR_MOVETOEX:
1191 						currentDC.currentPoint = getPoint(ds, true);
1192 						currentDC.Coords.svgMoveTo(currentDC.currentPoint.x(), currentDC.currentPoint.y());
1193 						break;
1194 					case U_EMR_SAVEDC:
1195 						dcStack.push(currentDC);
1196 						break;
1197 					case U_EMR_RESTOREDC:
1198 						{
1199 							invalidateClipGroup();
1200 							qint32 drop;
1201 							ds >> drop;
1202 							drop = qAbs(drop);
1203 							if (dcStack.count() >= drop)
1204 							{
1205 								for (qint32 a = 0; a < drop; a++)
1206 								{
1207 									currentDC = dcStack.pop();
1208 									if (dcStack.count() == 0)
1209 										break;
1210 								}
1211 							}
1212 							if (currentDC.clipPath.count() != 0)
1213 							{
1214 								if (checkClip(currentDC.clipPath))
1215 								{
1216 									currentDC.clipValid = true;
1217 									createClipGroup();
1218 								}
1219 							}
1220 						}
1221 						break;
1222 					case U_EMR_SETWORLDTRANSFORM:
1223 						{
1224 							float m11, m12, m21, m22, dx, dy;
1225 							ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
1226 							setWTransform(QTransform(m11, m12, m21, m22, dx, dy), 4);
1227 						}
1228 						break;
1229 					case U_EMR_MODIFYWORLDTRANSFORM:
1230 						{
1231 							float m11, m12, m21, m22, dx, dy;
1232 							ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
1233 							quint32 mod;
1234 							ds >> mod;
1235 							setWTransform(QTransform(m11, m12, m21, m22, dx, dy), mod);
1236 						}
1237 						break;
1238 					case U_EMR_SELECTOBJECT:
1239 						{
1240 							quint32 numObj;
1241 							ds >> numObj;
1242 							if (emfStyleMap.contains(numObj))
1243 							{
1244 								emfStyle sty = emfStyleMap[numObj];
1245 								if (sty.styType == U_OT_Pen)
1246 								{
1247 									currentDC.CurrColorStroke = sty.penColor;
1248 									currentDC.CurrStrokeTrans = sty.penTrans;
1249 									currentDC.penCap = sty.penCap;
1250 									currentDC.penJoin = sty.penJoin;
1251 									currentDC.penStyle = sty.penStyle;
1252 									currentDC.LineW = sty.penWidth;
1253 								}
1254 								else if (sty.styType == U_OT_Brush)
1255 								{
1256 									currentDC.CurrColorFill = sty.brushColor;
1257 									currentDC.brushStyle = sty.brushStyle;
1258 									currentDC.hatchStyle = sty.hatchStyle;
1259 									currentDC.patternName = sty.patternName;
1260 									currentDC.CurrFillTrans = sty.fillTrans;
1261 								}
1262 								else if (sty.styType == U_OT_Font)
1263 								{
1264 									currentDC.fontName = sty.fontName;
1265 									currentDC.fontSize = sty.fontSize;
1266 									currentDC.fontRotation = sty.fontRotation;
1267 								}
1268 							}
1269 							else
1270 								qDebug() << QString("U_EMR_SELECTOBJECT -> try to select nonexisting Object Nr %1!").arg(numObj);
1271 						}
1272 						break;
1273 					case U_EMR_CREATEPEN:
1274 						{
1275 							quint32 penID, penStyle, penWidth, dummy, penColor;
1276 							ds >> penID >> penStyle >> penWidth >> dummy;
1277 							penColor = getColor(ds);
1278 							handlePenDef(penID, penStyle, penWidth, penColor);
1279 						}
1280 						break;
1281 					case U_EMR_CREATEBRUSHINDIRECT:
1282 						{
1283 							quint32 brID, brStyle, brHatch, brColor;
1284 							ds >> brID >> brStyle;
1285 							brColor = getColor(ds);
1286 							ds >> brHatch;
1287 							QColor col((QRgb)brColor);
1288 							emfStyle sty;
1289 							sty.styType = U_OT_Brush;
1290 							if (brStyle == 1)
1291 								sty.brushColor = CommonStrings::None;
1292 							else
1293 								sty.brushColor = handleColor(col);
1294 							sty.brushStyle = brStyle;
1295 							sty.hatchStyle = brHatch;
1296 							sty.fillTrans = 0;
1297 							emfStyleMap.insert(brID, sty);
1298 						}
1299 						break;
1300 					case U_EMR_DELETEOBJECT:
1301 						{
1302 							quint32 numObj;
1303 							ds >> numObj;
1304 							if (numObj < U_STOCK_OBJECT)
1305 								emfStyleMap.remove(numObj);
1306 						}
1307 						break;
1308 					case U_EMR_ELLIPSE:
1309 						handleEllipse(ds);
1310 						break;
1311 					case U_EMR_RECTANGLE:
1312 						handleRectangle(ds);
1313 						break;
1314 					case U_EMR_ROUNDRECT:
1315 						handleRoundRect(ds);
1316 						break;
1317 					case U_EMR_ARC:
1318 						handleArc(ds);
1319 						break;
1320 					case U_EMR_CHORD:
1321 						handleChord(ds);
1322 						break;
1323 					case U_EMR_PIE:
1324 						handlePie(ds);
1325 						break;
1326 					case U_EMR_LINETO:
1327 						handleLineTo(ds);
1328 						break;
1329 					case U_EMR_ARCTO:
1330 						handleArcTo(ds);
1331 						break;
1332 					case U_EMR_SETARCDIRECTION:
1333 						{
1334 							quint32 fm;
1335 							ds >> fm;
1336 							currentDC.arcDirection = (fm == 1);
1337 						}
1338 						break;
1339 					case U_EMR_BEGINPATH:
1340 						inPath = true;
1341 						currentDC.Coords.resize(0);
1342 						currentDC.Coords.svgInit();
1343 						break;
1344 					case U_EMR_ENDPATH:
1345 						inPath = false;
1346 						break;
1347 					case U_EMR_CLOSEFIGURE:
1348 						currentDC.Coords.svgClosePath();
1349 						break;
1350 					case U_EMR_FILLPATH:
1351 						{
1352 							int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
1353 							PageItem* ite = m_Doc->Items->at(z);
1354 							ite->PoLine = currentDC.Coords.copy();
1355 							finishItem(ite);
1356 						}
1357 						break;
1358 					case U_EMR_STROKEANDFILLPATH:
1359 						{
1360 							int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, currentDC.CurrColorFill, currentDC.CurrColorStroke);
1361 							PageItem* ite = m_Doc->Items->at(z);
1362 							ite->PoLine = currentDC.Coords.copy();
1363 							finishItem(ite);
1364 						}
1365 						break;
1366 					case U_EMR_STROKEPATH:
1367 						{
1368 							int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
1369 							PageItem* ite = m_Doc->Items->at(z);
1370 							ite->PoLine = currentDC.Coords.copy();
1371 							finishItem(ite, false);
1372 						}
1373 						break;
1374 					case U_EMR_SELECTCLIPPATH:
1375 						{
1376 							invalidateClipGroup();
1377 							quint32 mode;
1378 							ds >> mode;
1379 							if (currentDC.Coords.count() != 0)
1380 							{
1381 								if (checkClip(currentDC.Coords))
1382 								{
1383 									currentDC.clipValid = true;
1384 									currentDC.clipPath = currentDC.Coords.copy();
1385 									createClipGroup();
1386 								}
1387 							}
1388 						}
1389 						break;
1390 					case U_EMR_EXCLUDECLIPRECT:
1391 						{
1392 							invalidateClipGroup();
1393 							QPointF p1 = getPoint(ds, true);
1394 							QPointF p2 = getPoint(ds, true);
1395 							FPointArray clipPath;
1396 							clipPath.resize(0);
1397 							clipPath.svgInit();
1398 							clipPath.svgMoveTo(p1.x(), p1.y());
1399 							clipPath.svgLineTo(p2.x(), p1.y());
1400 							clipPath.svgLineTo(p2.x(), p2.y());
1401 							clipPath.svgLineTo(p1.x(), p2.y());
1402 							clipPath.svgClosePath();
1403 							if (currentDC.clipPath.isEmpty())
1404 							{
1405 								if (checkClip(clipPath))
1406 								{
1407 									currentDC.clipPath = clipPath.copy();
1408 									currentDC.clipValid = true;
1409 									createClipGroup();
1410 								}
1411 							}
1412 							else
1413 							{
1414 								QPainterPath pathN = clipPath.toQPainterPath(true);
1415 								QPainterPath pathA = currentDC.clipPath.toQPainterPath(true);
1416 								QPainterPath resultPath = pathA.subtracted(pathN);
1417 								if (!resultPath.isEmpty())
1418 								{
1419 									FPointArray polyline;
1420 									polyline.resize(0);
1421 									polyline.fromQPainterPath(resultPath, true);
1422 									polyline.svgClosePath();
1423 									if (checkClip(polyline))
1424 									{
1425 										currentDC.clipPath = polyline.copy();
1426 										currentDC.clipValid = true;
1427 										createClipGroup();
1428 									}
1429 								}
1430 								else
1431 									currentDC.clipValid = false;
1432 							}
1433 						}
1434 						break;
1435 					case U_EMR_INTERSECTCLIPRECT:
1436 						{
1437 							invalidateClipGroup();
1438 							QPointF p1 = getPoint(ds, true);
1439 							QPointF p2 = getPoint(ds, true);
1440 							FPointArray clipPath;
1441 							clipPath.resize(0);
1442 							clipPath.svgInit();
1443 							clipPath.svgMoveTo(p1.x(), p1.y());
1444 							clipPath.svgLineTo(p2.x(), p1.y());
1445 							clipPath.svgLineTo(p2.x(), p2.y());
1446 							clipPath.svgLineTo(p1.x(), p2.y());
1447 							clipPath.svgClosePath();
1448 							if (currentDC.clipPath.isEmpty())
1449 							{
1450 								if (checkClip(clipPath))
1451 								{
1452 									currentDC.clipPath = clipPath.copy();
1453 									currentDC.clipValid = true;
1454 									createClipGroup();
1455 								}
1456 							}
1457 							else
1458 							{
1459 								QPainterPath pathN = clipPath.toQPainterPath(true);
1460 								QPainterPath pathA = currentDC.clipPath.toQPainterPath(true);
1461 								QPainterPath resultPath = pathA.intersected(pathN);
1462 								if (!resultPath.isEmpty())
1463 								{
1464 									FPointArray polyline;
1465 									polyline.resize(0);
1466 									polyline.fromQPainterPath(resultPath, true);
1467 									polyline.svgClosePath();
1468 									if (checkClip(polyline))
1469 									{
1470 										currentDC.clipPath = polyline.copy();
1471 										currentDC.clipValid = true;
1472 										createClipGroup();
1473 									}
1474 								}
1475 								else
1476 									currentDC.clipValid = false;
1477 							}
1478 						}
1479 						break;
1480 					case U_EMR_ABORTPATH:
1481 						inPath = false;
1482 						currentDC.Coords.resize(0);
1483 						currentDC.Coords.svgInit();
1484 						break;
1485 					case U_EMR_COMMENT:
1486 						handleComment(ds);
1487 						break;
1488 					case U_EMR_FILLRGN:
1489 						handleFillRegion(ds);
1490 						break;
1491 					case U_EMR_FRAMERGN:
1492 						handleFrameRegion(ds);
1493 						break;
1494 					case U_EMR_BITBLT:
1495 						{
1496 							qint32 bLeft, bTop, bRight, bBottom, dstX, dstY, dstW, dstH, srcLeft, srcTop;
1497 							quint32 offBitH, sizeBitH, offBits, sizeBits, usage, rasterOp, bgCol;
1498 							ds >> bLeft >> bTop >> bRight >> bBottom;
1499 							ds >> dstX >> dstY >> dstW >> dstH;
1500 							ds >> rasterOp;
1501 							ds >> srcLeft >> srcTop;
1502 							float m11, m12, m21, m22, dx, dy;
1503 							ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
1504 							ds >> bgCol >> usage;
1505 							ds >> offBitH >> sizeBitH >> offBits >> sizeBits;
1506 							QImage img = handleDIB(ds, posi, offBitH, sizeBitH, offBits, sizeBits);
1507 							if (!img.isNull())
1508 								handleImage(dstX, dstY, dstW, dstH, img);
1509 							else
1510 								handlePatternFill(dstX, dstY, dstW, dstH);
1511 						}
1512 						break;
1513 					case U_EMR_STRETCHBLT:
1514 						{
1515 							qint32 bLeft, bTop, bRight, bBottom, dstX, dstY, dstW, dstH, srcLeft, srcTop, srcW, srcH;
1516 							quint32 offBitH, sizeBitH, offBits, sizeBits, usage, rasterOp, bgCol;
1517 							ds >> bLeft >> bTop >> bRight >> bBottom;
1518 							ds >> dstX >> dstY >> dstW >> dstH;
1519 							ds >> rasterOp;
1520 							ds >> srcLeft >> srcTop;
1521 							float m11, m12, m21, m22, dx, dy;
1522 							ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
1523 							ds >> bgCol >> usage;
1524 							ds >> offBitH >> sizeBitH >> offBits >> sizeBits;
1525 							ds >> srcW >> srcH;
1526 							QImage img = handleDIB(ds, posi, offBitH, sizeBitH, offBits, sizeBits);
1527 							if (!img.isNull())
1528 								handleImage(dstX, dstY, dstW, dstH, img);
1529 							else
1530 								handlePatternFill(dstX, dstY, dstW, dstH);
1531 						}
1532 						break;
1533 					case U_EMR_STRETCHDIBITS:
1534 						{
1535 							qint32 bLeft, bTop, bRight, bBottom, dstX, dstY, dstW, dstH, srcLeft, srcTop, srcRight, srcBottom;
1536 							quint32 offBitH, sizeBitH, offBits, sizeBits, usage, rasterOp;
1537 							ds >> bLeft >> bTop >> bRight >> bBottom;
1538 							ds >> dstX >> dstY;
1539 							ds >> srcLeft >> srcTop >> srcRight >> srcBottom;
1540 							ds >> offBitH >> sizeBitH >> offBits >> sizeBits;
1541 							ds >> usage >> rasterOp;
1542 							ds >> dstW >> dstH;
1543 							QImage img = handleDIB(ds, posi, offBitH, sizeBitH, offBits, sizeBits);
1544 							if (!img.isNull())
1545 								handleImage(dstX, dstY, dstW, dstH, img);
1546 							else
1547 								handlePatternFill(dstX, dstY, dstW, dstH);
1548 						}
1549 						break;
1550 					case U_EMR_EXTCREATEFONTINDIRECTW:
1551 						{
1552 							quint32 foID, foFlags1, foFlags2;
1553 							qint32 foHeight, foWidth, foEsc, foOri, foWeight;
1554 							QString fontName = "";
1555 							ds >> foID >> foHeight >> foWidth >> foEsc >> foOri >> foWeight >> foFlags1 >> foFlags2;
1556 							QByteArray foNam;
1557 							for (int c = 0; c < 32; c++)
1558 							{
1559 								quint16 cc;
1560 								ds >> cc;
1561 								if (cc == 0)
1562 									break;
1563 								foNam.append(cc);
1564 							}
1565 							fontName = QString::fromUtf8(foNam.data());
1566 							emfStyle sty;
1567 							sty.styType = U_OT_Font;
1568 							sty.fontRotation = foOri / 10.0;
1569 							sty.fontSize = qAbs(convertLogical2Pts(static_cast<double>(foHeight)));
1570 							sty.fontName = fontName;
1571 							emfStyleMap.insert(foID, sty);
1572 						}
1573 						break;
1574 					case U_EMR_EXTTEXTOUTA:
1575 						handleText(ds, posi, false);
1576 						break;
1577 					case U_EMR_EXTTEXTOUTW:
1578 						handleText(ds, posi, true);
1579 						break;
1580 					case U_EMR_POLYBEZIER16:
1581 						handleBezier(ds, false);
1582 						break;
1583 					case U_EMR_POLYGON16:
1584 						handlePolygon(ds, false, true);
1585 						break;
1586 					case U_EMR_POLYLINE16:
1587 						handlePolygon(ds, false, false);
1588 						break;
1589 					case U_EMR_POLYBEZIERTO16:
1590 						handlePolyBezierTo(ds, false);
1591 						break;
1592 					case U_EMR_POLYLINETO16:
1593 						handlePolylineTo(ds, false);
1594 						break;
1595 					case U_EMR_POLYPOLYLINE16:
1596 						handlePolyPolygon(ds, false, false);
1597 						break;
1598 					case U_EMR_POLYPOLYGON16:
1599 						handlePolyPolygon(ds, false, true);
1600 						break;
1601 					case U_EMR_CREATEMONOBRUSH:
1602 						{
1603 							quint32 brID, usage, offBitH, sizeBitH, offBits, sizeBits;
1604 							ds >> brID >> usage;
1605 							ds >> offBitH >> sizeBitH >> offBits >> sizeBits;
1606 							QImage img = handleDIB(ds, posi, offBitH, sizeBitH, offBits, sizeBits);
1607 							if (!img.isNull())
1608 								createPatternFromDIB(img, brID);
1609 						}
1610 						break;
1611 					case U_EMR_CREATEDIBPATTERNBRUSHPT:
1612 						{
1613 							quint32 brID, usage, offBitH, sizeBitH, offBits, sizeBits;
1614 							ds >> brID >> usage;
1615 							ds >> offBitH >> sizeBitH >> offBits >> sizeBits;
1616 							QImage img = handleDIB(ds, posi, offBitH, sizeBitH, offBits, sizeBits);
1617 							if (!img.isNull())
1618 								createPatternFromDIB(img, brID);
1619 						}
1620 						break;
1621 					case U_EMR_EXTCREATEPEN:
1622 						{
1623 							quint32 penID, penStyle, penWidth, dummy, penColor;
1624 							ds >> penID >> dummy >> dummy >> dummy >> dummy;
1625 							ds >> penStyle >> penWidth >> dummy;
1626 							penColor = getColor(ds);
1627 							handlePenDef(penID, penStyle, penWidth, penColor);
1628 						}
1629 						break;
1630 					case U_EMR_EXTSELECTCLIPRGN:
1631 						handleSetClipRegion(ds);
1632 						break;
1633 					case U_EMR_SMALLTEXTOUT:
1634 						handleSmallText(ds);
1635 						break;
1636 					case U_EMR_POLYDRAW16:
1637 						qDebug() << "U_EMR_POLYDRAW16";
1638 						break;
1639 					case U_EMR_POLYTEXTOUTA:
1640 						qDebug() << "U_EMR_POLYTEXTOUTA";
1641 						break;
1642 					case U_EMR_POLYTEXTOUTW:
1643 						qDebug() << "U_EMR_POLYTEXTOUTW";
1644 						break;
1645 					case U_EMR_GRADIENTFILL:
1646 						qDebug() << "U_EMR_GRADIENTFILL";
1647 						break;
1648 					case U_EMR_ANGLEARC:
1649 						qDebug() << "U_EMR_ANGLEARC";
1650 						break;
1651 					case U_EMR_POLYDRAW:
1652 						qDebug() << "U_EMR_POLYDRAW";
1653 						break;
1654 					case U_EMR_SETROP2:
1655 					case U_EMR_SETSTRETCHBLTMODE:
1656 					case U_EMR_SETCOLORADJUSTMENT:
1657 					case U_EMR_FLATTENPATH:
1658 					case U_EMR_WIDENPATH:
1659 					case U_EMR_EXTFLOODFILL:
1660 					case U_EMR_INVERTRGN:
1661 					case U_EMR_PAINTRGN:
1662 					case U_EMR_MASKBLT:
1663 					case U_EMR_PLGBLT:
1664 					case U_EMR_SETDIBITSTODEVICE:
1665 					case U_EMR_SETICMMODE:
1666 					case U_EMR_CREATECOLORSPACE:
1667 					case U_EMR_SETCOLORSPACE:
1668 					case U_EMR_DELETECOLORSPACE:
1669 					case U_EMR_GLSRECORD:
1670 					case U_EMR_GLSBOUNDEDRECORD:
1671 					case U_EMR_PIXELFORMAT:
1672 					case U_EMR_DRAWESCAPE:
1673 					case U_EMR_EXTESCAPE:
1674 					case U_EMR_UNDEF107:
1675 					case U_EMR_FORCEUFIMAPPING:
1676 					case U_EMR_NAMEDESCAPE:
1677 					case U_EMR_COLORCORRECTPALETTE:
1678 					case U_EMR_SETICMPROFILEA:
1679 					case U_EMR_SETICMPROFILEW:
1680 					case U_EMR_ALPHABLEND:
1681 					case U_EMR_SETLAYOUT:
1682 					case U_EMR_TRANSPARENTBLT:
1683 					case U_EMR_UNDEF117:
1684 					case U_EMR_SETLINKEDUFIS:
1685 					case U_EMR_SETTEXTJUSTIFICATION:
1686 					case U_EMR_COLORMATCHTOTARGETW:
1687 					case U_EMR_CREATECOLORSPACEW:
1688 					case U_EMR_EOF:
1689 						//	qDebug() << "\tUnsupported Op-Code" << id2;
1690 						break;
1691 					default:
1692 						//qDebug() << "\tUnknown Op-Code" << id;
1693 						break;
1694 				}
1695 				if (id == U_EMR_EOF)
1696 					break;
1697 			}
1698 			ds.device()->seek(posi + size);
1699 			if (progressDialog)
1700 			{
1701 				progressDialog->setProgress("GI", recordCount);
1702 				qApp->processEvents();
1703 			}
1704 		}
1705 		invalidateClipGroup();
1706 		if (Elements.count() == 0)
1707 		{
1708 			if (importedColors.count() != 0)
1709 			{
1710 				for (int cd = 0; cd < importedColors.count(); cd++)
1711 				{
1712 					m_Doc->PageColors.remove(importedColors[cd]);
1713 				}
1714 			}
1715 			if (importedPatterns.count() != 0)
1716 			{
1717 				for (int cd = 0; cd < importedPatterns.count(); cd++)
1718 				{
1719 					m_Doc->docPatterns.remove(importedPatterns[cd]);
1720 				}
1721 			}
1722 		}
1723 		f.close();
1724 	}
1725 	if (progressDialog)
1726 		progressDialog->close();
1727 	return true;
1728 }
1729 
checkClip(FPointArray & clip)1730 bool EmfPlug::checkClip(FPointArray &clip)
1731 {
1732 	bool ret = true;
1733 	QRectF clipRect = clip.toQPainterPath(false).boundingRect();
1734 	if (clipRect.x() < docX)
1735 		ret = false;
1736 	if (clipRect.y() < docY)
1737 		ret = false;
1738 	if (clipRect.right() > docX + docWidth)
1739 		ret = false;
1740 	if (clipRect.bottom() > docY + docHeight)
1741 		ret = false;
1742 	return ret;
1743 }
1744 
aligntoQuadWord(QDataStream & ds)1745 void EmfPlug::aligntoQuadWord(QDataStream &ds)
1746 {
1747 	if ((ds.device()->pos() % 4) != 0)
1748 	{
1749 		qint32 adj = 4 - (ds.device()->pos() % 4);
1750 		ds.skipRawData(adj);
1751 	}
1752 }
1753 
convertDevice2Pts(double in)1754 double EmfPlug::convertDevice2Pts(double in)
1755 {
1756 	QPointF pp;
1757 	pp.setX(in);
1758 	pp = convertDevice2Pts(pp);
1759 	return pp.x();
1760 }
1761 
convertDevice2Pts(QPointF in)1762 QPointF EmfPlug::convertDevice2Pts(QPointF in)
1763 {
1764 	QPointF out;
1765 //	double scaleX = (bBoxMM.width() / 1000.0 / 2.54 * 72.0) / bBoxDev.width(); // Device -> Pts
1766 //	double scaleY = (bBoxMM.height() / 1000.0 / 2.54 * 72.0) / bBoxDev.height(); // Device -> Pts
1767 //	out.setX(in.x() * scaleX);
1768 //	out.setY(in.y() * scaleY);
1769 	out.setX(in.x() / dpiX * 72.0);
1770 	out.setY(in.y() / dpiY * 72.0);
1771 	return out;
1772 }
1773 
convertLogical2Pts(double in)1774 double EmfPlug::convertLogical2Pts(double in)
1775 {
1776 	QPointF pp;
1777 	pp.setX(in);
1778 	pp = convertLogical2Pts(pp);
1779 	return pp.x();
1780 }
1781 
convertLogical2Pts(QPointF in)1782 QPointF EmfPlug::convertLogical2Pts(QPointF in)
1783 {
1784 	QPointF out;
1785 //	double scaleX = qAbs((bBoxMM.width() / 1000.0 / 2.54 * 72.0) / bBoxDev.width()); // Device -> Pts
1786 //	double scaleY = qAbs((bBoxMM.height() / 1000.0 / 2.54 * 72.0) / bBoxDev.height()); // Device -> Pts
1787 	if (currentDC.m_mapMode == 1)
1788 	{
1789 	//	out.setX(in.x() * scaleX);
1790 	//	out.setY(in.y() * scaleY);
1791 		out.setX(in.x() / dpiX * 72.0);
1792 		out.setY(in.y() / dpiY * 72.0);
1793 	}
1794 	else if (currentDC.m_mapMode == 2)
1795 	{
1796 		out.setX(in.x() / 100.0 / 2.54 * 72.0);
1797 		out.setY(in.y() / 100.0 / 2.54 * 72.0);
1798 	}
1799 	else if (currentDC.m_mapMode == 3)
1800 	{
1801 		out.setX(in.x() / 1000.0 / 2.54 * 72.0);
1802 		out.setY(in.y() / 1000.0 / 2.54 * 72.0);
1803 	}
1804 	else if (currentDC.m_mapMode == 4)
1805 	{
1806 		out.setX(in.x() / 1000.0 * 72.0);
1807 		out.setY(in.y() / 1000.0 * 72.0);
1808 	}
1809 	else if (currentDC.m_mapMode == 5)
1810 	{
1811 		out.setX(in.x() / 10000.0 * 72.0);
1812 		out.setY(in.y() / 10000.0 * 72.0);
1813 	}
1814 	else if (currentDC.m_mapMode == 6)
1815 	{
1816 		out.setX(in.x() / 1440.0 * 72.0);
1817 		out.setY(in.y() / 1440.0 * 72.0);
1818 	}
1819 	else if ((currentDC.m_mapMode == 0x07) || (currentDC.m_mapMode == 0x08))
1820 	{
1821 		double ratioX = viewPextendX / static_cast<double>(winPextendX); // Logical --> Device
1822 		double ratioY = viewPextendY / static_cast<double>(winPextendY); // Logical --> Device
1823 		// logic --> device --> pts
1824 	//	out.setX(in.x() * ratioX * scaleX);
1825 	//	out.setY(in.y() * ratioY * scaleY);
1826 		out.setX(in.x() * ratioX);
1827 		out.setY(in.y() * ratioY);
1828 		out.setX(out.x() / dpiX * 72.0);
1829 		out.setY(out.y() / dpiY * 72.0);
1830 	}
1831 	return out;
1832 }
1833 
createPatternFromDIB(const QImage & img,quint32 brID)1834 void EmfPlug::createPatternFromDIB(const QImage& img, quint32 brID)
1835 {
1836 	if (!img.isNull())
1837 	{
1838 		QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_emf_XXXXXX.png");
1839 		tempFile->setAutoRemove(false);
1840 		if (tempFile->open())
1841 		{
1842 			QString fileName = getLongPathName(tempFile->fileName());
1843 			if (!fileName.isEmpty())
1844 			{
1845 				tempFile->close();
1846 				img.save(fileName, "PNG");
1847 				ScPattern pat = ScPattern();
1848 				pat.setDoc(m_Doc);
1849 				int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, 0, 0, 1, 1, 0, CommonStrings::None, CommonStrings::None);
1850 				PageItem* newItem = m_Doc->Items->at(z);
1851 				m_Doc->loadPict(fileName, newItem);
1852 				m_Doc->Items->takeAt(z);
1853 				newItem->isInlineImage = true;
1854 				newItem->isTempFile = true;
1855 				pat.width = newItem->pixm.qImage().width();
1856 				pat.height = newItem->pixm.qImage().height();
1857 				pat.scaleX = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
1858 				pat.scaleY = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
1859 				pat.pattern = newItem->pixm.qImage().copy();
1860 				newItem->setWidth(pat.pattern.width());
1861 				newItem->setHeight(pat.pattern.height());
1862 				newItem->SetRectFrame();
1863 				newItem->gXpos = 0.0;
1864 				newItem->gYpos = 0.0;
1865 				newItem->gWidth = pat.pattern.width();
1866 				newItem->gHeight = pat.pattern.height();
1867 				pat.items.append(newItem);
1868 				QString patternName = "Pattern_"+newItem->itemName();
1869 				m_Doc->addPattern(patternName, pat);
1870 				emfStyle sty;
1871 				sty.styType = U_OT_Brush;
1872 				sty.brushStyle = U_BT_TextureFill;
1873 				sty.patternName = patternName;
1874 				sty.fillTrans = 0;
1875 				emfStyleMap.insert(brID, sty);
1876 				importedPatterns.append(patternName);
1877 			}
1878 		}
1879 	}
1880 }
1881 
getPolyInfo(QDataStream & ds,QRectF & bounds,quint32 & count)1882 void EmfPlug::getPolyInfo(QDataStream &ds, QRectF &bounds, quint32 &count)
1883 {
1884 	qint32 bLeft, bTop, bRight, bBottom;
1885 	ds >> bLeft >> bTop >> bRight >> bBottom;
1886 	bounds = QRectF(QPointF(bLeft, bTop), QPointF(bRight, bBottom));
1887 	ds >> count;
1888 }
1889 
getPolyPoints(QDataStream & ds,quint32 count,bool length,bool closed)1890 FPointArray EmfPlug::getPolyPoints(QDataStream &ds, quint32 count, bool length, bool closed)
1891 {
1892 	bool bFirst = true;
1893 	FPointArray polyline;
1894 	polyline.svgInit();
1895 	for (quint32 a = 0; a < count; a++)
1896 	{
1897 		QPointF p = getPoint(ds, length);
1898 		if (inPath)
1899 		{
1900 			if (bFirst)
1901 			{
1902 				currentDC.Coords.svgMoveTo(p.x(), p.y());
1903 				bFirst = false;
1904 			}
1905 			else
1906 				currentDC.Coords.svgLineTo(p.x(), p.y());
1907 		}
1908 		else
1909 		{
1910 			if (bFirst)
1911 			{
1912 				polyline.svgMoveTo(p.x(), p.y());
1913 				bFirst = false;
1914 			}
1915 			else
1916 				polyline.svgLineTo(p.x(), p.y());
1917 		}
1918 	}
1919 	if (inPath)
1920 	{
1921 		if ((currentDC.Coords.size() > 4) && (closed))
1922 			currentDC.Coords.svgClosePath();
1923 	}
1924 	else
1925 	{
1926 		if ((polyline.size() > 4) && (closed))
1927 			polyline.svgClosePath();
1928 	}
1929 	return polyline;
1930 }
1931 
getPoint(QDataStream & ds,bool size)1932 QPointF EmfPlug::getPoint(QDataStream &ds, bool size)
1933 {
1934 	QPointF p;
1935 	if (size)
1936 	{
1937 		qint32 x1, y1;
1938 		ds >> x1 >> y1;
1939 		p = currentDC.m_WorldMap.map(QPointF(x1, y1));
1940 		p = convertLogical2Pts(p);
1941 	}
1942 	else
1943 	{
1944 		qint16 x1, y1;
1945 		ds >> x1 >> y1;
1946 		p = currentDC.m_WorldMap.map(QPointF(x1, y1));
1947 		p = convertLogical2Pts(p);
1948 	}
1949 	p += currentDC.viewOrigin;
1950 	return p;
1951 }
1952 
getColor(QDataStream & ds)1953 quint32 EmfPlug::getColor(QDataStream &ds)
1954 {
1955 	quint8 r, g, b, a;
1956 	ds >> r >> g >> b >> a;
1957 	return qRgba(r, g, b, 255);
1958 }
1959 
setWTransform(const QTransform & mm,quint32 how)1960 void EmfPlug::setWTransform(const QTransform& mm, quint32 how)
1961 {
1962 	if (how == 1)
1963 		currentDC.m_WorldMap = QTransform();
1964 	else if (how == 2)
1965 		currentDC.m_WorldMap = mm * currentDC.m_WorldMap;
1966 	else if (how == 3)
1967 		currentDC.m_WorldMap = currentDC.m_WorldMap * mm;
1968 	else if (how == 4)
1969 		currentDC.m_WorldMap = mm;
1970 }
1971 
intersectBoundingRect(PageItem * item,QLineF gradientVector)1972 QPointF EmfPlug::intersectBoundingRect(PageItem *item, QLineF gradientVector)
1973 {
1974 	QPointF interPoint;
1975 	QPointF gradEnd;
1976 	if (gradientVector.intersects(QLineF(0, 0, item->width(), 0), &interPoint) == QLineF::BoundedIntersection)
1977 		gradEnd = interPoint;
1978 	else if (gradientVector.intersects(QLineF(item->width(), 0, item->width(), item->height()), &interPoint) == QLineF::BoundedIntersection)
1979 		gradEnd = interPoint;
1980 	else if (gradientVector.intersects(QLineF(item->width(), item->height(), 0, item->height()), &interPoint) == QLineF::BoundedIntersection)
1981 		gradEnd = interPoint;
1982 	else if (gradientVector.intersects(QLineF(0, item->height(), 0, 0), &interPoint) == QLineF::BoundedIntersection)
1983 		gradEnd = interPoint;
1984 	return gradEnd;
1985 }
1986 
finishItem(PageItem * ite,bool fill)1987 void EmfPlug::finishItem(PageItem* ite, bool fill)
1988 {
1989 	ite->fillRule = currentDC.fillRule;
1990 	ite->ClipEdited = true;
1991 	ite->FrameType = 3;
1992 	ite->setFillShade(100.0);
1993 	ite->setLineShade(100.0);
1994 	ite->setLineJoin(currentDC.penJoin);
1995 	ite->setLineEnd(currentDC.penCap);
1996 	ite->setLineStyle(currentDC.penStyle);
1997 	if (!currentDC.dashArray.isEmpty())
1998 	{
1999 		ite->DashValues.clear();
2000 		for (int a = 0; a < currentDC.dashArray.count(); a++)
2001 		{
2002 			ite->DashValues.append(currentDC.dashArray[a] * ite->lineWidth());
2003 		}
2004 	}
2005 	ite->DashOffset = currentDC.dashOffset;
2006 	if (inEMFPlus && currentDC.alphaOn)
2007 	{
2008 		ite->setFillTransparency(currentDC.CurrFillTrans);
2009 		ite->setLineTransparency(currentDC.CurrStrokeTrans);
2010 	}
2011 	FPoint oldPos = getMinClipF(&ite->PoLine);
2012 	FPoint wh = getMaxClipF(&ite->PoLine);
2013 	ite->setWidthHeight(wh.x(),wh.y());
2014 	ite->setTextFlowMode(PageItem::TextFlowDisabled);
2015 	m_Doc->adjustItemSize(ite);
2016 	ite->moveBy(-docX, -docY, true);
2017 	ite->moveBy(-currentDC.winOrigin.x(), -currentDC.winOrigin.y());
2018 	ite->OldB2 = ite->width();
2019 	ite->OldH2 = ite->height();
2020 	ite->updateClip();
2021 	if (fill)
2022 	{
2023 		if (inEMFPlus)
2024 		{
2025 			if (currentDC.brushStyle == U_BT_HatchFill)
2026 			{
2027 				switch (currentDC.hatchStyle)
2028 				{
2029 					case U_HSP_Horizontal:
2030 						ite->setHatchParameters(0, 5, 0, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2031 						ite->GrType = Gradient_Hatch;
2032 						break;
2033 					case U_HSP_Vertical:
2034 						ite->setHatchParameters(0, 5, 90, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2035 						ite->GrType = Gradient_Hatch;
2036 						break;
2037 					case U_HSP_ForwardDiagonal:
2038 						ite->setHatchParameters(0, 5, -45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2039 						ite->GrType = Gradient_Hatch;
2040 						break;
2041 					case U_HSP_BackwardDiagonal:
2042 						ite->setHatchParameters(0, 5, 45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2043 						ite->GrType = Gradient_Hatch;
2044 						break;
2045 					case U_HSP_LargeGrid:
2046 						ite->setHatchParameters(1, 5, 0, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2047 						ite->GrType = Gradient_Hatch;
2048 						break;
2049 					case U_HSP_DiagonalCross:
2050 						ite->setHatchParameters(1, 5, 45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2051 						ite->GrType = Gradient_Hatch;
2052 						break;
2053 					default:
2054 						ite->setHatchParameters(1, 5, 45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2055 						ite->GrType = Gradient_Hatch;
2056 						break;
2057 				}
2058 			}
2059 			else if (currentDC.brushStyle == U_BT_LinearGradient)
2060 			{
2061 				ite->fill_gradient = currentDC.gradient;
2062 				QLineF gradientVectorE;
2063 				gradientVectorE.setP1(QPointF(ite->width() / 2.0, ite->height() / 2.0));
2064 				gradientVectorE.setAngle(currentDC.gradientAngle);
2065 				gradientVectorE.setLength(sqrt(ite->width() * ite->width() + ite->height() * ite->height()) / 2.0 + 1.0);
2066 				QPointF gradEnd = intersectBoundingRect(ite, gradientVectorE);
2067 				QLineF gradientVectorS;
2068 				gradientVectorS.setP1(QPointF(ite->width() / 2.0, ite->height() / 2.0));
2069 				gradientVectorS.setAngle(currentDC.gradientAngle + 180);
2070 				gradientVectorS.setLength(sqrt(ite->width() * ite->width() + ite->height() * ite->height()) / 2.0 + 1.0);
2071 				QPointF gradStart = intersectBoundingRect(ite, gradientVectorS);
2072 				ite->setGradientVector(gradStart.x(), gradStart.y(), gradEnd.x(), gradEnd.y(), gradStart.x(), gradStart.y(), 1, 0);
2073 				ite->setGradientType(6);
2074 			}
2075 			else if (currentDC.brushStyle == U_BT_PathGradient)
2076 			{
2077 				FPoint newPos = getMinClipF(&ite->PoLine);
2078 				double dx = newPos.x() - oldPos.x();
2079 				double dy = newPos.y() - oldPos.y();
2080 				QPointF cx = currentDC.gradientStart + QPointF(dx, dy);
2081 				FPointArray gpath = currentDC.gradientPath.copy();
2082 				gpath.translate(dx, dy);
2083 				for (int sub = 0; sub < 2; sub++)
2084 				{
2085 					FPointArray points;
2086 					double nearT = 0.5;
2087 					uint psize = gpath.size();
2088 					for (uint a = 0; a < psize-3; a += 4)
2089 					{
2090 						if (gpath.isMarker(a))
2091 						{
2092 							points.setMarker();
2093 							continue;
2094 						}
2095 						const FPoint& base = gpath.point(a);
2096 						const FPoint& c1 = gpath.point(a+1);
2097 						const FPoint& base2 =  gpath.point(a+2);
2098 						const FPoint& c2 = gpath.point(a+3);
2099 						FPoint cn1 = (1.0 - nearT) * base + nearT * c1;
2100 						FPoint cn2 = (1.0 - nearT) * cn1 + nearT * ((1.0 - nearT) * c1 + nearT * c2);
2101 						FPoint cn3 = (1.0 - nearT) * ((1.0 - nearT) * c1 + nearT * c2) + nearT * ((1.0 - nearT) * c2 + nearT * base2);
2102 						FPoint cn4 = (1.0 - nearT) * c2 + nearT * base2;
2103 						FPoint bp1 = (1.0 - nearT) * cn2 + nearT * cn3;
2104 						if ((base == c1) && (base2 == c2))
2105 						{
2106 							points.addPoint(base);
2107 							points.addPoint(c1);
2108 							points.addPoint(bp1);
2109 							points.addPoint(bp1);
2110 							points.addPoint(bp1);
2111 							points.addPoint(bp1);
2112 							points.addPoint(base2);
2113 							points.addPoint(c2);
2114 						}
2115 						else
2116 						{
2117 							points.addPoint(base);
2118 							points.addPoint(cn1);
2119 							points.addPoint(bp1);
2120 							points.addPoint(cn2);
2121 							points.addPoint(bp1);
2122 							points.addPoint(cn3);
2123 							points.addPoint(base2);
2124 							points.addPoint(cn4);
2125 						}
2126 					}
2127 					gpath = points;
2128 				}
2129 				ite->meshGradientPatches.clear();
2130 				FPoint center = FPoint(cx.x(), cx.y());
2131 				QList<VColorStop*> colorStops = currentDC.gradient.colorStops();
2132 				if (colorStops.count() == 2)
2133 				{
2134 					int endC = colorStops.count() - 1;
2135 					MeshPoint cP;
2136 					cP.resetTo(center);
2137 					cP.transparency = colorStops[0]->opacity;
2138 					cP.shade = 100;
2139 					cP.colorName = colorStops[0]->name;
2140 					cP.color = colorStops[0]->color;
2141 					for (int poi = 0; poi < gpath.size()-3; poi += 4)
2142 					{
2143 						meshGradientPatch patch;
2144 						patch.BL = cP;
2145 						patch.BR = cP;
2146 						if (gpath.isMarker(poi))
2147 							continue;
2148 						MeshPoint tL;
2149 						tL.resetTo(gpath.point(poi));
2150 						tL.controlRight = gpath.point(poi + 1);
2151 						tL.transparency = colorStops[endC]->opacity;
2152 						tL.shade = 100;
2153 						tL.colorName = colorStops[endC]->name;
2154 						tL.color = colorStops[endC]->color;
2155 						MeshPoint tR;
2156 						tR.resetTo(gpath.point(poi + 2));
2157 						tR.controlLeft = gpath.point(poi + 3);
2158 						tR.transparency = colorStops[endC]->opacity;
2159 						tR.shade = 100;
2160 						tR.colorName = colorStops[endC]->name;
2161 						tR.color = colorStops[endC]->color;
2162 						patch.TL = tL;
2163 						patch.TR = tR;
2164 						ite->meshGradientPatches.append(patch);
2165 					}
2166 				}
2167 				else
2168 				{
2169 					FPointArray gpath2 = gpath.copy();
2170 					QTransform mm;
2171 					mm.translate(cx.x(), cx.y());
2172 					mm.scale(colorStops[1]->rampPoint, colorStops[1]->rampPoint);
2173 					mm.translate(-cx.x(), -cx.y());
2174 					gpath2.map(mm);
2175 					MeshPoint cP;
2176 					cP.resetTo(center);
2177 					cP.transparency = colorStops[0]->opacity;
2178 					cP.shade = 100;
2179 					cP.colorName = colorStops[0]->name;
2180 					cP.color = colorStops[0]->color;
2181 					for (int poi = 0; poi < gpath2.size()-3; poi += 4)
2182 					{
2183 						meshGradientPatch patch;
2184 						patch.BL = cP;
2185 						patch.BR = cP;
2186 						if (gpath.isMarker(poi))
2187 							continue;
2188 						MeshPoint tL;
2189 						tL.resetTo(gpath2.point(poi));
2190 						tL.controlRight = gpath2.point(poi + 1);
2191 						tL.transparency = colorStops[1]->opacity;
2192 						tL.shade = 100;
2193 						tL.colorName = colorStops[1]->name;
2194 						tL.color = colorStops[1]->color;
2195 						MeshPoint tR;
2196 						tR.resetTo(gpath2.point(poi + 2));
2197 						tR.controlLeft = gpath2.point(poi + 3);
2198 						tR.transparency = colorStops[1]->opacity;
2199 						tR.shade = 100;
2200 						tR.colorName = colorStops[1]->name;
2201 						tR.color = colorStops[1]->color;
2202 						patch.TL = tL;
2203 						patch.TR = tR;
2204 						ite->meshGradientPatches.append(patch);
2205 					}
2206 					for (int cstp = 2; cstp < colorStops.count(); cstp++)
2207 					{
2208 						FPointArray gpath3 = gpath2.copy();
2209 						gpath2 = gpath.copy();
2210 						QTransform mm;
2211 						mm.translate(cx.x(), cx.y());
2212 						mm.scale(colorStops[cstp]->rampPoint, colorStops[cstp]->rampPoint);
2213 						mm.translate(-cx.x(), -cx.y());
2214 						gpath2.map(mm);
2215 						for (int poi = 0; poi < gpath2.size()-3; poi += 4)
2216 						{
2217 							if (gpath.isMarker(poi))
2218 								continue;
2219 							meshGradientPatch patch;
2220 							MeshPoint bL;
2221 							bL.resetTo(gpath3.point(poi));
2222 							bL.controlRight = gpath3.point(poi + 1);
2223 							bL.transparency = colorStops[cstp - 1]->opacity;
2224 							bL.shade = 100;
2225 							bL.colorName = colorStops[cstp - 1]->name;
2226 							bL.color = colorStops[cstp - 1]->color;
2227 							patch.BL = bL;
2228 							MeshPoint bR;
2229 							bR.resetTo(gpath3.point(poi + 2));
2230 							bR.controlLeft = gpath3.point(poi + 3);
2231 							bR.transparency = colorStops[cstp - 1]->opacity;
2232 							bR.shade = 100;
2233 							bR.colorName = colorStops[cstp - 1]->name;
2234 							bR.color = colorStops[cstp - 1]->color;
2235 							patch.BR = bR;
2236 							MeshPoint tL;
2237 							tL.resetTo(gpath2.point(poi));
2238 							tL.controlRight = gpath2.point(poi + 1);
2239 							tL.transparency = colorStops[cstp]->opacity;
2240 							tL.shade = 100;
2241 							tL.colorName = colorStops[cstp]->name;
2242 							tL.color = colorStops[cstp]->color;
2243 							MeshPoint tR;
2244 							tR.resetTo(gpath2.point(poi + 2));
2245 							tR.controlLeft = gpath2.point(poi + 3);
2246 							tR.transparency = colorStops[cstp]->opacity;
2247 							tR.shade = 100;
2248 							tR.colorName = colorStops[cstp]->name;
2249 							tR.color = colorStops[cstp]->color;
2250 							patch.TL = tL;
2251 							patch.TR = tR;
2252 							ite->meshGradientPatches.append(patch);
2253 						}
2254 					}
2255 				}
2256 				ite->GrType = Gradient_PatchMesh;
2257 			}
2258 			else if (currentDC.brushStyle == U_BT_TextureFill)
2259 			{
2260 				if (m_Doc->docPatterns.contains(currentDC.patternName))
2261 				{
2262 					ite->setPattern(currentDC.patternName);
2263 					ScPattern pat = m_Doc->docPatterns[currentDC.patternName];
2264 					if ((pat.height < ite->height()) || (pat.width < ite->width()))
2265 					{
2266 						if (currentDC.patternMode == 1)
2267 							ite->setPatternFlip(true, false);
2268 						else if (currentDC.patternMode == 2)
2269 							ite->setPatternFlip(false, true);
2270 						else if (currentDC.patternMode == 3)
2271 							ite->setPatternFlip(true, true);
2272 						else if (currentDC.patternMode == 4)
2273 						{
2274 							double sx = ite->width() / pat.width * 100;
2275 							double sy = ite->height() / pat.height * 100;
2276 							ite->setPatternTransform(sx, sy, 0, 0, 0, 0, 0);
2277 						}
2278 					}
2279 					else
2280 					{
2281 						double sx = ite->width() / pat.width * 100;
2282 						double sy = ite->height() / pat.height * 100;
2283 						ite->setPatternTransform(sx, sy, 0, 0, 0, 0, 0);
2284 					}
2285 					ite->GrType = Gradient_Pattern;
2286 				}
2287 			}
2288 		}
2289 		else
2290 		{
2291 			if (currentDC.brushStyle == U_BT_HatchFill)
2292 			{
2293 				switch (currentDC.hatchStyle)
2294 				{
2295 					case U_HSP_Horizontal:
2296 						ite->setHatchParameters(0, 5, 0, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2297 						ite->GrType = Gradient_Hatch;
2298 						break;
2299 					case U_HSP_Vertical:
2300 						ite->setHatchParameters(0, 5, 90, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2301 						ite->GrType = Gradient_Hatch;
2302 						break;
2303 					case U_HSP_ForwardDiagonal:
2304 						ite->setHatchParameters(0, 5, -45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2305 						ite->GrType = Gradient_Hatch;
2306 						break;
2307 					case U_HSP_BackwardDiagonal:
2308 						ite->setHatchParameters(0, 5, 45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2309 						ite->GrType = Gradient_Hatch;
2310 						break;
2311 					case U_HSP_LargeGrid:
2312 						ite->setHatchParameters(1, 5, 0, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2313 						ite->GrType = Gradient_Hatch;
2314 						break;
2315 					case U_HSP_DiagonalCross:
2316 						ite->setHatchParameters(1, 5, 45, currentDC.backgroundMode, currentDC.backColor, currentDC.CurrColorFill);
2317 						ite->GrType = Gradient_Hatch;
2318 						break;
2319 					case 6:
2320 					case 7:
2321 						ite->setFillColor(currentDC.CurrColorFill);
2322 						break;
2323 					case 8:
2324 					case 9:
2325 						ite->setFillColor(currentDC.CurrColorText);
2326 						break;
2327 					case 10:
2328 					case 11:
2329 						ite->setFillColor(currentDC.backColor);
2330 						break;
2331 					default:
2332 						break;
2333 				}
2334 			}
2335 			else if (currentDC.brushStyle == U_BT_TextureFill)
2336 			{
2337 				ite->setPattern(currentDC.patternName);
2338 				ite->GrType = Gradient_Pattern;
2339 			}
2340 		}
2341 	}
2342 	if (clipGroup != nullptr)
2343 	{
2344 		QList<PageItem*> itemList;
2345 		itemList.append(ite);
2346 		m_Doc->groupObjectsToItem(clipGroup, itemList);
2347 	}
2348 	else
2349 		Elements.append(ite);
2350 }
2351 
invalidateClipGroup()2352 void EmfPlug::invalidateClipGroup()
2353 {
2354 	if (clipGroup != nullptr)
2355 	{
2356 		if (clipGroup->asGroupFrame()->groupItemList.count() == 0)
2357 		{
2358 			Elements.removeAll(clipGroup);
2359 			m_Doc->Items->removeAll(clipGroup);
2360 			delete clipGroup;
2361 		}
2362 	}
2363 	clipGroup = nullptr;
2364 }
2365 
createClipGroup()2366 void EmfPlug::createClipGroup()
2367 {
2368 	if (currentDC.clipValid)
2369 	{
2370 		int z = m_Doc->itemAdd(PageItem::Group, PageItem::Unspecified, baseX, baseY, 10, 10, 0, CommonStrings::None, CommonStrings::None);
2371 		PageItem* ite = m_Doc->Items->at(z);
2372 		ite->PoLine = currentDC.clipPath.copy();
2373 		ite->setFillEvenOdd(false);
2374 		ite->ClipEdited = true;
2375 		ite->FrameType = 3;
2376 		FPoint wh = getMaxClipF(&ite->PoLine);
2377 		ite->setWidthHeight(wh.x(),wh.y());
2378 		ite->setTextFlowMode(PageItem::TextFlowDisabled);
2379 		m_Doc->adjustItemSize(ite, true);
2380 		ite->moveBy(-docX, -docY, true);
2381 		ite->moveBy(-currentDC.winOrigin.x(), -currentDC.winOrigin.y());
2382 		ite->OldB2 = ite->width();
2383 		ite->OldH2 = ite->height();
2384 		ite->updateClip();
2385 		ite->OwnPage = m_Doc->OnPage(ite);
2386 		m_Doc->GroupOnPage(ite);
2387 		clipGroup = ite;
2388 		Elements.append(ite);
2389 	}
2390 }
2391 
handleComment(QDataStream & ds)2392 void EmfPlug::handleComment(QDataStream &ds)
2393 {
2394 	quint32 commTyp, dtaSize;
2395 	ds >> dtaSize;
2396 	ds >> commTyp;
2397 	if (commTyp == 0x2B464D45)
2398 		handleEMFPlus(ds, dtaSize);
2399 }
2400 
handleEllipse(QDataStream & ds)2401 void EmfPlug::handleEllipse(QDataStream &ds)
2402 {
2403 	QPointF p1 = getPoint(ds, true);
2404 	QPointF p2 = getPoint(ds, true);
2405 	QRectF BoxDev = QRectF(p1, p2);
2406 	if (inPath)
2407 	{
2408 		QPainterPath painterPath;
2409 		painterPath.addEllipse(BoxDev);
2410 		FPointArray  pointArray;
2411 		pointArray.fromQPainterPath(painterPath);
2412 		currentDC.Coords.setMarker();
2413 		currentDC.Coords += pointArray;
2414 	}
2415 	else
2416 	{
2417 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, currentDC.CurrColorFill, currentDC.CurrColorStroke);
2418 		PageItem* ite = m_Doc->Items->at(z);
2419 		QTransform mm(1.0, 0.0, 0.0, 1.0, BoxDev.x(), BoxDev.y());
2420 		ite->PoLine.map(mm);
2421 		finishItem(ite);
2422 	}
2423 }
2424 
handleRectangle(QDataStream & ds)2425 void EmfPlug::handleRectangle(QDataStream &ds)
2426 {
2427 	QPointF p1 = getPoint(ds, true);
2428 	QPointF p2 = getPoint(ds, true);
2429 	QRectF BoxDev = QRectF(p1, p2);
2430 	if (inPath)
2431 	{
2432 		QPainterPath painterPath;
2433 		painterPath.addRect(BoxDev);
2434 		FPointArray  pointArray;
2435 		pointArray.fromQPainterPath(painterPath);
2436 		currentDC.Coords.setMarker();
2437 		currentDC.Coords += pointArray;
2438 	}
2439 	else
2440 	{
2441 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, currentDC.CurrColorFill, currentDC.CurrColorStroke);
2442 		PageItem* ite = m_Doc->Items->at(z);
2443 		QTransform mm(1.0, 0.0, 0.0, 1.0, BoxDev.x(), BoxDev.y());
2444 		ite->PoLine.map(mm);
2445 		finishItem(ite);
2446 	}
2447 }
2448 
handleRoundRect(QDataStream & ds)2449 void EmfPlug::handleRoundRect(QDataStream &ds)
2450 {
2451 	QPointF p1 = getPoint(ds, true);
2452 	QPointF p2 = getPoint(ds, true);
2453 	qint32 x1, y1;
2454 	ds >> x1 >> y1;
2455 	QPointF p3 = convertLogical2Pts(QPointF(x1, y1));
2456 	QRectF BoxDev = QRectF(p1, p2);
2457 	if (inPath)
2458 	{
2459 		QPainterPath painterPath;
2460 		painterPath.addRoundedRect(BoxDev, p3.x(), p3.y());
2461 		FPointArray  pointArray;
2462 		pointArray.fromQPainterPath(painterPath);
2463 		currentDC.Coords.setMarker();
2464 		currentDC.Coords += pointArray;
2465 	}
2466 	else
2467 	{
2468 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, currentDC.CurrColorFill, currentDC.CurrColorStroke);
2469 		PageItem* ite = m_Doc->Items->at(z);
2470 		QTransform mm(1.0, 0.0, 0.0, 1.0, BoxDev.x(), BoxDev.y());
2471 		ite->PoLine.map(mm);
2472 		finishItem(ite);
2473 		if ((p3.x() != 0.0) || (p3.y() != 0.0))
2474 		{
2475 			ite->setCornerRadius(qMax(p3.x(), p3.y()));
2476 			ite->SetFrameRound();
2477 			m_Doc->setRedrawBounding(ite);
2478 		}
2479 	}
2480 }
2481 
handlePolyBezierTo(QDataStream & ds,bool size)2482 void EmfPlug::handlePolyBezierTo(QDataStream &ds, bool size)
2483 {
2484 	QRectF BoxDev;
2485 	quint32 countP;
2486 	getPolyInfo(ds, BoxDev, countP);
2487 	for (quint32 a = 0; a < countP; a += 3)
2488 	{
2489 		QPointF p1 = getPoint(ds, size);
2490 		QPointF p2 = getPoint(ds, size);
2491 		QPointF p3 = getPoint(ds, size);
2492 		if (currentDC.Coords.count() == 0)
2493 			currentDC.Coords.svgMoveTo(currentDC.currentPoint.x(), currentDC.currentPoint.y());
2494 		currentDC.Coords.svgCurveToCubic(p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y());
2495 		currentDC.currentPoint = p3;
2496 	}
2497 	if (!inPath)
2498 	{
2499 		if (currentDC.Coords.count() != 0)
2500 		{
2501 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
2502 			PageItem* ite = m_Doc->Items->at(z);
2503 			ite->PoLine = currentDC.Coords.copy();
2504 			finishItem(ite, false);
2505 			currentDC.Coords.resize(0);
2506 			currentDC.Coords.svgInit();
2507 		}
2508 	}
2509 }
2510 
handlePolylineTo(QDataStream & ds,bool size)2511 void EmfPlug::handlePolylineTo(QDataStream &ds, bool size)
2512 {
2513 	QRectF bBoxDev;
2514 	quint32 countP;
2515 	getPolyInfo(ds, bBoxDev, countP);
2516 	for (quint32 a = 0; a < countP; a++)
2517 	{
2518 		QPointF p1 = getPoint(ds, size);
2519 		if (currentDC.Coords.count() == 0)
2520 			currentDC.Coords.svgMoveTo(currentDC.currentPoint.x(), currentDC.currentPoint.y());
2521 		currentDC.Coords.svgLineTo(p1.x(), p1.y());
2522 		currentDC.currentPoint = p1;
2523 	}
2524 	if (!inPath)
2525 	{
2526 		if (currentDC.Coords.count() != 0)
2527 		{
2528 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
2529 			PageItem* ite = m_Doc->Items->at(z);
2530 			ite->PoLine = currentDC.Coords.copy();
2531 			finishItem(ite, false);
2532 			currentDC.Coords.resize(0);
2533 			currentDC.Coords.svgInit();
2534 		}
2535 	}
2536 }
2537 
handleLineTo(QDataStream & ds)2538 void EmfPlug::handleLineTo(QDataStream &ds)
2539 {
2540 	QPointF p1 = getPoint(ds, true);
2541 	if (currentDC.Coords.count() == 0)
2542 	{
2543 		currentDC.Coords.svgInit();
2544 		currentDC.Coords.svgMoveTo(currentDC.currentPoint.x(), currentDC.currentPoint.y());
2545 	}
2546 	currentDC.Coords.svgLineTo(p1.x(), p1.y());
2547 	currentDC.currentPoint = p1;
2548 	if (!inPath)
2549 	{
2550 		if (currentDC.Coords.count() != 0)
2551 		{
2552 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
2553 			PageItem* ite = m_Doc->Items->at(z);
2554 			ite->PoLine = currentDC.Coords.copy();
2555 			finishItem(ite, false);
2556 			currentDC.Coords.resize(0);
2557 			currentDC.Coords.svgInit();
2558 		}
2559 	}
2560 }
2561 
handleArc(QDataStream & ds)2562 void EmfPlug::handleArc(QDataStream &ds)
2563 {
2564 	QPointF p1 = getPoint(ds, true);
2565 	QPointF p2 = getPoint(ds, true);
2566 	QRectF BoxDev = QRectF(p1, p2);
2567 	QPointF st = getPoint(ds, true);
2568 	QPointF en = getPoint(ds, true);
2569 	QLineF stlin = QLineF(BoxDev.center(), st);
2570 	QLineF enlin = QLineF(BoxDev.center(), en);
2571 	FPointArray  pointArray;
2572 	QPainterPath painterPath;
2573 	painterPath.arcMoveTo(BoxDev, stlin.angle());
2574 	if (currentDC.arcDirection)
2575 		painterPath.arcTo(BoxDev, stlin.angle(), enlin.angle() - stlin.angle());
2576 	else
2577 		painterPath.arcTo(BoxDev, stlin.angle(), stlin.angle() - enlin.angle());
2578 	pointArray.fromQPainterPath(painterPath);
2579 	if (pointArray.count() != 0)
2580 	{
2581 		if (inPath)
2582 		{
2583 			currentDC.Coords += pointArray;
2584 			currentDC.currentPoint = en;
2585 		}
2586 		else
2587 		{
2588 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
2589 			PageItem* ite = m_Doc->Items->at(z);
2590 			ite->PoLine = pointArray.copy();
2591 			finishItem(ite, false);
2592 		}
2593 	}
2594 }
2595 
handleArcTo(QDataStream & ds)2596 void EmfPlug::handleArcTo(QDataStream &ds)
2597 {
2598 	QPointF p1 = getPoint(ds, true);
2599 	QPointF p2 = getPoint(ds, true);
2600 	QRectF BoxDev = QRectF(p1, p2);
2601 	QPointF st = getPoint(ds, true);
2602 	QPointF en = getPoint(ds, true);
2603 	QLineF stlin = QLineF(BoxDev.center(), st);
2604 	QLineF enlin = QLineF(BoxDev.center(), en);
2605 	if (inPath)
2606 	{
2607 		if (enlin.angleTo(stlin) > 180)
2608 		{
2609 		//	currentDC.Coords.svgMoveTo(st.x(), st.y());
2610 			currentDC.Coords.svgArcTo(BoxDev.width() / 2.0, BoxDev.height() / 2.0, 0, enlin.angleTo(stlin) < 180, stlin.angleTo(enlin) > 180, en.x(), en.y());
2611 		}
2612 		else
2613 		{
2614 		//	currentDC.Coords.svgMoveTo(st.x(), st.y());
2615 			currentDC.Coords.svgArcTo(BoxDev.width() / 2.0, BoxDev.height() / 2.0, 0, enlin.angleTo(stlin) > 180, stlin.angleTo(enlin) > 180, en.x(), en.y());
2616 		}
2617 		currentDC.currentPoint = en;
2618 	}
2619 	else
2620 	{
2621 		FPointArray  pointArray;
2622 		QPainterPath painterPath;
2623 		double ang1 = stlin.angleTo(enlin);
2624 		if (currentDC.arcDirection)
2625 		{
2626 			painterPath.arcMoveTo(BoxDev, stlin.angle());
2627 			painterPath.arcTo(BoxDev, stlin.angle(), ang1);
2628 		}
2629 		else
2630 		{
2631 			painterPath.arcMoveTo(BoxDev, stlin.angle());
2632 			painterPath.arcTo(BoxDev, stlin.angle(), -(360 - ang1));
2633 		}
2634 		pointArray.fromQPainterPath(painterPath);
2635 		if (pointArray.count() != 0)
2636 		{
2637 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
2638 			PageItem* ite = m_Doc->Items->at(z);
2639 			ite->PoLine = pointArray.copy();
2640 			finishItem(ite, false);
2641 		}
2642 	}
2643 }
2644 
handleChord(QDataStream & ds)2645 void EmfPlug::handleChord(QDataStream &ds)
2646 {
2647 	QPointF p1 = getPoint(ds, true);
2648 	QPointF p2 = getPoint(ds, true);
2649 	QRectF BoxDev = QRectF(p1, p2);
2650 	QPointF st = getPoint(ds, true);
2651 	QPointF en = getPoint(ds, true);
2652 	QLineF stlin = QLineF(BoxDev.center(), st);
2653 	QLineF enlin = QLineF(BoxDev.center(), en);
2654 	FPointArray  pointArray;
2655 	QPainterPath painterPath;
2656 	QPointF firstPoint;
2657 	double ang1 = stlin.angleTo(enlin);
2658 	if (currentDC.arcDirection)
2659 	{
2660 		painterPath.arcMoveTo(BoxDev, stlin.angle());
2661 		firstPoint = painterPath.currentPosition();
2662 		painterPath.arcTo(BoxDev, stlin.angle(), ang1);
2663 	}
2664 	else
2665 	{
2666 		painterPath.arcMoveTo(BoxDev, stlin.angle());
2667 		firstPoint = painterPath.currentPosition();
2668 		painterPath.arcTo(BoxDev, stlin.angle(), -(360 - ang1));
2669 	}
2670 	painterPath.lineTo(firstPoint);
2671 	pointArray.fromQPainterPath(painterPath);
2672 	if (pointArray.count() != 0)
2673 	{
2674 		if (inPath)
2675 		{
2676 			currentDC.Coords += pointArray;
2677 			currentDC.currentPoint = firstPoint;
2678 		}
2679 		else
2680 		{
2681 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, currentDC.CurrColorFill, currentDC.CurrColorStroke);
2682 			PageItem* ite = m_Doc->Items->at(z);
2683 			ite->PoLine = pointArray.copy();
2684 			finishItem(ite);
2685 		}
2686 	}
2687 }
2688 
handlePie(QDataStream & ds)2689 void EmfPlug::handlePie(QDataStream &ds)
2690 {
2691 	QPointF p1 = getPoint(ds, true);
2692 	QPointF p2 = getPoint(ds, true);
2693 	QRectF BoxDev = QRectF(p1, p2);
2694 	QPointF st = getPoint(ds, true);
2695 	QPointF en = getPoint(ds, true);
2696 	QLineF stlin = QLineF(BoxDev.center(), st);
2697 	QLineF enlin = QLineF(BoxDev.center(), en);
2698 	FPointArray  pointArray;
2699 	QPainterPath painterPath;
2700 	QPointF firstPoint;
2701 	double ang1 = stlin.angleTo(enlin);
2702 	if (currentDC.arcDirection)
2703 	{
2704 		painterPath.arcMoveTo(BoxDev, stlin.angle());
2705 		firstPoint = painterPath.currentPosition();
2706 		painterPath.arcTo(BoxDev, stlin.angle(), ang1);
2707 	}
2708 	else
2709 	{
2710 		painterPath.arcMoveTo(BoxDev, stlin.angle());
2711 		firstPoint = painterPath.currentPosition();
2712 		painterPath.arcTo(BoxDev, stlin.angle(), -(360 - ang1));
2713 	}
2714 	painterPath.lineTo(BoxDev.center());
2715 	painterPath.lineTo(firstPoint);
2716 	pointArray.fromQPainterPath(painterPath);
2717 	if (pointArray.count() != 0)
2718 	{
2719 		if (inPath)
2720 		{
2721 			currentDC.Coords += pointArray;
2722 			currentDC.currentPoint = firstPoint;
2723 		}
2724 		else
2725 		{
2726 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, BoxDev.width(), BoxDev.height(), currentDC.LineW, currentDC.CurrColorFill, currentDC.CurrColorStroke);
2727 			PageItem* ite = m_Doc->Items->at(z);
2728 			ite->PoLine = pointArray.copy();
2729 			finishItem(ite);
2730 		}
2731 	}
2732 }
2733 
handleSmallText(QDataStream & ds)2734 void EmfPlug::handleSmallText(QDataStream &ds)
2735 {
2736 	qint32 bLeft, bTop, bRight, bBottom;
2737 	quint32 grMode, numChar, txOpts;
2738 	float sx, sy;
2739 	QPointF p1 = getPoint(ds, true);
2740 	if (currentDC.textAlignment &0x0001)
2741 		p1 = currentDC.currentPoint;
2742 	ds >> numChar >> txOpts >> grMode;
2743 	ds >> sx >> sy;
2744 	if (!(txOpts & 0x00000100))
2745 		ds >> bLeft >> bTop >> bRight >> bBottom;
2746 	QString aTxt = "";
2747 	for (quint32 a = 0; a < numChar; a++)
2748 	{
2749 		if (txOpts & 0x00000200)
2750 		{
2751 			quint8 cc;
2752 			ds >> cc;
2753 			aTxt.append(QChar(cc));
2754 		}
2755 		else
2756 		{
2757 			quint16 cc;
2758 			ds >> cc;
2759 			aTxt.append(QChar(cc));
2760 		}
2761 	}
2762 	if (aTxt.isEmpty())
2763 		return;
2764 	FPointArray textPath;
2765 	QPainterPath painterPath;
2766 	QFont font = QFont(currentDC.fontName, currentDC.fontSize);
2767 	font.setPixelSize(currentDC.fontSize);
2768 	painterPath.addText(p1.x(), p1.y(), font, aTxt);
2769 	QFontMetricsF fm(font);
2770 	if (currentDC.textAlignment == 0)
2771 		painterPath.translate(0, fm.ascent());
2772 	if (currentDC.textAlignment & 0x0002)
2773 		painterPath.translate(-fm.horizontalAdvance(aTxt), 0);
2774 	else if (currentDC.textAlignment & 0x0006)
2775 		painterPath.translate(-fm.horizontalAdvance(aTxt) / 2.0, 0);
2776 	if (currentDC.textAlignment & 0x0008)
2777 		painterPath.translate(0, fm.descent());
2778 	textPath.fromQPainterPath(painterPath);
2779 	if (!textPath.empty())
2780 	{
2781 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorText, CommonStrings::None);
2782 		PageItem* ite = m_Doc->Items->at(z);
2783 		ite->PoLine = textPath.copy();
2784 		finishItem(ite);
2785 		if (currentDC.fontRotation != 0)
2786 			ite->setRotation(-currentDC.fontRotation, true);
2787 	}
2788 	if (currentDC.textAlignment & 0x0001)
2789 	{
2790 		if (currentDC.textAlignment & 0x0002)
2791 			currentDC.currentPoint = p1;
2792 		else if (currentDC.textAlignment & 0x0006)
2793 			currentDC.currentPoint = QPointF(p1.x() + (fm.horizontalAdvance(aTxt) / 2.0), p1.y());
2794 		else
2795 			currentDC.currentPoint = QPointF(p1.x() + fm.horizontalAdvance(aTxt), p1.y());
2796 	}
2797 }
2798 
handleText(QDataStream & ds,qint64 posi,bool size)2799 void EmfPlug::handleText(QDataStream &ds, qint64 posi, bool size)
2800 {
2801 	QString aTxt = "";
2802 	QPainterPath painterPath;
2803 	qint32 bLeft, bTop, bRight, bBottom, oLeft, oTop, oRight, oBottom;
2804 	quint32 grMode, numChar, offTxt, txOpts, offDx;
2805 	float sx, sy;
2806 	ds >> bLeft >> bTop >> bRight >> bBottom;
2807 	ds >> grMode;
2808 	ds >> sx >> sy;
2809 	QPointF p1 = getPoint(ds, true);
2810 	if (currentDC.textAlignment &0x0001)
2811 		p1 = currentDC.currentPoint;
2812 	ds >> numChar >> offTxt >> txOpts;
2813 	ds >> oLeft >> oTop >> oRight >> oBottom;
2814 	ds >> offDx;
2815 	ds.device()->seek(posi + offTxt);
2816 	QFont font = QFont(currentDC.fontName, currentDC.fontSize);
2817 	font.setPixelSize(currentDC.fontSize);
2818 	QFontMetricsF fm(font);
2819 	double aTextWidth = 0;
2820 	if (txOpts & 0x00000010)
2821 	{
2822 		QList<quint32> glyphs;
2823 		for (quint32 a = 0; a < numChar; a++)
2824 		{
2825 			if (size)
2826 			{
2827 				quint16 cc;
2828 				ds >> cc;
2829 				glyphs.append(cc);
2830 			}
2831 			else
2832 			{
2833 				quint8 cc;
2834 				ds >> cc;
2835 				glyphs.append(cc);
2836 			}
2837 		}
2838 		ds.device()->seek(posi + offDx);
2839 		QList<quint32> dxTxt;
2840 		for (quint32 a = 0; a < numChar; a++)
2841 		{
2842 			quint32 cc;
2843 			ds >> cc;
2844 			dxTxt.append(cc);
2845 		}
2846 		QRawFont rFont = QRawFont::fromFont(font);
2847 		double startX = p1.x();
2848 		for (quint32 a = 0; a < numChar; a++)
2849 		{
2850 			QPainterPath gPath = rFont.pathForGlyph(glyphs[a]);
2851 			gPath.translate(startX, p1.y());
2852 			painterPath.addPath(gPath);
2853 			startX += convertLogical2Pts(static_cast<double>(dxTxt[a]));
2854 		}
2855 		aTextWidth = painterPath.boundingRect().width();
2856 	}
2857 	else
2858 	{
2859 		for (quint32 a = 0; a < numChar; a++)
2860 		{
2861 			if (size)
2862 			{
2863 				quint16 cc;
2864 				ds >> cc;
2865 				aTxt.append(QChar(cc));
2866 			}
2867 			else
2868 			{
2869 				quint8 cc;
2870 				ds >> cc;
2871 				aTxt.append(QChar(cc));
2872 			}
2873 		}
2874 		ds.device()->seek(posi + offDx);
2875 		QList<quint32> dxTxt;
2876 		for (quint32 a = 0; a < numChar; a++)
2877 		{
2878 			quint32 cc;
2879 			ds >> cc;
2880 			dxTxt.append(cc);
2881 		}
2882 		if (aTxt.isEmpty())
2883 			return;
2884 		if (font.exactMatch())
2885 		{
2886 			double startX = p1.x();
2887 			for (quint32 a = 0; a < numChar; a++)
2888 			{
2889 				painterPath.addText(startX, p1.y(), font, aTxt.at(a));
2890 				startX += convertLogical2Pts(static_cast<double>(dxTxt[a]));
2891 			}
2892 		}
2893 		else
2894 			painterPath.addText(p1.x(), p1.y(), font, aTxt);
2895 		aTextWidth = fm.horizontalAdvance(aTxt);
2896 	}
2897 	if (currentDC.textAlignment == 0)
2898 		painterPath.translate(0, fm.ascent());
2899 	if (currentDC.textAlignment & 0x0002)
2900 		painterPath.translate(-aTextWidth, 0);
2901 	else if (currentDC.textAlignment & 0x0006)
2902 		painterPath.translate(-aTextWidth / 2.0, 0);
2903 	if (currentDC.textAlignment & 0x0008)
2904 		painterPath.translate(0, fm.descent());
2905 	QTransform bm = currentDC.m_WorldMap;
2906 	bm = QTransform(bm.m11(), bm.m12(), bm.m21(), bm.m22(), 0, 0);
2907 	painterPath = bm.map(painterPath);
2908 	FPointArray textPath;
2909 	textPath.fromQPainterPath(painterPath);
2910 	if (!textPath.empty())
2911 	{
2912 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorText, CommonStrings::None);
2913 		PageItem* ite = m_Doc->Items->at(z);
2914 		ite->PoLine = textPath.copy();
2915 		finishItem(ite);
2916 		if (currentDC.fontRotation != 0)
2917 			ite->setRotation(-currentDC.fontRotation, true);
2918 	}
2919 	if (currentDC.textAlignment & 0x0001)
2920 	{
2921 		if (currentDC.textAlignment & 0x0002)
2922 			currentDC.currentPoint = p1;
2923 		else if (currentDC.textAlignment & 0x0006)
2924 			currentDC.currentPoint = QPointF(p1.x() + (aTextWidth / 2.0), p1.y());
2925 		else
2926 			currentDC.currentPoint = QPointF(p1.x() + aTextWidth, p1.y());
2927 	}
2928 }
2929 
handleImage(qint32 dstX,qint32 dstY,qint32 dstW,qint32 dstH,const QImage & img)2930 void EmfPlug::handleImage(qint32 dstX, qint32 dstY, qint32 dstW, qint32 dstH, const QImage& img)
2931 {
2932 	QTransform bm = currentDC.m_WorldMap;
2933 	if ((currentDC.m_mapMode == 0x07) || (currentDC.m_mapMode == 0x08))
2934 	{
2935 		double ratioX = viewPextendX / static_cast<double>(winPextendX); // Logical --> Device
2936 		double ratioY = viewPextendY / static_cast<double>(winPextendY); // Logical --> Device
2937 		bm = QTransform(bm.m11() * ratioX, bm.m12() * ratioY, bm.m21() * ratioX, bm.m22() * ratioY, bm.dx() * ratioX, bm.dy() * ratioY);
2938 	}
2939 	QPointF p = currentDC.m_WorldMap.map(QPointF(dstX, dstY));
2940 	p = convertLogical2Pts(p);
2941 	QPointF p2 = QPointF(qAbs(dstW), qAbs(dstH));
2942 	QLineF wl = QLineF(0, 0, p2.x(), 0);
2943 	wl = bm.map(wl);
2944 	QLineF hl = QLineF(0, 0, p2.y(), 0);
2945 	hl = bm.map(hl);
2946 	p2 = convertDevice2Pts(QPointF(wl.length(), hl.length()));
2947 	int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX + p.x(), baseY + p.y(), p2.x(), p2.y(), 0, CommonStrings::None, CommonStrings::None);
2948 	PageItem* ite = m_Doc->Items->at(z);
2949 	finishItem(ite, false);
2950 	QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_emf_XXXXXX.png");
2951 	tempFile->setAutoRemove(false);
2952 	if (tempFile->open())
2953 	{
2954 		QString fileName = getLongPathName(tempFile->fileName());
2955 		if (!fileName.isEmpty())
2956 		{
2957 			tempFile->close();
2958 			img.save(fileName, "PNG");
2959 			ite->isInlineImage = true;
2960 			ite->isTempFile = true;
2961 			ite->AspectRatio = false;
2962 			ite->ScaleType   = false;
2963 			if (currentDC.clipValid)
2964 			{
2965 				FPointArray cp = currentDC.clipPath.copy();
2966 				cp.translate(baseX, baseY);
2967 				cp.translate(-docX, -docY);
2968 				cp.translate(-ite->xPos(), -ite->yPos());
2969 				ite->PoLine = cp.copy();
2970 				FPoint wh = getMaxClipF(&ite->PoLine);
2971 				ite->setWidthHeight(wh.x(),wh.y());
2972 				ite->setTextFlowMode(PageItem::TextFlowDisabled);
2973 				m_Doc->adjustItemSize(ite);
2974 				ite->OldB2 = ite->width();
2975 				ite->OldH2 = ite->height();
2976 				ite->updateClip();
2977 			}
2978 			m_Doc->loadPict(fileName, ite);
2979 			ite->adjustPictScale();
2980 		}
2981 	}
2982 	delete tempFile;
2983 }
2984 
handlePatternFill(qint32 dstX,qint32 dstY,qint32 dstW,qint32 dstH)2985 void EmfPlug::handlePatternFill(qint32 dstX, qint32 dstY, qint32 dstW, qint32 dstH)
2986 {
2987 	if (currentDC.brushStyle == U_BT_TextureFill)
2988 	{
2989 		QTransform bm = currentDC.m_WorldMap;
2990 		if ((currentDC.m_mapMode == 0x07) || (currentDC.m_mapMode == 0x08))
2991 		{
2992 			double ratioX = viewPextendX / static_cast<double>(winPextendX); // Logical --> Device
2993 			double ratioY = viewPextendY / static_cast<double>(winPextendY); // Logical --> Device
2994 			bm = QTransform(bm.m11() * ratioX, bm.m12() * ratioX, bm.m21() * ratioY, bm.m22() * ratioY, bm.dx() * ratioX, bm.dy() * ratioY);
2995 		}
2996 		QPointF p = currentDC.m_WorldMap.map(QPointF(dstX, dstY));
2997 		p = convertLogical2Pts(p);
2998 		QPointF p2 = QPointF(qAbs(dstW), qAbs(dstH));
2999 		QLineF wl = QLineF(0, 0, p2.x(), 0);
3000 		wl = bm.map(wl);
3001 		QLineF hl = QLineF(0, 0, p2.y(), 0);
3002 		hl = bm.map(hl);
3003 		p2 = convertDevice2Pts(QPointF(wl.length(), hl.length()));
3004 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX + p.x(), baseY + p.y(), p2.x(), p2.y(), 0, CommonStrings::None, CommonStrings::None);
3005 		PageItem* ite = m_Doc->Items->at(z);
3006 		finishItem(ite);
3007 	}
3008 }
3009 
handleDIB(QDataStream & ds,qint64 filePos,quint32 offBitH,quint32 sizeBitH,quint32 offBits,quint32 sizeBits)3010 QImage EmfPlug::handleDIB(QDataStream &ds, qint64 filePos, quint32 offBitH, quint32 sizeBitH, quint32 offBits, quint32 sizeBits)
3011 {
3012 	QImage img = QImage();
3013 	quint32 hSiz = 0, hCompression = 0, imgSize = 0, xres = 0, yres = 0, colorsUsed = 0, colorsReq = 0;
3014 	qint32 hWidth = 0, hHeight = 0;
3015 	quint16 hPlane = 0, hBitCount = 0;
3016 	QVector<QRgb> colorTbl;
3017 	if ((sizeBitH != 0) && (sizeBits != 0))
3018 	{
3019 		QByteArray headerBits;
3020 		headerBits.resize(sizeBitH);
3021 		ds.device()->seek(filePos + offBitH);
3022 		ds.readRawData(headerBits.data(), sizeBitH);
3023 		if (sizeBitH != 12)
3024 		{
3025 			QDataStream dsH(headerBits);
3026 			dsH.setByteOrder(QDataStream::LittleEndian);
3027 			dsH >> hSiz >> hWidth >> hHeight;
3028 			dsH >> hPlane >> hBitCount;
3029 			dsH >> hCompression;
3030 			dsH >> imgSize >> xres >> yres >> colorsUsed >> colorsReq;
3031 			if (((hBitCount == 8) || (hBitCount == 4) || (hBitCount == 1)) && (hCompression == 0))
3032 			{
3033 				if (colorsUsed == 0)
3034 				{
3035 					if (hBitCount == 8)
3036 						colorsUsed = 256;
3037 					else if (hBitCount == 4)
3038 						colorsUsed = 16;
3039 					else if (hBitCount == 1)
3040 						colorsUsed = 2;
3041 				}
3042 				for (quint32 pa = 0; pa < colorsUsed; pa++)
3043 				{
3044 					quint8 r, g, b, a;
3045 					dsH >> b >> g >> r >> a;
3046 					colorTbl.append(qRgba(r, g, b, 255));
3047 				}
3048 			}
3049 		}
3050 		QByteArray bitsBits;
3051 		bitsBits.resize(sizeBits);
3052 		ds.device()->seek(filePos + offBits);
3053 		ds.readRawData(bitsBits.data(), sizeBits);
3054 		if (hCompression == 0)
3055 		{
3056 			QDataStream dsB(bitsBits);
3057 			dsB.setByteOrder(QDataStream::LittleEndian);
3058 			hWidth = qAbs(hWidth);
3059 			hHeight = qAbs(hHeight);
3060 			img = QImage(hWidth, hHeight, QImage::Format_ARGB32);
3061 			img.fill(0);
3062 			if (hBitCount == 32)
3063 			{
3064 				for (qint32 yy = 0; yy < hHeight; yy++)
3065 				{
3066 					QRgb *dst = (QRgb*)img.scanLine(hHeight - yy - 1);
3067 					for (qint32 xx = 0; xx < hWidth; xx++)
3068 					{
3069 						quint8 r, g, b, a;
3070 						dsB >> b >> g >> r >> a;
3071 						*dst = qRgba(r, g, b, 255);
3072 						dst++;
3073 					}
3074 				}
3075 			}
3076 			else if (hBitCount == 24)
3077 			{
3078 				for (qint32 yy = 0; yy < hHeight; yy++)
3079 				{
3080 					QRgb *dst = (QRgb*)img.scanLine(hHeight - yy - 1);
3081 					for (qint32 xx = 0; xx < hWidth; xx++)
3082 					{
3083 						quint8 r, g, b;
3084 						dsB >> b >> g >> r;
3085 						*dst = qRgba(r, g, b, 255);
3086 						dst++;
3087 					}
3088 					aligntoQuadWord(dsB);
3089 				}
3090 			}
3091 			else if (hBitCount == 16)
3092 			{
3093 				for (qint32 yy = 0; yy < hHeight; yy++)
3094 				{
3095 					QRgb *dst = (QRgb*)img.scanLine(hHeight - yy - 1);
3096 					for (qint32 xx = 0; xx < hWidth; xx++)
3097 					{
3098 						quint16 dt;
3099 						quint8 r, g, b;
3100 						dsB >> dt;
3101 						b = (dt & 0x1F) * 8;
3102 						g = ((dt >> 5) & 0x1F) * 8;
3103 						r = ((dt >> 10) & 0x1F) * 8;
3104 						*dst = qRgba(r, g, b, 255);
3105 						dst++;
3106 					}
3107 					aligntoQuadWord(dsB);
3108 				}
3109 			}
3110 			else if (hBitCount == 8)
3111 			{
3112 				img = QImage(hWidth, hHeight, QImage::Format_Indexed8);
3113 				img.fill(0);
3114 				img.setColorTable(colorTbl);
3115 				for (qint32 yy = 0; yy < hHeight; yy++)
3116 				{
3117 					char *dst = (char*)img.scanLine(hHeight - yy - 1);
3118 					dsB.readRawData(dst, hWidth);
3119 					aligntoQuadWord(dsB);
3120 				}
3121 				img = img.convertToFormat(QImage::Format_ARGB32);
3122 			}
3123 			else if (hBitCount == 4)
3124 			{
3125 				for (qint32 yy = 0; yy < hHeight; yy++)
3126 				{
3127 					QRgb *dst = (QRgb*)img.scanLine(hHeight - yy - 1);
3128 					for (qint32 xx = 0; xx < hWidth; xx += 2)
3129 					{
3130 						quint8 r, rh, rl;
3131 						dsB >> r;
3132 						rh = (r >> 4) & 0xF;
3133 						rl = r & 0xF;
3134 						if (rh < colorTbl.count())
3135 							*dst = colorTbl[rh];
3136 						dst++;
3137 						if (xx == hWidth - 1)
3138 							break;
3139 						if (rl < colorTbl.count())
3140 							*dst = colorTbl[rl];
3141 						dst++;
3142 					}
3143 					aligntoQuadWord(dsB);
3144 				}
3145 			}
3146 			else if (hBitCount == 1)
3147 			{
3148 				img = QImage(hWidth, hHeight, QImage::Format_Mono);
3149 				img.fill(0);
3150 				img.setColorTable(colorTbl);
3151 				int bpl = img.bytesPerLine();
3152 				for (qint32 yy = 0; yy < hHeight; yy++)
3153 				{
3154 					char *dst = (char*)img.scanLine(hHeight - yy - 1);
3155 					dsB.readRawData(dst, bpl);
3156 				}
3157 				img = img.convertToFormat(QImage::Format_ARGB32);
3158 			}
3159 		}
3160 		else if ((hCompression == 1) || (hCompression == 2))
3161 		{
3162 			QByteArray pattern;
3163 			pattern.resize(14);
3164 			pattern.fill(0);
3165 			quint16 bmType = 0x4D42;
3166 			quint32 bmSize = bitsBits.count() + headerBits.count() + 14;
3167 			QDataStream pa(&pattern, QIODevice::WriteOnly);
3168 			pa.setByteOrder(QDataStream::LittleEndian);
3169 			pa << bmType;
3170 			pa << bmSize;
3171 			bitsBits.prepend(headerBits);
3172 			bitsBits.prepend(pattern);
3173 			img.loadFromData(bitsBits, "BMP");
3174 			img = img.convertToFormat(QImage::Format_ARGB32);
3175 		}
3176 		else if (hCompression == 3)
3177 		{
3178 			QDataStream dsB(bitsBits);
3179 			dsB.setByteOrder(QDataStream::LittleEndian);
3180 			img = QImage(hWidth, hHeight, QImage::Format_ARGB32);
3181 			img.fill(0);
3182 			for (qint32 yy = 0; yy < hHeight; yy++)
3183 			{
3184 				QRgb *dst = (QRgb*)img.scanLine(hHeight - yy - 1);
3185 				for (qint32 xx = 0; xx < hWidth; xx++)
3186 				{
3187 					quint8 r, g, b, a;
3188 					dsB >> b >> g >> r >> a;
3189 					*dst = qRgba(r, g, b, 255);
3190 					dst++;
3191 				}
3192 			}
3193 		}
3194 		else if (hCompression == 4)
3195 		{
3196 			img.loadFromData(bitsBits);
3197 			img = img.convertToFormat(QImage::Format_ARGB32);
3198 		}
3199 		else if (hCompression == 5)
3200 		{
3201 			img.loadFromData(bitsBits);
3202 			img = img.convertToFormat(QImage::Format_ARGB32);
3203 		}
3204 	}
3205 	return img;
3206 }
3207 
handleBezier(QDataStream & ds,bool size)3208 void EmfPlug::handleBezier(QDataStream &ds, bool size)
3209 {
3210 	QRectF BoxDev;
3211 	quint32 countP;
3212 	getPolyInfo(ds, BoxDev, countP);
3213 	FPointArray pointsPoly;
3214 	pointsPoly.svgInit();
3215 	QPointF p = getPoint(ds, size);
3216 	if (inPath)
3217 		currentDC.Coords.svgMoveTo(p.x(), p.y());
3218 	else
3219 		pointsPoly.svgMoveTo(p.x(), p.y());
3220 	for (quint32 a = 1; a < countP; a += 3)
3221 	{
3222 		QPointF p1 = getPoint(ds, size);
3223 		QPointF p2 = getPoint(ds, size);
3224 		QPointF p3 = getPoint(ds, size);
3225 		if (inPath)
3226 			currentDC.Coords.svgCurveToCubic(p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y());
3227 		else
3228 			pointsPoly.svgCurveToCubic(p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y());
3229 	}
3230 	if (!inPath)
3231 	{
3232 		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3233 		PageItem* ite = m_Doc->Items->at(z);
3234 		ite->PoLine = pointsPoly.copy();
3235 		finishItem(ite, false);
3236 	}
3237 }
3238 
handlePolygon(QDataStream & ds,bool size,bool fill)3239 void EmfPlug::handlePolygon(QDataStream &ds, bool size, bool fill)
3240 {
3241 	if (inPath)
3242 	{
3243 		QRectF BoxDev;
3244 		quint32 countP;
3245 		getPolyInfo(ds, BoxDev, countP);
3246 		FPointArray points = getPolyPoints(ds, countP, size, fill);
3247 		currentDC.Coords += points;
3248 	}
3249 	else
3250 	{
3251 		int z = -1;
3252 		QRectF BoxDev;
3253 		quint32 countP;
3254 		getPolyInfo(ds, BoxDev, countP);
3255 		FPointArray pointsPoly = getPolyPoints(ds, countP, size, fill);
3256 		if (fill)
3257 			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, currentDC.CurrColorFill, currentDC.CurrColorStroke);
3258 		else
3259 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3260 		PageItem* ite = m_Doc->Items->at(z);
3261 		ite->PoLine = pointsPoly.copy();
3262 		finishItem(ite, fill);
3263 	}
3264 }
3265 
handlePolyPolygon(QDataStream & ds,bool size,bool fill)3266 void EmfPlug::handlePolyPolygon(QDataStream &ds, bool size, bool fill)
3267 {
3268 	if (inPath)
3269 	{
3270 		QRectF BoxDev;
3271 		quint32 countP, dummy;
3272 		getPolyInfo(ds, BoxDev, countP);
3273 		ds >> dummy;
3274 		QList<quint32> polyCounts;
3275 		for (quint32 a = 0; a < countP; a++)
3276 		{
3277 			ds >> dummy;
3278 			polyCounts.append(dummy);
3279 		}
3280 		for (quint32 a = 0; a < countP; a++)
3281 		{
3282 			FPointArray points = getPolyPoints(ds, polyCounts[a], size, fill);
3283 			currentDC.Coords += points;
3284 			if (countP > 1)
3285 				currentDC.Coords.setMarker();
3286 		}
3287 	}
3288 	else
3289 	{
3290 		int z = -1;
3291 		QRectF BoxDev;
3292 		quint32 countP, dummy;
3293 		getPolyInfo(ds, BoxDev, countP);
3294 		ds >> dummy;
3295 		QList<quint32> polyCounts;
3296 		for (quint32 a = 0; a < countP; a++)
3297 		{
3298 			ds >> dummy;
3299 			polyCounts.append(dummy);
3300 		}
3301 		FPointArray pointsPoly;
3302 		for (quint32 a = 0; a < countP; a++)
3303 		{
3304 			FPointArray points = getPolyPoints(ds, polyCounts[a], size, fill);
3305 			pointsPoly += points;
3306 			if (countP > 1)
3307 				pointsPoly.setMarker();
3308 		}
3309 		if (fill)
3310 			z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, currentDC.CurrColorFill, currentDC.CurrColorStroke);
3311 		else
3312 			z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3313 		PageItem* ite = m_Doc->Items->at(z);
3314 		ite->PoLine = pointsPoly.copy();
3315 		finishItem(ite, fill);
3316 	}
3317 }
handlePenDef(quint32 penID,quint32 penStyle,quint32 penWidth,quint32 penColor)3318 void EmfPlug::handlePenDef(quint32 penID, quint32 penStyle, quint32 penWidth, quint32 penColor)
3319 {
3320 	QColor col((QRgb)penColor);
3321 	emfStyle sty;
3322 	sty.styType = U_OT_Pen;
3323 	sty.brushColor = CommonStrings::None;
3324 	sty.penColor = handleColor(col);
3325 	sty.penCap = Qt::RoundCap;
3326 	sty.penJoin = Qt::RoundJoin;
3327 	if ((penStyle & 0x0F) == U_LS_Solid)
3328 		sty.penStyle = Qt::SolidLine;
3329 	else if ((penStyle & 0x0F) == U_LS_Dash)
3330 		sty.penStyle = Qt::DashLine;
3331 	else if ((penStyle & 0x0F) == U_LS_Dot)
3332 		sty.penStyle = Qt::DotLine;
3333 	else if ((penStyle & 0x0F) == U_LS_DashDot)
3334 		sty.penStyle = Qt::DashDotLine;
3335 	else if ((penStyle & 0x0F) == U_LS_DashDotDot)
3336 		sty.penStyle = Qt::SolidLine;
3337 	else if ((penStyle & 0x0F) == 5)
3338 	{
3339 		sty.penStyle = Qt::SolidLine;
3340 		sty.penColor = CommonStrings::None;
3341 	}
3342 	else
3343 		sty.penStyle = Qt::SolidLine;
3344 	if ((penStyle & 0x0F00) == 0x100)
3345 		sty.penCap = Qt::SquareCap;
3346 	if ((penStyle & 0x0F00) == 0x200)
3347 		sty.penCap = Qt::FlatCap;
3348 	if ((penStyle & 0x0F000) == 0x1000)
3349 		sty.penJoin = Qt::BevelJoin;
3350 	if ((penStyle & 0x0F000) == 0x2000)
3351 		sty.penJoin = Qt::MiterJoin;
3352 	if ((penStyle & 0x0F0000) == 0x10000)
3353 		sty.penWidth = convertLogical2Pts(static_cast<double>(penWidth));
3354 	else
3355 		sty.penWidth = convertDevice2Pts(static_cast<double>(penWidth));
3356 	QLineF p = QLineF(0, 0, sty.penWidth, 0);
3357 	p = currentDC.m_WorldMap.map(p);
3358 	sty.penWidth = p.length();
3359 	emfStyleMap.insert(penID, sty);
3360 }
3361 
handleColor(const QColor & col)3362 QString EmfPlug::handleColor(const QColor& col)
3363 {
3364 	ScColor tmp;
3365 	tmp.setRgbColor(col.red(), col.green(), col.blue());
3366 	tmp.setSpotColor(false);
3367 	tmp.setRegistrationColor(false);
3368 	QString tmpName = "FromEMF"+col.name().toUpper();
3369 	QString fNam = m_Doc->PageColors.tryAddColor(tmpName, tmp);
3370 	if (fNam == tmpName)
3371 		importedColors.append(tmpName);
3372 	return fNam;
3373 }
3374 
handleFillRegion(QDataStream & ds)3375 void EmfPlug::handleFillRegion(QDataStream &ds)
3376 {
3377 	quint32 dummy, numObj, countRects;
3378 	ds >> dummy >> dummy >> dummy >> dummy >> dummy;
3379 	ds >> numObj;
3380 	if (emfStyleMap.contains(numObj))
3381 	{
3382 		emfStyle sty = emfStyleMap[numObj];
3383 		if (sty.styType == U_OT_Brush)
3384 		{
3385 			currentDC.CurrColorFill = sty.brushColor;
3386 			currentDC.CurrFillTrans = sty.fillTrans;
3387 			ds >> dummy >> dummy >> countRects;
3388 			ds >> dummy >> dummy >> dummy >> dummy >> dummy;
3389 			QPainterPath pathN;
3390 			for (quint32 a = 0; a < countRects; a++)
3391 			{
3392 				QPointF p1 = getPoint(ds, true);
3393 				QPointF p2 = getPoint(ds, true);
3394 				QPainterPath painterPath;
3395 				painterPath.addRect(QRectF(p1, p2));
3396 				pathN = pathN.united(painterPath);
3397 			}
3398 			FPointArray polyline;
3399 			polyline.fromQPainterPath(pathN, true);
3400 			int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
3401 			PageItem* ite = m_Doc->Items->at(z);
3402 			ite->PoLine = polyline.copy();
3403 			finishItem(ite);
3404 		}
3405 	}
3406 }
3407 
handleFrameRegion(QDataStream & ds)3408 void EmfPlug::handleFrameRegion(QDataStream &ds)
3409 {
3410 	quint32 dummy, numObj, countRects;
3411 	ds >> dummy >> dummy >> dummy >> dummy >> dummy;
3412 	ds >> numObj >> dummy >> dummy;
3413 	if (emfStyleMap.contains(numObj))
3414 	{
3415 		emfStyle sty = emfStyleMap[numObj];
3416 		if (sty.styType == U_OT_Pen)
3417 		{
3418 			currentDC.CurrColorStroke = sty.penColor;
3419 			currentDC.CurrStrokeTrans = sty.penTrans;
3420 			currentDC.penCap = sty.penCap;
3421 			currentDC.penJoin = sty.penJoin;
3422 			currentDC.penStyle = sty.penStyle;
3423 			currentDC.LineW = sty.penWidth;
3424 			ds >> dummy >> dummy >> countRects;
3425 			ds >> dummy >> dummy >> dummy >> dummy >> dummy;
3426 			QPainterPath pathN;
3427 			for (quint32 a = 0; a < countRects; a++)
3428 			{
3429 				QPointF p1 = getPoint(ds, true);
3430 				QPointF p2 = getPoint(ds, true);
3431 				QPainterPath painterPath;
3432 				painterPath.addRect(QRectF(p1, p2));
3433 				pathN = pathN.united(painterPath);
3434 			}
3435 			FPointArray polyline;
3436 			polyline.fromQPainterPath(pathN, true);
3437 			int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
3438 			PageItem* ite = m_Doc->Items->at(z);
3439 			ite->PoLine = polyline.copy();
3440 			finishItem(ite);
3441 		}
3442 	}
3443 }
3444 
handleSetClipRegion(QDataStream & ds)3445 void EmfPlug::handleSetClipRegion(QDataStream &ds)
3446 {
3447 	invalidateClipGroup();
3448 	quint32 dummy, mode, countRects;
3449 	ds >> dummy >> mode;
3450 	ds >> dummy >> dummy >> countRects;
3451 	ds >> dummy >> dummy >> dummy >> dummy >> dummy;
3452 /*	QPainterPath pathN;
3453 	for (quint32 a = 0; a < countRects; a++)
3454 	{
3455 		QPointF p1 = getPoint(ds, true);
3456 		QPointF p2 = getPoint(ds, true);
3457 		QPainterPath painterPath;
3458 		painterPath.addRect(QRectF(p1, p2));
3459 		pathN = pathN.united(painterPath);
3460 	}
3461 	FPointArray polyline;
3462 	if ((mode == 0) || (currentDC.clipPath.isEmpty()))
3463 	{
3464 		polyline.fromQPainterPath(pathN, true);
3465 		currentDC.clipPath = polyline.copy();
3466 	}
3467 	else
3468 	{
3469 		QPainterPath pathA = currentDC.clipPath.toQPainterPath(true);
3470 		QPainterPath resultPath;
3471 		if (mode == 1)
3472 			resultPath = pathA.intersected(pathN);
3473 		else if (mode == 2)
3474 			resultPath = pathA.united(pathN);
3475 		else if (mode == 3)
3476 		{
3477 			QPainterPath part1 = pathA.subtracted(pathN);
3478 			QPainterPath part2 = pathN.subtracted(pathA);
3479 			resultPath.addPath(part1);
3480 			resultPath.addPath(part2);
3481 		}
3482 		else if (mode == 4)
3483 			resultPath = pathA.subtracted(pathN);
3484 		else if (mode == 5)
3485 			resultPath = pathN;
3486 		if (!resultPath.isEmpty())
3487 		{
3488 			polyline.resize(0);
3489 			polyline.fromQPainterPath(resultPath, true);
3490 			polyline.svgClosePath();
3491 			currentDC.clipPath = polyline.copy();
3492 		}
3493 	}*/
3494 }
3495 
handleEMFPlus(QDataStream & ds,quint32 dtaSize)3496 void EmfPlug::handleEMFPlus(QDataStream &ds, quint32 dtaSize)
3497 {
3498 	inEMFPlus = true;
3499 	quint16 id2, flagsHL;
3500 	quint8 flagsH, flagsL;
3501 	quint32 size2;
3502 	quint32 dummy;
3503 	quint32 dataSize;
3504 	qint32 xorg, yorg;
3505 	float m11, m12, m21, m22, dx, dy;
3506 	QTransform mm;
3507 	QByteArray emfRecords;
3508 	emfRecords.resize(dtaSize);
3509 	ds.readRawData(emfRecords.data(), dtaSize);
3510 	QDataStream dsEmf(emfRecords);
3511 	dsEmf.setByteOrder(QDataStream::LittleEndian);
3512 	dsEmf.setFloatingPointPrecision(QDataStream::SinglePrecision);
3513 	while (!dsEmf.atEnd())
3514 	{
3515 		qint64 posi2 = dsEmf.device()->pos();
3516 		dsEmf >> id2;
3517 		if ((id2 < 0x4000) || (id2 > 0x403A))
3518 			break;
3519 		dsEmf >> flagsHL;
3520 		flagsL = (flagsHL & 0xFF00) >> 8;
3521 		flagsH = (flagsHL & 0x00FF);
3522 		dsEmf >> size2 >> dataSize;
3523 		switch (id2)
3524 		{
3525 			case U_PMR_HEADER:
3526 				emfPlusDual = (flagsH == 1);
3527 				dsEmf >> dummy >> dummy;
3528 				dsEmf >> EmfPdpiX >> EmfPdpiY;
3529 			//	dpiX = EmfPdpiX;
3530 			//	dpiY = EmfPdpiY;
3531 				break;
3532 			case U_PMR_ENDOFFILE:
3533 				inEMFPlus = false;
3534 				break;
3535 			case U_PMR_GETDC:
3536 				if (emfPlusDual)
3537 					inEMFPlus = false;
3538 				break;
3539 			case U_PMR_OBJECT:
3540 				handleEMPObject(dsEmf, flagsH, flagsL, dataSize);
3541 				break;
3542 			case U_PMR_FILLRECTS:
3543 				handleEMFPFillRects(dsEmf, flagsL);
3544 				break;
3545 			case U_PMR_DRAWRECTS:
3546 				handleEMFPDrawRects(dsEmf, flagsL, flagsH);
3547 				break;
3548 			case U_PMR_FILLPOLYGON:
3549 				handleEMFPFillPolygon(dsEmf, flagsL);
3550 				break;
3551 			case U_PMR_DRAWLINES:
3552 				handleEMFPDrawLines(dsEmf, flagsL, flagsH);
3553 				break;
3554 			case U_PMR_FILLELLIPSE:
3555 				handleEMFPFillEllipse(dsEmf, flagsL);
3556 				break;
3557 			case U_PMR_DRAWELLIPSE:
3558 				handleEMFPDrawEllipse(dsEmf, flagsL, flagsH);
3559 				break;
3560 			case U_PMR_FILLPIE:
3561 				handleEMFPFillPie(dsEmf, flagsL);
3562 				break;
3563 			case U_PMR_DRAWPIE:
3564 				handleEMFPDrawPie(dsEmf, flagsL, flagsH);
3565 				break;
3566 			case U_PMR_DRAWARC:
3567 				handleEMFPDrawArc(dsEmf, flagsL, flagsH);
3568 				break;
3569 			case U_PMR_FILLREGION:
3570 				handleEMFPFillRegion(dsEmf, flagsL, flagsH);
3571 				break;
3572 			case U_PMR_FILLPATH:
3573 				handleEMFPFillPath(dsEmf, flagsL, flagsH);
3574 				break;
3575 			case U_PMR_DRAWPATH:
3576 				handleEMFPDrawPath(dsEmf, flagsH);
3577 				break;
3578 			case U_PMR_FILLCLOSEDCURVE:
3579 				handleEMFPFillClosedCurve(dsEmf, flagsL);
3580 				break;
3581 			case U_PMR_DRAWCLOSEDCURVE:
3582 				handleEMFPDrawClosedCurve(dsEmf, flagsL, flagsH);
3583 				break;
3584 			case U_PMR_DRAWCURVE:
3585 				handleEMFPDrawCurve(dsEmf, flagsL, flagsH);
3586 				break;
3587 			case U_PMR_DRAWBEZIERS:
3588 				handleEMFPDrawBezier(dsEmf, flagsL, flagsH);
3589 				break;
3590 			case U_PMR_DRAWIMAGE:
3591 				handleEMFPDrawImage(dsEmf, flagsL, flagsH);
3592 				break;
3593 			case U_PMR_DRAWIMAGEPOINTS:
3594 				handleEMFPDrawImagePoints(dsEmf, flagsL, flagsH);
3595 				break;
3596 			case U_PMR_DRAWSTRING:
3597 				handleEMFPDrawString(dsEmf, flagsL, flagsH);
3598 				break;
3599 			case U_PMR_SETRENDERINGORIGIN:
3600 				dsEmf >> xorg >> yorg;
3601 				currentDC.originEMFP = convertDevice2Pts(QPointF(xorg, yorg));
3602 				break;
3603 			case U_PMR_SETCOMPOSITINGMODE:
3604 				currentDC.alphaOn = (flagsH == 0);
3605 				break;
3606 			case U_PMR_SAVE:
3607 				dsEmf >> dummy;
3608 				dcStackEMP.insert(dummy, currentDC);
3609 				break;
3610 			case U_PMR_RESTORE:
3611 				invalidateClipGroup();
3612 				dsEmf >> dummy;
3613 				if (dcStackEMP.contains(dummy))
3614 					currentDC = dcStackEMP[dummy];
3615 				if (currentDC.clipPath.count() != 0)
3616 				{
3617 					if (checkClip(currentDC.clipPath))
3618 					{
3619 						currentDC.clipValid = true;
3620 						createClipGroup();
3621 					}
3622 				}
3623 				break;
3624 			case U_PMR_SETWORLDTRANSFORM:
3625 				dsEmf >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
3626 				currentDC.m_WorldMapEMFP = QTransform(m11, m12, m21, m22, dx, dy);
3627 				break;
3628 			case U_PMR_RESETWORLDTRANSFORM:
3629 				currentDC.m_WorldMapEMFP = QTransform();
3630 				break;
3631 			case U_PMR_MULTIPLYWORLDTRANSFORM:
3632 				dsEmf >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
3633 				if (flagsL & 0x20)
3634 					currentDC.m_WorldMapEMFP = currentDC.m_WorldMapEMFP * QTransform(m11, m12, m21, m22, dx, dy);
3635 				else
3636 					currentDC.m_WorldMapEMFP = QTransform(m11, m12, m21, m22, dx, dy) * currentDC.m_WorldMapEMFP;
3637 				break;
3638 			case U_PMR_TRANSLATEWORLDTRANSFORM:
3639 				dsEmf >> dx >> dy;
3640 				mm = QTransform();
3641 				mm.translate(dx, dy);
3642 				if (flagsL & 0x20)
3643 					currentDC.m_WorldMapEMFP = currentDC.m_WorldMapEMFP * mm;
3644 				else
3645 					currentDC.m_WorldMapEMFP = mm * currentDC.m_WorldMapEMFP;
3646 				break;
3647 			case U_PMR_SCALEWORLDTRANSFORM:
3648 				dsEmf >> m11 >> m12;
3649 				mm = QTransform();
3650 				mm.scale(m11, m12);
3651 				if (flagsL & 0x20)
3652 					currentDC.m_WorldMapEMFP = currentDC.m_WorldMapEMFP * mm;
3653 				else
3654 					currentDC.m_WorldMapEMFP = mm * currentDC.m_WorldMapEMFP;
3655 				break;
3656 			case U_PMR_ROTATEWORLDTRANSFORM:
3657 				dsEmf >> m11;
3658 				mm = QTransform();
3659 				mm.rotate(m11);
3660 				if (flagsL & 0x20)
3661 					currentDC.m_WorldMapEMFP = currentDC.m_WorldMapEMFP * mm;
3662 				else
3663 					currentDC.m_WorldMapEMFP = mm * currentDC.m_WorldMapEMFP;
3664 				break;
3665 			case U_PMR_SETPAGETRANSFORM:
3666 				currentDC.emfPlusUnit = flagsH;
3667 				dsEmf >> emfPlusScale;
3668 				break;
3669 			case U_PMR_OFFSETCLIP:
3670 				if (currentDC.clipValid)
3671 				{
3672 					double dx = getEMFPDistance(dsEmf, false);
3673 					double dy = getEMFPDistance(dsEmf, false);
3674 					currentDC.clipPath.translate(dx, dy);
3675 					invalidateClipGroup();
3676 					createClipGroup();
3677 				}
3678 				break;
3679 			case U_PMR_RESETCLIP:
3680 				currentDC.clipPath.resize(0);
3681 				currentDC.clipPath.svgInit();
3682 				currentDC.clipValid = false;
3683 				invalidateClipGroup();
3684 				break;
3685 			case U_PMR_SETCLIPRECT:
3686 				handleEMFPSetClipRect(dsEmf, flagsL);
3687 				break;
3688 			case U_PMR_SETCLIPREGION:
3689 				handleEMFPSetClipRegion(dsEmf, flagsL, flagsH);
3690 				break;
3691 			case U_PMR_SETCLIPPATH:
3692 				handleEMFPSetClipPath(dsEmf, flagsL, flagsH);
3693 				break;
3694 			case U_PMR_DRAWDRIVERSTRING:
3695 				handleEMFPDrawDriverString(dsEmf, flagsL, flagsH);
3696 				break;
3697 			case U_PMR_STROKEFILLPATH:
3698 				{
3699 					qDebug() << "\tU_PMR_STROKEFILLPATH";
3700 				}
3701 				break;
3702 			case U_PMR_SERIALIZABLEOBJECT:
3703 				handleEMFPSerializableObject(dsEmf);
3704 				break;
3705 			case U_PMR_BEGINCONTAINER:
3706 			case U_PMR_BEGINCONTAINERNOPARAMS:
3707 			case U_PMR_ENDCONTAINER:
3708 			case U_PMR_COMMENT:
3709 			case U_PMR_SETANTIALIASMODE:
3710 			case U_PMR_SETTEXTRENDERINGHINT:
3711 			case U_PMR_SETTEXTCONTRAST:
3712 			case U_PMR_SETINTERPOLATIONMODE:
3713 			case U_PMR_SETPIXELOFFSETMODE:
3714 			case U_PMR_SETCOMPOSITINGQUALITY:
3715 			case U_PMR_SETTSGRAPHICS:
3716 			case U_PMR_SETTSCLIP:
3717 			case U_PMR_MULTIFORMATSTART:
3718 			case U_PMR_MULTIFORMATSECTION:
3719 			case U_PMR_MULTIFORMATEND:
3720 			case U_PMR_CLEAR:
3721 			//	qDebug() << "\tUnsupported Op-Code" << id2;
3722 				break;
3723 			default:
3724 				qDebug() << "\tUnknown Op-Code" << id2;
3725 				break;
3726 		}
3727 		dsEmf.device()->seek(posi2 + size2);
3728 	}
3729 }
3730 
handleEMPObject(QDataStream & ds,quint8 flagsH,quint8 flagsL,quint32 dataSize)3731 void EmfPlug::handleEMPObject(QDataStream &ds, quint8 flagsH, quint8 flagsL, quint32 dataSize)
3732 {
3733 	quint16 id = flagsH;
3734 	quint16 type = flagsL & 0x7F;
3735 	quint32 totalSize = 0;
3736 	bool cont = (flagsL & 0x80);
3737 	bool first = true;
3738 	if (!cont)
3739 	{
3740 		m_ObjSize = 0;
3741 		m_currObjSize = 0;
3742 	}
3743 	else
3744 	{
3745 		if (m_ObjSize != 0)
3746 			first = false;
3747 		if (m_objID != id)
3748 			first = true;
3749 		ds >> totalSize;
3750 		m_ObjSize = totalSize;
3751 	}
3752 	if (type == U_OT_Brush)
3753 		m_currObjSize += handleEMPBrush(ds, id, first, cont, dataSize);
3754 	else if (type == U_OT_Pen)
3755 		handleEMPPen(ds, id);
3756 	else if (type == U_OT_Path)
3757 		handleEMPPath(ds, id);
3758 	else if (type == U_OT_Region)
3759 		handleEMPRegion(ds, id);
3760 	else if (type == U_OT_Image)
3761 	{
3762 		quint32 lenS = 0;
3763 		if (cont)
3764 			lenS = 4;
3765 		m_currObjSize += handleEMPImage(ds, id, first, cont, dataSize - lenS);
3766 	}
3767 	else if (type == U_OT_Font)
3768 		handleEMPFont(ds, id);
3769 	else if (type == U_OT_StringFormat)
3770 		handleEMPSFormat(ds, id);
3771 	else if (type == U_OT_CustomLineCap)
3772 		handleEMPLineCap(ds, id);
3773 	if (m_currObjSize >= totalSize)
3774 	{
3775 		m_ObjSize = 0;
3776 		m_currObjSize = 0;
3777 	}
3778 	m_objID = id;
3779 }
3780 
handleEMPBrush(QDataStream & ds,quint16 id,bool first,bool cont,quint32 dataSize)3781 quint32 EmfPlug::handleEMPBrush(QDataStream &ds, quint16 id, bool first, bool cont, quint32 dataSize)
3782 {
3783 	emfStyle sty;
3784 	quint32 retVal = 0;
3785 	if (!first)
3786 	{
3787 		quint32 lenS = 0;
3788 		if (cont)
3789 			lenS = 4;
3790 		retVal += getImageData(ds, id, first, cont, dataSize - lenS, sty);
3791 		return retVal;
3792 	}
3793 	quint32 dummy;
3794 	quint32 brushType;
3795 	ds >> dummy;
3796 	ds >> brushType;
3797 	if (brushType == U_BT_SolidColor)
3798 	{
3799 		quint32 brush;
3800 		ds >> brush;
3801 		quint8 r = brush & 0xFF;
3802 		quint8 g = (brush >> 8) & 0xFF;
3803 		quint8 b = (brush >> 16) & 0xFF;
3804 		quint8 a = (brush >> 24) & 0xFF;
3805 		QColor col(b, g, r, a);
3806 		sty.brushColor = handleColor(col);
3807 		sty.penColor = CommonStrings::None;
3808 		sty.fillTrans = 1.0 - col.alphaF();
3809 		sty.brushStyle = U_BT_SolidColor;
3810 		sty.hatchStyle = 0;
3811 	}
3812 	else if (brushType == U_BT_HatchFill)
3813 	{
3814 		quint32 hatchStyle, fgColor, bgColor;
3815 		ds >> hatchStyle >> fgColor >> bgColor;
3816 		quint8 r = fgColor & 0xFF;
3817 		quint8 g = (fgColor >> 8) & 0xFF;
3818 		quint8 b = (fgColor >> 16) & 0xFF;
3819 		quint8 a = (fgColor >> 24) & 0xFF;
3820 		QColor col(b, g, r, a);
3821 		r = bgColor & 0xFF;
3822 		g = (bgColor >> 8) & 0xFF;
3823 		b = (bgColor >> 16) & 0xFF;
3824 		a = (bgColor >> 24) & 0xFF;
3825 		QColor col2(b, g, r, a);
3826 		sty.brushColor = handleColor(col);
3827 		sty.fillTrans = 1.0 - col.alphaF();
3828 		sty.penColor = handleColor(col2);
3829 		sty.penTrans = 1.0 - col2.alphaF();
3830 		if (sty.penTrans > 0.5)
3831 			sty.penColor = CommonStrings::None;
3832 		sty.hatchStyle = hatchStyle;
3833 		sty.brushStyle = U_BT_HatchFill;
3834 	}
3835 	else if (brushType == U_BT_TextureFill)
3836 	{
3837 		if (first)
3838 		{
3839 			quint32 lenS = 16;
3840 			if (cont)
3841 				lenS += 4;
3842 			quint32 gFlags, wrap;
3843 			ds >> gFlags >> wrap;
3844 			bool mTrans = (gFlags & 0x00000002);
3845 			if (mTrans)
3846 			{
3847 				lenS += 24;
3848 				float m11, m12, m21, m22, dx, dy;
3849 				ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
3850 				QLineF lin = QLineF(0, 0, 1, 0);
3851 				lin = QTransform(m11, m12, m21, m22, dx, dy).map(lin);
3852 				sty.gradientAngle = lin.angle();
3853 			}
3854 			sty.brushStyle = U_BT_TextureFill;
3855 			sty.patternMode = wrap;
3856 			retVal = getImageData(ds, id, first, cont, dataSize - lenS, sty);
3857 		}
3858 	}
3859 	else if (brushType == U_BT_PathGradient)
3860 	{
3861 		quint32 gFlags {0}, wrap {0}, startCol {0}, cCount {0}, endCol {0};
3862 		ds >> gFlags >> wrap;
3863 		ds >> startCol;
3864 		QPointF p1 = getEMFPPoint(ds, false);
3865 		ds >> cCount;
3866 		for (quint32 i = 0; i < cCount; i++)
3867 		{
3868 			ds >> endCol;
3869 		}
3870 		bool mPath  = (gFlags & 0x00000001);
3871 		bool mTrans = (gFlags & 0x00000002);
3872 		bool preCol = (gFlags & 0x00000004);
3873 		bool blFacH = (gFlags & 0x00000008);
3874 		sty.brushStyle = U_BT_PathGradient;
3875 		sty.gradientStart = p1;
3876 		if (mPath)
3877 		{
3878 			quint32 pCount;
3879 			ds >> pCount;
3880 			qint64 ppos = ds.device()->pos();
3881 			FPointArray polyline = getEMPPathData(ds);
3882 			sty.gradientPath = polyline.copy();
3883 			ds.device()->seek(ppos + pCount);
3884 		}
3885 		else
3886 		{
3887 			quint32 pCount;
3888 			ds >> pCount;
3889 			QPolygonF points = getEMFPCurvePoints(ds, 0, pCount);
3890 			QPainterPath path;
3891 			GdipAddPathClosedCurve(path, points, 0);
3892 			FPointArray polyline;
3893 			polyline.fromQPainterPath(path, true);
3894 			sty.gradientPath = polyline.copy();
3895 		}
3896 		if (mTrans)
3897 		{
3898 			float m11, m12, m21, m22, dx, dy;
3899 			ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
3900 			QLineF lin = QLineF(0, 0, 1, 0);
3901 			lin = QTransform(m11, m12, m21, m22, dx, dy).map(lin);
3902 			sty.gradientAngle = lin.angle() + 45;
3903 		}
3904 		if (blFacH && !preCol)
3905 		{
3906 			quint32 cCount;
3907 			ds >> cCount;
3908 			ds.skipRawData(8 * cCount);
3909 		}
3910 		sty.gradient = VGradient(VGradient::linear);
3911 		sty.gradient.clearStops();
3912 		sty.gradient.setRepeatMethod(VGradient::pad);
3913 		if (preCol)
3914 		{
3915 			quint32 cCount;
3916 			ds >> cCount;
3917 			QList<float> posit;
3918 			QList<quint32> facts;
3919 			for (quint32 c = 0; c < cCount; c++)
3920 			{
3921 				float fact;
3922 				ds >> fact;
3923 				posit.append(fact);
3924 			}
3925 			for (quint32 c = 0; c < cCount; c++)
3926 			{
3927 				quint32 fact;
3928 				ds >> fact;
3929 				facts.append(fact);
3930 			}
3931 			for (quint32 c = 0; c < cCount; c++)
3932 			{
3933 				quint8 r = facts[c] & 0xFF;
3934 				quint8 g = (facts[c] >> 8) & 0xFF;
3935 				quint8 b = (facts[c] >> 16) & 0xFF;
3936 				quint8 a = (facts[c] >> 24) & 0xFF;
3937 				QColor col(b, g, r, a);
3938 				QString stColor = handleColor(col);
3939 				sty.gradient.addStop(col, 1.0 - posit[c], 0.5, col.alphaF(), stColor, 100);
3940 			}
3941 		}
3942 		else
3943 		{
3944 			quint8 r = startCol & 0xFF;
3945 			quint8 g = (startCol >> 8) & 0xFF;
3946 			quint8 b = (startCol >> 16) & 0xFF;
3947 			quint8 a = (startCol >> 24) & 0xFF;
3948 			QColor col(b, g, r, a);
3949 			QString stColor = handleColor(col);
3950 			sty.gradient.addStop(col, 0.0, 0.5, col.alphaF(), stColor, 100);
3951 			r = endCol & 0xFF;
3952 			g = (endCol >> 8) & 0xFF;
3953 			b = (endCol >> 16) & 0xFF;
3954 			a = (endCol >> 24) & 0xFF;
3955 			QColor col2(b, g, r, a);
3956 			QString enColor = handleColor(col2);
3957 			sty.gradient.addStop(col2, 1.0, 0.5, col2.alphaF(), enColor, 100);
3958 		}
3959 	}
3960 	else if (brushType == U_BT_LinearGradient)
3961 	{
3962 		quint32 gFlags, wrap, startCol, endCol;
3963 		ds >> gFlags >> wrap;
3964 		QPolygonF rect = getEMFPRect(ds, false);
3965 		ds >> startCol >> endCol;
3966 		ds >> dummy >> dummy;
3967 		bool mTrans = (gFlags & 0x00000002);
3968 		bool preCol = (gFlags & 0x00000004);
3969 		bool blFacH = (gFlags & 0x00000008);
3970 		bool blFacV = (gFlags & 0x00000010);
3971 		sty.brushStyle = U_BT_LinearGradient;
3972 		sty.gradientStart = rect[0];
3973 		sty.gradientEnd = rect[2];
3974 		if (mTrans)
3975 		{
3976 			float m11, m12, m21, m22, dx, dy;
3977 			ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
3978 			QLineF lin = QLineF(rect[0], rect[2]);
3979 			lin = QTransform(m11, m12, m21, m22, dx, dy).map(lin);
3980 			sty.gradientAngle = lin.angle() + 45;
3981 		}
3982 		if ((blFacH || blFacV) && !preCol)
3983 		{
3984 			quint32 cCount;
3985 			ds >> cCount;
3986 			ds.skipRawData(8 * cCount);
3987 		}
3988 		sty.gradient = VGradient(VGradient::linear);
3989 		sty.gradient.clearStops();
3990 		sty.gradient.setRepeatMethod(VGradient::pad);
3991 		if (preCol)
3992 		{
3993 			quint32 cCount;
3994 			ds >> cCount;
3995 			QList<float> posit;
3996 			QList<quint32> facts;
3997 			for (quint32 c = 0; c < cCount; c++)
3998 			{
3999 				float fact;
4000 				ds >> fact;
4001 				posit.append(fact);
4002 			}
4003 			for (quint32 c = 0; c < cCount; c++)
4004 			{
4005 				quint32 fact;
4006 				ds >> fact;
4007 				facts.append(fact);
4008 			}
4009 			for (quint32 c = 0; c < cCount; c++)
4010 			{
4011 				quint8 r = facts[c] & 0xFF;
4012 				quint8 g = (facts[c] >> 8) & 0xFF;
4013 				quint8 b = (facts[c] >> 16) & 0xFF;
4014 				quint8 a = (facts[c] >> 24) & 0xFF;
4015 				QColor col(b, g, r, a);
4016 				QString stColor = handleColor(col);
4017 				sty.gradient.addStop(col, posit[c], 0.5, col.alphaF(), stColor, 100);
4018 			}
4019 		}
4020 		else
4021 		{
4022 			quint8 r = startCol & 0xFF;
4023 			quint8 g = (startCol >> 8) & 0xFF;
4024 			quint8 b = (startCol >> 16) & 0xFF;
4025 			quint8 a = (startCol >> 24) & 0xFF;
4026 			QColor col(b, g, r, a);
4027 			QString stColor = handleColor(col);
4028 			sty.gradient.addStop(col, 1.0, 0.5, col.alphaF(), stColor, 100);
4029 			r = endCol & 0xFF;
4030 			g = (endCol >> 8) & 0xFF;
4031 			b = (endCol >> 16) & 0xFF;
4032 			a = (endCol >> 24) & 0xFF;
4033 			QColor col2(b, g, r, a);
4034 			QString enColor = handleColor(col2);
4035 			sty.gradient.addStop(col2, 0.0, 0.5, col2.alphaF(), enColor, 100);
4036 		}
4037 	}
4038 	sty.styType = U_OT_Brush;
4039 	emfStyleMapEMP.insert(id, sty);
4040 	return retVal;
4041 }
4042 
handleEMPPen(QDataStream & ds,quint16 id)4043 void EmfPlug::handleEMPPen(QDataStream &ds, quint16 id)
4044 {
4045 	emfStyle sty;
4046 	quint32 dummy;
4047 	quint32 penData, penUnit;
4048 	float penWidth;
4049 	ds >> dummy;
4050 	ds >> dummy;
4051 	ds >> penData >> penUnit >> penWidth;
4052 	sty.penCap = Qt::RoundCap;
4053 	sty.penJoin = Qt::RoundJoin;
4054 	sty.penStyle = Qt::SolidLine;
4055 	if (penData & U_PD_Transform)
4056 	{
4057 		float m11, m12, m21, m22, dx, dy;
4058 		ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
4059 	}
4060 	if (penData & U_PD_StartCap)
4061 	{
4062 		qint32 startCap;
4063 		ds >> startCap;
4064 		if (startCap == U_LCT_Square)
4065 			sty.penCap = Qt::SquareCap;
4066 		if (startCap == U_LCT_Flat)
4067 			sty.penCap = Qt::FlatCap;
4068 		else if (startCap == U_LCT_Round)
4069 			sty.penCap = Qt::RoundCap;
4070 		else
4071 			sty.penCap = Qt::RoundCap;
4072 	}
4073 	if (penData & U_PD_EndCap)
4074 	{
4075 		qint32 endCap;
4076 		ds >> endCap;
4077 		if (endCap == U_LCT_Square)
4078 			sty.penCap = Qt::SquareCap;
4079 		if (endCap == U_LCT_Flat)
4080 			sty.penCap = Qt::FlatCap;
4081 		else if (endCap == U_LCT_Round)
4082 			sty.penCap = Qt::RoundCap;
4083 		else
4084 			sty.penCap = Qt::RoundCap;
4085 	}
4086 	if (penData & U_PD_Join)
4087 	{
4088 		qint32 join;
4089 		ds >> join;
4090 		if (join == U_LJT_Bevel)
4091 			sty.penJoin = Qt::BevelJoin;
4092 		else if (join == U_LJT_Miter)
4093 			sty.penJoin = Qt::MiterJoin;
4094 		else if (join == U_LJT_Round)
4095 			sty.penJoin = Qt::RoundJoin;
4096 		else
4097 			sty.penJoin = Qt::RoundJoin;
4098 	}
4099 	if (penData & U_PD_MiterLimit)
4100 	{
4101 		float data;
4102 		ds >> data;
4103 	}
4104 	if (penData & U_PD_LineStyle)
4105 	{
4106 		qint32 penStyle;
4107 		ds >> penStyle;
4108 		if ((penStyle) == U_LS_Solid)
4109 			sty.penStyle = Qt::SolidLine;
4110 		else if ((penStyle) == U_LS_Dash)
4111 			sty.penStyle = Qt::DashLine;
4112 		else if ((penStyle) == U_LS_Dot)
4113 			sty.penStyle = Qt::DotLine;
4114 		else if ((penStyle) == U_LS_DashDot)
4115 			sty.penStyle = Qt::DashDotLine;
4116 		else if ((penStyle) == U_LS_DashDotDot)
4117 			sty.penStyle = Qt::DashDotDotLine;
4118 		else if ((penStyle) == 5)
4119 			sty.penStyle = Qt::SolidLine;
4120 		else
4121 			sty.penStyle = Qt::SolidLine;
4122 	}
4123 	if (penData & U_PD_DLCap)
4124 	{
4125 		qint32 data;
4126 		ds >> data;
4127 	}
4128 	if (penData & U_PD_DLOffset)
4129 	{
4130 		float data;
4131 		ds >> data;
4132 		sty.dashOffset = data;
4133 	}
4134 	if (penData & U_PD_DLData)
4135 	{
4136 		quint32 data;
4137 		ds >> data;
4138 		for (quint32 a = 0; a < data; a++)
4139 		{
4140 			float dData;
4141 			ds >> dData;
4142 			sty.dashArray.append(dData);
4143 		}
4144 	}
4145 	if (penData & U_PD_NonCenter)
4146 	{
4147 		float data;
4148 		ds >> data;
4149 	//	qDebug() << QString("\n\t\t\tPenAlignment");
4150 	}
4151 	if (penData & U_PD_CLData)
4152 	{
4153 		quint32 data;
4154 		ds >> data;
4155 		for (quint32 a = 0; a < data; a++)
4156 		{
4157 			float dData;
4158 			ds >> dData;
4159 		}
4160 	//	qDebug() << QString("\n\t\t\tCompoundLine");
4161 	}
4162 	if (penData & U_PD_CustomStartCap)
4163 	{
4164 		quint32 data;
4165 		ds >> data;
4166 		ds.skipRawData(data);
4167 	//	qDebug() << QString("\n\t\t\tCustomStartCap");
4168 	}
4169 	if (penData & U_PD_CustomEndCap)
4170 	{
4171 		quint32 data;
4172 		ds >> data;
4173 		ds.skipRawData(data);
4174 	//	qDebug() << QString("\n\t\t\tCustomEndCap");
4175 	}
4176 	quint32 brushType;
4177 	ds >> dummy;
4178 	ds >> brushType;
4179 	if (brushType == U_BT_SolidColor)
4180 	{
4181 		quint32 brush;
4182 		ds >> brush;
4183 		quint8 r = brush & 0xFF;
4184 		quint8 g = (brush >> 8) & 0xFF;
4185 		quint8 b = (brush >> 16) & 0xFF;
4186 		quint8 a = (brush >> 24) & 0xFF;
4187 		QColor col(b, g, r, a);
4188 		sty.penColor = handleColor(col);
4189 		sty.penTrans = 1.0 - col.alphaF();
4190 	}
4191 	else
4192 		sty.penColor = "Black";
4193 	sty.styType = U_OT_Pen;
4194 	sty.brushColor = CommonStrings::None;
4195 	if ((penUnit == U_UT_World) || (penUnit == U_UT_Display))
4196 		sty.penWidth = convertEMFPLogical2Pts(penWidth, currentDC.emfPlusUnit);
4197 	else
4198 		sty.penWidth = convertEMFPLogical2Pts(penWidth, penUnit);
4199 	emfStyleMapEMP.insert(id, sty);
4200 }
4201 
handleEMPPath(QDataStream & ds,quint16 id)4202 void EmfPlug::handleEMPPath(QDataStream &ds, quint16 id)
4203 {
4204 	FPointArray polyline = getEMPPathData(ds);
4205 	if (polyline.count() > 0)
4206 	{
4207 		emfStyle sty;
4208 		sty.styType = U_OT_Path;
4209 		sty.Coords = polyline.copy();
4210 		emfStyleMapEMP.insert(id, sty);
4211 	}
4212 }
4213 
handleEMPRegion(QDataStream & ds,quint16 id)4214 void EmfPlug::handleEMPRegion(QDataStream &ds, quint16 id)
4215 {
4216 	emfStyle sty;
4217 	sty.styType = U_OT_Region;
4218 	quint32 nPoints, rgnType, dummy;
4219 	ds >> dummy;
4220 	ds >> nPoints;
4221 	ds >> rgnType;
4222 	if (rgnType <= U_RNDT_Complement)
4223 	{
4224 		QPainterPath pathL, pathR, resultPath;
4225 		quint32 rgnTypeL, rgnTypeR;
4226 		ds >> rgnTypeL;
4227 		if (rgnTypeL == U_RNDT_Rect)
4228 		{
4229 			QPolygonF rect = getEMFPRect(ds, false);
4230 			pathL.addPolygon(rect);
4231 		}
4232 		else if (rgnTypeL == U_RNDT_Path)
4233 		{
4234 			quint32 rLen;
4235 			ds >> rLen;
4236 			qint64 ppos = ds.device()->pos();
4237 			FPointArray polyline = getEMPPathData(ds);
4238 			ds.device()->seek(ppos + rLen);
4239 			pathL = polyline.toQPainterPath(true);
4240 		}
4241 		ds >> rgnTypeR;
4242 		if (rgnTypeR == U_RNDT_Rect)
4243 		{
4244 			QPolygonF rect = getEMFPRect(ds, false);
4245 			pathR.addPolygon(rect);
4246 		}
4247 		else if (rgnTypeR == U_RNDT_Path)
4248 		{
4249 			quint32 rLen;
4250 			ds >> rLen;
4251 			qint64 ppos = ds.device()->pos();
4252 			FPointArray polyline = getEMPPathData(ds);
4253 			ds.device()->seek(ppos + rLen);
4254 			pathR = polyline.toQPainterPath(true);
4255 		}
4256 		if (rgnType == U_RNDT_And)
4257 			resultPath = pathL.intersected(pathR);
4258 		else if (rgnType == U_RNDT_Or)
4259 			resultPath = pathL.united(pathR);
4260 		else if (rgnType == U_RNDT_Exclude)
4261 		{
4262 			QPainterPath part1 = pathL.subtracted(pathR);
4263 			QPainterPath part2 = pathR.subtracted(pathL);
4264 			resultPath.addPath(part1);
4265 			resultPath.addPath(part2);
4266 		}
4267 		if (!resultPath.isEmpty())
4268 		{
4269 			FPointArray polyline;
4270 			polyline.resize(0);
4271 			polyline.fromQPainterPath(resultPath, true);
4272 			polyline.svgClosePath();
4273 			sty.Coords = polyline.copy();
4274 			emfStyleMapEMP.insert(id, sty);
4275 		}
4276 	}
4277 	else
4278 	{
4279 		if (rgnType == U_RNDT_Rect)
4280 		{
4281 			QPolygonF rect = getEMFPRect(ds, false);
4282 			FPointArray polyline;
4283 			polyline.resize(0);
4284 			polyline.svgInit();
4285 			polyline.svgMoveTo(rect[0].x(), rect[0].y());
4286 			polyline.svgLineTo(rect[1].x(), rect[1].y());
4287 			polyline.svgLineTo(rect[2].x(), rect[2].y());
4288 			polyline.svgLineTo(rect[3].x(), rect[3].y());
4289 			polyline.svgClosePath();
4290 			sty.Coords = polyline.copy();
4291 			emfStyleMapEMP.insert(id, sty);
4292 		}
4293 		else if (rgnType == U_RNDT_Path)
4294 		{
4295 			quint32 rLen;
4296 			ds >> rLen;
4297 			qint64 ppos = ds.device()->pos();
4298 			FPointArray polyline = getEMPPathData(ds);
4299 			ds.device()->seek(ppos + rLen);
4300 			sty.Coords = polyline.copy();
4301 			emfStyleMapEMP.insert(id, sty);
4302 		}
4303 	}
4304 }
4305 
handleEMPImage(QDataStream & ds,quint16 id,bool first,bool cont,quint32 dataSize)4306 quint32 EmfPlug::handleEMPImage(QDataStream &ds, quint16 id, bool first, bool cont, quint32 dataSize)
4307 {
4308 	emfStyle sty;
4309 	sty.styType = U_OT_Image;
4310 	quint32 retVal = getImageData(ds, id, first, cont, dataSize, sty);
4311 	if (first)
4312 		emfStyleMapEMP.insert(id, sty);
4313 	return retVal;
4314 }
4315 
getImageData(QDataStream & ds,quint16 id,bool first,bool cont,quint32 dataSize,emfStyle & sty)4316 quint32 EmfPlug::getImageData(QDataStream &ds, quint16 id, bool first, bool cont, quint32 dataSize, emfStyle &sty)
4317 {
4318 	quint32 retVal = 0;
4319 	if (first)
4320 	{
4321 		quint32 dataV, dummy;
4322 		ds >> dummy;
4323 		ds >> dataV;
4324 		if (dataV == U_IDT_Bitmap)
4325 		{
4326 			qint32 w, h;
4327 			quint32 pixelFormat, imgType;
4328 			ds >> w >> h >> dummy;
4329 			ds >> pixelFormat >> imgType;
4330 			sty.MetaFile = false;
4331 			sty.imageType = imgType;
4332 			sty.imageWidth = w;
4333 			sty.imageHeight = h;
4334 			sty.imagePixelFormat = pixelFormat;
4335 			sty.imageData.resize(dataSize - 28);
4336 			retVal = ds.readRawData(sty.imageData.data(), dataSize - 28);
4337 		}
4338 		else if (dataV == U_IDT_Metafile)
4339 		{
4340 			quint32 imgType, imgSize;
4341 			ds >> imgType >> imgSize;
4342 			if (imgType == U_MDT_WmfPlaceable)
4343 			{
4344 				QByteArray hea;
4345 				hea.resize(22);
4346 				ds.readRawData(hea.data(), 22);
4347 				ds.skipRawData(2);
4348 				QByteArray dta;
4349 				dta.resize(dataSize - 40);
4350 				retVal = ds.readRawData(dta.data(), dataSize - 40);
4351 				retVal += 24;
4352 				sty.imageData = hea;
4353 				sty.imageData += dta;
4354 			}
4355 			else
4356 			{
4357 				sty.imageData.resize(dataSize - 16);
4358 				retVal = ds.readRawData(sty.imageData.data(), dataSize - 16);
4359 			}
4360 			sty.imageType = imgType;
4361 			sty.MetaFile = true;
4362 		}
4363 	}
4364 	else
4365 	{
4366 		if (emfStyleMapEMP.contains(id))
4367 		{
4368 			QByteArray hea;
4369 			hea.resize(dataSize);
4370 			retVal = ds.readRawData(hea.data(), dataSize);
4371 			emfStyleMapEMP[id].imageData += hea;
4372 		}
4373 	}
4374 	return retVal;
4375 }
4376 
handleEMPFont(QDataStream & ds,quint16 id)4377 void EmfPlug::handleEMPFont(QDataStream &ds, quint16 id)
4378 {
4379 	quint32 dummy, unit, flags, length;
4380 	float emSize;
4381 	ds >> dummy;
4382 	ds >> emSize;
4383 	ds >> unit >> flags >> dummy >> length;
4384 	QString fontName = "";
4385 	for (quint32 a = 0; a < length; a++)
4386 	{
4387 		quint16 cc;
4388 		ds >> cc;
4389 		fontName.append(QChar(cc));
4390 	}
4391 	emfStyle sty;
4392 	sty.styType = U_OT_Font;
4393 	sty.fontSize = emSize;
4394 	sty.fontName = fontName;
4395 	sty.fontUnit = unit;
4396 	emfStyleMapEMP.insert(id, sty);
4397 }
4398 
handleEMPSFormat(QDataStream & ds,quint16 id)4399 void EmfPlug::handleEMPSFormat(QDataStream &ds, quint16 id)
4400 {
4401 	quint32 dummy, flags, hAlign, vAlign;
4402 	ds >> dummy >> flags >> dummy >> hAlign >> vAlign;
4403 	emfStyle sty;
4404 	sty.styType = U_OT_StringFormat;
4405 	sty.hAlign = hAlign;
4406 	sty.vAlign = vAlign;
4407 	sty.verticalText = (flags & 0x00000002);
4408 	emfStyleMapEMP.insert(id, sty);
4409 }
4410 
handleEMPLineCap(QDataStream & ds,quint16 id)4411 void EmfPlug::handleEMPLineCap(QDataStream &ds, quint16 id)
4412 {
4413 	qDebug() << "\t\tLine Cap";
4414 }
4415 
handleEMFPFillClosedCurve(QDataStream & ds,quint8 flagsL)4416 void EmfPlug::handleEMFPFillClosedCurve(QDataStream &ds, quint8 flagsL)
4417 {
4418 	quint32 brushID, count;
4419 	float tension;
4420 	ds >> brushID;
4421 	ds >> tension;
4422 	ds >> count;
4423 	bool directBrush = (flagsL & 0x80);
4424 	currentDC.fillRule = !(flagsL & 0x20);
4425 	getEMFPBrush(brushID, directBrush);
4426 	QPolygonF points = getEMFPCurvePoints(ds, flagsL, count);
4427 	QPainterPath path;
4428 	GdipAddPathClosedCurve(path, points, tension);
4429 	FPointArray polyline;
4430 	polyline.fromQPainterPath(path);
4431 	if (polyline.size() > 3)
4432 	{
4433 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
4434 		PageItem* ite = m_Doc->Items->at(z);
4435 		ite->PoLine = polyline.copy();
4436 		finishItem(ite);
4437 	}
4438 }
4439 
handleEMFPFillEllipse(QDataStream & ds,quint8 flagsL)4440 void EmfPlug::handleEMFPFillEllipse(QDataStream &ds, quint8 flagsL)
4441 {
4442 	quint32 brushID;
4443 	ds >> brushID;
4444 	bool directBrush = (flagsL & 0x80);
4445 	bool compressedRects = (flagsL & 0x40);
4446 	getEMFPBrush(brushID, directBrush);
4447 	QPointF p = getEMFPPoint(ds, compressedRects);
4448 	double w = getEMFPDistance(ds, compressedRects);
4449 	double h = getEMFPDistance(ds, compressedRects);
4450 	int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX, baseY, w, h, 0, currentDC.CurrColorFill, CommonStrings::None);
4451 	PageItem* ite = m_Doc->Items->at(z);
4452 	QTransform mm(1.0, 0.0, 0.0, 1.0, p.x(), p.y());
4453 	ite->PoLine.map(mm);
4454 	finishItem(ite);
4455 }
4456 
handleEMFPFillPath(QDataStream & ds,quint8 flagsL,quint8 flagsH)4457 void EmfPlug::handleEMFPFillPath(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4458 {
4459 	quint32 brushID;
4460 	ds >> brushID;
4461 	bool directBrush = (flagsL & 0x80);
4462 	getEMFPBrush(brushID, directBrush);
4463 	if (emfStyleMapEMP.contains(flagsH))
4464 	{
4465 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
4466 		PageItem* ite = m_Doc->Items->at(z);
4467 		ite->PoLine = emfStyleMapEMP[flagsH].Coords.copy();
4468 		finishItem(ite);
4469 	}
4470 }
4471 
handleEMFPFillPie(QDataStream & ds,quint8 flagsL)4472 void EmfPlug::handleEMFPFillPie(QDataStream &ds, quint8 flagsL)
4473 {
4474 	quint32 brushID;
4475 	float startA, sweepA;
4476 	ds >> brushID;
4477 	ds >> startA >> sweepA;
4478 	bool directBrush    = (flagsL & 0x80);
4479 	bool rectCompressed = (flagsL & 0x40);
4480 	getEMFPBrush(brushID, directBrush);
4481 	QRectF rect = getEMFPRect(ds, rectCompressed).boundingRect();
4482 	FPointArray  pointArray;
4483 	QPainterPath painterPath;
4484 	painterPath.arcMoveTo(rect, -startA);
4485 	QPointF firstPoint = painterPath.currentPosition();
4486 	painterPath.arcTo(rect, -startA, -sweepA);
4487 	painterPath.lineTo(rect.center());
4488 	painterPath.lineTo(firstPoint);
4489 	pointArray.fromQPainterPath(painterPath);
4490 	if (pointArray.size() > 3)
4491 	{
4492 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
4493 		PageItem* ite = m_Doc->Items->at(z);
4494 		ite->PoLine = pointArray.copy();
4495 		finishItem(ite);
4496 	}
4497 }
4498 
handleEMFPFillPolygon(QDataStream & ds,quint8 flagsL)4499 void EmfPlug::handleEMFPFillPolygon(QDataStream &ds, quint8 flagsL)
4500 {
4501 	quint32 brushID, count;
4502 	ds >> brushID >> count;
4503 	bool directBrush         = (flagsL & 0x80);
4504 	bool compressedPoints    = (flagsL & 0x40);
4505 	bool relativeCoordinates = (flagsL & 0x08);
4506 	getEMFPBrush(brushID, directBrush);
4507 	if (!relativeCoordinates)
4508 	{
4509 		bool bFirst = true;
4510 		FPointArray polyline;
4511 		polyline.svgInit();
4512 		for (quint32 a = 0; a < count; a++)
4513 		{
4514 			QPointF p = getEMFPPoint(ds, compressedPoints);
4515 			if (bFirst)
4516 			{
4517 				polyline.svgMoveTo(p.x(), p.y());
4518 				bFirst = false;
4519 			}
4520 			else
4521 				polyline.svgLineTo(p.x(), p.y());
4522 		}
4523 		if (polyline.size() > 3)
4524 		{
4525 			polyline.svgClosePath();
4526 			int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
4527 			PageItem* ite = m_Doc->Items->at(z);
4528 			ite->PoLine = polyline.copy();
4529 			finishItem(ite);
4530 		}
4531 	}
4532 }
4533 
handleEMFPFillRects(QDataStream & ds,quint8 flagsL)4534 void EmfPlug::handleEMFPFillRects(QDataStream &ds, quint8 flagsL)
4535 {
4536 	quint32 brushID, count;
4537 	ds >> brushID >> count;
4538 	bool directBrush = (flagsL & 0x80);
4539 	bool compressedRects = (flagsL & 0x40);
4540 	getEMFPBrush(brushID, directBrush);
4541 	for (quint32 a = 0; a < count; a++)
4542 	{
4543 		QPolygonF rect = getEMFPRect(ds, compressedRects);
4544 		FPointArray polyline;
4545 		polyline.svgInit();
4546 		polyline.svgMoveTo(rect[0].x(), rect[0].y());
4547 		polyline.svgLineTo(rect[1].x(), rect[1].y());
4548 		polyline.svgLineTo(rect[2].x(), rect[2].y());
4549 		polyline.svgLineTo(rect[3].x(), rect[3].y());
4550 		polyline.svgClosePath();
4551 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
4552 		PageItem* ite = m_Doc->Items->at(z);
4553 		ite->PoLine = polyline.copy();
4554 		finishItem(ite);
4555 	}
4556 }
4557 
handleEMFPFillRegion(QDataStream & ds,quint8 flagsL,quint8 flagsH)4558 void EmfPlug::handleEMFPFillRegion(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4559 {
4560 	quint32 brushID;
4561 	ds >> brushID;
4562 	bool directBrush = (flagsL & 0x80);
4563 	getEMFPBrush(brushID, directBrush);
4564 	if (emfStyleMapEMP.contains(flagsH))
4565 	{
4566 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
4567 		PageItem* ite = m_Doc->Items->at(z);
4568 		ite->PoLine = emfStyleMapEMP[flagsH].Coords.copy();
4569 		finishItem(ite);
4570 	}
4571 }
4572 
handleEMFPDrawArc(QDataStream & ds,quint8 flagsL,quint8 flagsH)4573 void EmfPlug::handleEMFPDrawArc(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4574 {
4575 	float startA, sweepA;
4576 	bool compressedRects = (flagsL & 0x40);
4577 	getEMFPPen(flagsH);
4578 	ds >> startA >> sweepA;
4579 	QRectF rect = getEMFPRect(ds, compressedRects).boundingRect();
4580 	FPointArray  pointArray;
4581 	QPainterPath painterPath;
4582 	painterPath.arcMoveTo(rect, -startA);
4583 	painterPath.arcTo(rect, -startA, -sweepA);
4584 	pointArray.fromQPainterPath(painterPath);
4585 	if (pointArray.size() > 3)
4586 	{
4587 		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
4588 		PageItem* ite = m_Doc->Items->at(z);
4589 		ite->PoLine = pointArray.copy();
4590 		finishItem(ite, false);
4591 	}
4592 }
4593 
handleEMFPDrawBezier(QDataStream & ds,quint8 flagsL,quint8 flagsH)4594 void EmfPlug::handleEMFPDrawBezier(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4595 {
4596 	quint32 count;
4597 	ds >> count;
4598 	getEMFPPen(flagsH);
4599 	bool compressedPoints    = (flagsL & 0x40);
4600 	bool closedPolyline      = (flagsL & 0x20);
4601 	bool relativeCoordinates = (flagsL & 0x08);
4602 	if (!relativeCoordinates)
4603 	{
4604 		FPointArray polyline;
4605 		polyline.svgInit();
4606 		QPointF p1 = getEMFPPoint(ds, compressedPoints);
4607 		polyline.svgMoveTo(p1.x(), p1.y());
4608 		for (quint32 a = 1; a < count; a += 3)
4609 		{
4610 			QPointF p2 = getEMFPPoint(ds, compressedPoints);
4611 			QPointF p3 = getEMFPPoint(ds, compressedPoints);
4612 			QPointF p4 = getEMFPPoint(ds, compressedPoints);
4613 			polyline.svgCurveToCubic(p2.x(), p2.y(), p3.x(), p3.y(), p4.x(), p4.y());
4614 		}
4615 		if (polyline.size() > 3)
4616 		{
4617 			if (closedPolyline)
4618 				polyline.svgClosePath();
4619 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
4620 			PageItem* ite = m_Doc->Items->at(z);
4621 			ite->PoLine = polyline.copy();
4622 			finishItem(ite, false);
4623 		}
4624 	}
4625 }
4626 
handleEMFPDrawClosedCurve(QDataStream & ds,quint8 flagsL,quint8 flagsH)4627 void EmfPlug::handleEMFPDrawClosedCurve(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4628 {
4629 	quint32 count;
4630 	float tension;
4631 	ds >> tension;
4632 	ds >> count;
4633 	getEMFPPen(flagsH);
4634 	QPolygonF points = getEMFPCurvePoints(ds, flagsL, count);
4635 	QPainterPath path;
4636 	GdipAddPathClosedCurve(path, points, tension);
4637 	FPointArray polyline;
4638 	polyline.fromQPainterPath(path);
4639 	if (polyline.size() > 3)
4640 	{
4641 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
4642 		PageItem* ite = m_Doc->Items->at(z);
4643 		ite->PoLine = polyline.copy();
4644 		finishItem(ite, false);
4645 	}
4646 }
4647 
handleEMFPDrawCurve(QDataStream & ds,quint8 flagsL,quint8 flagsH)4648 void EmfPlug::handleEMFPDrawCurve(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4649 {
4650 	quint32 count, offset, numSegs;
4651 	float tension;
4652 	ds >> tension;
4653 	ds >> offset >> numSegs >> count;
4654 	getEMFPPen(flagsH);
4655 	QPolygonF points = getEMFPCurvePoints(ds, flagsL, count);
4656 	QPainterPath path;
4657 	GdipAddPathCurve(path, points, tension);
4658 	FPointArray polyline;
4659 	polyline.fromQPainterPath(path);
4660 	if (polyline.size() > 3)
4661 	{
4662 		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
4663 		PageItem* ite = m_Doc->Items->at(z);
4664 		ite->PoLine = polyline.copy();
4665 		finishItem(ite, false);
4666 	}
4667 }
4668 
handleEMFPDrawEllipse(QDataStream & ds,quint8 flagsL,quint8 flagsH)4669 void EmfPlug::handleEMFPDrawEllipse(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4670 {
4671 	bool compressedRects = (flagsL & 0x40);
4672 	getEMFPPen(flagsH);
4673 	QPointF p = getEMFPPoint(ds, compressedRects);
4674 	double w = getEMFPDistance(ds, compressedRects);
4675 	double h = getEMFPDistance(ds, compressedRects);
4676 	int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX, baseY, w, h, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
4677 	PageItem* ite = m_Doc->Items->at(z);
4678 	QTransform mm(1.0, 0.0, 0.0, 1.0, p.x(), p.y());
4679 	ite->PoLine.map(mm);
4680 	finishItem(ite, false);
4681 }
4682 
handleEMFPDrawImage(QDataStream & ds,quint8 flagsL,quint8 flagsH)4683 void EmfPlug::handleEMFPDrawImage(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4684 {
4685 	if (!emfStyleMapEMP.contains(flagsH))
4686 		return;
4687 	quint32 imgAttrs, dummy;
4688 	ds >> imgAttrs;
4689 	bool compressedPoints    = (flagsL & 0x40);
4690 	bool relativeCoordinates = (flagsL & 0x08);
4691 	currentDC.CurrFillTrans = 0.0;
4692 	if (!relativeCoordinates)
4693 	{
4694 		ds >> dummy >> dummy >> dummy >> dummy >> dummy;
4695 		QPolygonF rect = getEMFPRect(ds, compressedPoints);
4696 		QPointF p1 = rect[0];
4697 		QPointF p2 = rect[1];
4698 		QPointF p3 = rect[3];
4699 		handleEMFPDrawImageData(p1, p2, p3, flagsH);
4700 	}
4701 }
4702 
handleEMFPDrawImagePoints(QDataStream & ds,quint8 flagsL,quint8 flagsH)4703 void EmfPlug::handleEMFPDrawImagePoints(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4704 {
4705 	if (!emfStyleMapEMP.contains(flagsH))
4706 		return;
4707 	quint32 imgAttrs, dummy, count;
4708 	ds >> imgAttrs;
4709 	bool compressedPoints    = (flagsL & 0x40);
4710 	bool relativeCoordinates = (flagsL & 0x08);
4711 	currentDC.CurrFillTrans = 0.0;
4712 	if (!relativeCoordinates)
4713 	{
4714 		ds >> dummy >> dummy >> dummy >> dummy >> dummy;
4715 		ds >> count;
4716 		QPointF p1 = getEMFPPoint(ds, compressedPoints);
4717 		QPointF p2 = getEMFPPoint(ds, compressedPoints);
4718 		QPointF p3 = getEMFPPoint(ds, compressedPoints);
4719 		handleEMFPDrawImageData(p1, p2, p3, flagsH);
4720 	}
4721 }
4722 
handleEMFPDrawLines(QDataStream & ds,quint8 flagsL,quint8 flagsH)4723 void EmfPlug::handleEMFPDrawLines(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4724 {
4725 	quint32 count;
4726 	ds >> count;
4727 	getEMFPPen(flagsH);
4728 	bool compressedPoints    = (flagsL & 0x40);
4729 	bool closedPolyline      = (flagsL & 0x20);
4730 	bool relativeCoordinates = (flagsL & 0x08);
4731 	if (!relativeCoordinates)
4732 	{
4733 		bool bFirst = true;
4734 		FPointArray polyline;
4735 		polyline.svgInit();
4736 		for (quint32 a = 0; a < count; a++)
4737 		{
4738 			QPointF p = getEMFPPoint(ds, compressedPoints);
4739 			if (bFirst)
4740 			{
4741 				polyline.svgMoveTo(p.x(), p.y());
4742 				bFirst = false;
4743 			}
4744 			else
4745 				polyline.svgLineTo(p.x(), p.y());
4746 		}
4747 		if (polyline.size() > 3)
4748 		{
4749 			if (closedPolyline)
4750 				polyline.svgClosePath();
4751 			int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
4752 			PageItem* ite = m_Doc->Items->at(z);
4753 			ite->PoLine = polyline.copy();
4754 			finishItem(ite, false);
4755 		}
4756 	}
4757 }
4758 
handleEMFPDrawPath(QDataStream & ds,quint8 flagsH)4759 void EmfPlug::handleEMFPDrawPath(QDataStream &ds, quint8 flagsH)
4760 {
4761 	quint32 penID;
4762 	ds >> penID;
4763 	getEMFPPen(penID);
4764 	if (emfStyleMapEMP.contains(flagsH))
4765 	{
4766 		int z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
4767 		PageItem* ite = m_Doc->Items->at(z);
4768 		ite->PoLine = emfStyleMapEMP[flagsH].Coords.copy();
4769 		finishItem(ite, false);
4770 	}
4771 }
4772 
handleEMFPDrawPie(QDataStream & ds,quint8 flagsL,quint8 flagsH)4773 void EmfPlug::handleEMFPDrawPie(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4774 {
4775 	float startA, sweepA;
4776 	bool compressedRects = (flagsL & 0x40);
4777 	getEMFPPen(flagsH);
4778 	ds >> startA >> sweepA;
4779 	QRectF rect = getEMFPRect(ds, compressedRects).boundingRect();
4780 	FPointArray  pointArray;
4781 	QPainterPath painterPath;
4782 	painterPath.arcMoveTo(rect, -startA);
4783 	QPointF firstPoint = painterPath.currentPosition();
4784 	painterPath.arcTo(rect, -startA, -sweepA);
4785 	painterPath.lineTo(rect.center());
4786 	painterPath.lineTo(firstPoint);
4787 	pointArray.fromQPainterPath(painterPath);
4788 	if (pointArray.size() > 3)
4789 	{
4790 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
4791 		PageItem* ite = m_Doc->Items->at(z);
4792 		ite->PoLine = pointArray.copy();
4793 		finishItem(ite, false);
4794 	}
4795 }
4796 
handleEMFPDrawRects(QDataStream & ds,quint8 flagsL,quint8 flagsH)4797 void EmfPlug::handleEMFPDrawRects(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4798 {
4799 	quint32 count;
4800 	ds >> count;
4801 	bool compressedRects = (flagsL & 0x40);
4802 	getEMFPPen(flagsH);
4803 	for (quint32 a = 0; a < count; a++)
4804 	{
4805 		QPolygonF rect = getEMFPRect(ds, compressedRects);
4806 		FPointArray polyline;
4807 		polyline.svgInit();
4808 		polyline.svgMoveTo(rect[0].x(), rect[0].y());
4809 		polyline.svgLineTo(rect[1].x(), rect[1].y());
4810 		polyline.svgLineTo(rect[2].x(), rect[2].y());
4811 		polyline.svgLineTo(rect[3].x(), rect[3].y());
4812 		polyline.svgClosePath();
4813 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, currentDC.LineW, CommonStrings::None, currentDC.CurrColorStroke);
4814 		PageItem* ite = m_Doc->Items->at(z);
4815 		ite->PoLine = polyline.copy();
4816 		finishItem(ite, false);
4817 	}
4818 }
4819 
handleEMFPDrawDriverString(QDataStream & ds,quint8 flagsL,quint8 flagsH)4820 void EmfPlug::handleEMFPDrawDriverString(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4821 {
4822 	quint32 brushID, txOpts, matrix, numChars;
4823 	ds >> brushID >> txOpts >> matrix >> numChars;
4824 	bool directBrush = (flagsL & 0x80);
4825 	getEMFPBrush(brushID, directBrush);
4826 	getEMFPFont(flagsH);
4827 	quint32 unit = currentDC.fontUnit;
4828 	if ((unit == U_UT_World) || (unit == U_UT_Display))
4829 		unit = U_UT_Pixel;
4830 	double fSize = convertEMFPLogical2Pts(currentDC.fontSize, unit);
4831 	fSize *= 10.0;
4832 	QFont font = QFont(currentDC.fontName, fSize);
4833 	font.setPixelSize(fSize);
4834 	QList<QChar> stringData;
4835 	QList<quint32> glyphs;
4836 	QTransform txTrans = QTransform();
4837 	if (txOpts & 0x00000001)
4838 	{
4839 		for (quint32 a = 0; a < numChars; a++)
4840 		{
4841 			quint16 cc;
4842 			ds >> cc;
4843 			stringData.append(QChar(cc));
4844 		}
4845 	}
4846 	else
4847 	{
4848 		for (quint32 a = 0; a < numChars; a++)
4849 		{
4850 			quint16 cc;
4851 			ds >> cc;
4852 			glyphs.append(cc);
4853 		}
4854 	}
4855 	QList<QPointF> dxTxt;
4856 	for (quint32 a = 0; a < numChars; a++)
4857 	{
4858 		QPointF p = getEMFPPoint(ds, false);
4859 		dxTxt.append(p);
4860 	}
4861 	if (matrix == 1)
4862 	{
4863 		float m11, m12, m21, m22, dx, dy;
4864 		ds >> m11 >> m12 >> m21 >> m22 >> dx >> dy;
4865 		txTrans = QTransform(m11, m12, m21, m22, dx, dy);
4866 	}
4867 	QPainterPath painterPath;
4868 	if (txOpts & 0x00000001)
4869 	{
4870 		for (quint32 a = 0; a < numChars; a++)
4871 		{
4872 			QPainterPath gPath;
4873 			gPath.addText(0, 0, font, stringData[a]);
4874 			QTransform mm;
4875 			mm.scale(0.1, 0.1);
4876 			gPath = mm.map(gPath);
4877 			gPath.translate(dxTxt[a].x(), dxTxt[a].y());
4878 			gPath = txTrans.map(gPath);
4879 			painterPath.addPath(gPath);
4880 		}
4881 	}
4882 	else
4883 	{
4884 		QRawFont rFont = QRawFont::fromFont(font);
4885 		for (quint32 a = 0; a < numChars; a++)
4886 		{
4887 			QPainterPath gPath = rFont.pathForGlyph(glyphs[a]);
4888 			QTransform mm;
4889 			mm.scale(0.1, 0.1);
4890 			gPath = mm.map(gPath);
4891 			gPath.translate(dxTxt[a].x(), dxTxt[a].y());
4892 			gPath = txTrans.map(gPath);
4893 			painterPath.addPath(gPath);
4894 		}
4895 	}
4896 	FPointArray textPath;
4897 	textPath.fromQPainterPath(painterPath);
4898 	if (!textPath.empty())
4899 	{
4900 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
4901 		PageItem* ite = m_Doc->Items->at(z);
4902 		ite->PoLine = textPath.copy();
4903 		finishItem(ite);
4904 	}
4905 }
4906 
handleEMFPDrawString(QDataStream & ds,quint8 flagsL,quint8 flagsH)4907 void EmfPlug::handleEMFPDrawString(QDataStream &ds, quint8 flagsL, quint8 flagsH)
4908 {
4909 	quint32 brushID, formatID, numChars;
4910 	FPointArray textPath;
4911 	QPainterPath painterPath;
4912 	ds >> brushID >> formatID >> numChars;
4913 	QPolygonF rect = getEMFPRect(ds, false);
4914 	QString stringData = "";
4915 	for (quint32 a = 0; a < numChars; a++)
4916 	{
4917 		quint16 cc;
4918 		ds >> cc;
4919 		stringData.append(QChar(cc));
4920 	}
4921 	bool directBrush = (flagsL & 0x80);
4922 	getEMFPBrush(brushID, directBrush);
4923 	getEMFPFont(flagsH);
4924 	getEMFPStringFormat(formatID);
4925 	quint32 unit = currentDC.fontUnit;
4926 	if ((unit == U_UT_World) || (unit == U_UT_Display))
4927 		unit = U_UT_Pixel;
4928 	double fSize = convertEMFPLogical2Pts(currentDC.fontSize, unit);
4929 	if (fSize < 5)
4930 	{
4931 		QFont font = QFont(currentDC.fontName, fSize * 10);
4932 		font.setPixelSize(fSize * 10);
4933 		painterPath.addText(0, 0, font, stringData);
4934 		QTransform mm;
4935 		mm.scale(0.1, 0.1);
4936 		painterPath = mm.map(painterPath);
4937 	}
4938 	else
4939 	{
4940 		QFont font = QFont(currentDC.fontName, fSize);
4941 		font.setPixelSize(fSize);
4942 		painterPath.addText(0, 0, font, stringData);
4943 	}
4944 	painterPath.translate(0, -painterPath.boundingRect().y());
4945 	if (currentDC.verticalText)
4946 	{
4947 		QTransform vm;
4948 		vm.rotate(90);
4949 		painterPath = vm.map(painterPath);
4950 		painterPath.translate(-painterPath.boundingRect().x(), 0);
4951 	}
4952 	double sh = rect.boundingRect().height();
4953 	double sw = rect.boundingRect().width();
4954 	if (currentDC.verticalText)
4955 	{
4956 		if (sh > 0)
4957 		{
4958 			if (currentDC.hAlign == U_SA_Center)
4959 				painterPath.translate(0, (sh - painterPath.boundingRect().height()) / 2.0);
4960 			else if (currentDC.hAlign == U_SA_Far)
4961 				painterPath.translate(0, sh - painterPath.boundingRect().height());
4962 		}
4963 		if (sw > 0)
4964 		{
4965 			if (currentDC.vAlign == U_SA_Center)
4966 				painterPath.translate((sw - painterPath.boundingRect().width()) / 2.0, 0);
4967 			else if (currentDC.vAlign == U_SA_Far)
4968 				painterPath.translate(sw - painterPath.boundingRect().width(), 0);
4969 		}
4970 	}
4971 	else
4972 	{
4973 		if (sw > 0)
4974 		{
4975 			if (currentDC.hAlign == U_SA_Center)
4976 				painterPath.translate((sw - painterPath.boundingRect().width()) / 2.0, 0);
4977 			else if (currentDC.hAlign == U_SA_Far)
4978 				painterPath.translate(sw - painterPath.boundingRect().width(), 0);
4979 		}
4980 		if (sh > 0)
4981 		{
4982 			if (currentDC.vAlign == U_SA_Center)
4983 				painterPath.translate(0, (sh - painterPath.boundingRect().height()) / 2.0);
4984 			else if (currentDC.vAlign == U_SA_Far)
4985 				painterPath.translate(0, sh - painterPath.boundingRect().height());
4986 		}
4987 	}
4988 	QTransform bm = currentDC.m_WorldMapEMFP;
4989 	bm = QTransform(bm.m11(), bm.m12(), bm.m21(), bm.m22(), 0, 0);
4990 	painterPath = bm.map(painterPath);
4991 	painterPath.translate(rect[0].x(), rect[0].y());
4992 	textPath.fromQPainterPath(painterPath);
4993 	if (!textPath.empty())
4994 	{
4995 		int z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, 0, currentDC.CurrColorFill, CommonStrings::None);
4996 		PageItem* ite = m_Doc->Items->at(z);
4997 		ite->PoLine = textPath.copy();
4998 		finishItem(ite);
4999 	}
5000 }
5001 
handleEMFPSetClipRect(QDataStream & ds,quint8 flagsL)5002 void EmfPlug::handleEMFPSetClipRect(QDataStream &ds, quint8 flagsL)
5003 {
5004 	invalidateClipGroup();
5005 	quint8 mode = flagsL & 0x0F;
5006 	QPolygonF rect = getEMFPRect(ds, false);
5007 	FPointArray clipPath;
5008 	clipPath.resize(0);
5009 	clipPath.svgInit();
5010 	clipPath.svgMoveTo(rect[0].x(), rect[0].y());
5011 	clipPath.svgLineTo(rect[1].x(), rect[1].y());
5012 	clipPath.svgLineTo(rect[2].x(), rect[2].y());
5013 	clipPath.svgLineTo(rect[3].x(), rect[3].y());
5014 	clipPath.svgClosePath();
5015 	if ((mode == 0) || (!currentDC.clipValid))
5016 	{
5017 		if (checkClip(clipPath))
5018 		{
5019 			currentDC.clipPath = clipPath.copy();
5020 			currentDC.clipValid = true;
5021 			createClipGroup();
5022 		}
5023 	}
5024 	else
5025 	{
5026 		QPainterPath pathN = clipPath.toQPainterPath(true);
5027 		QPainterPath pathA = currentDC.clipPath.toQPainterPath(true);
5028 		QPainterPath resultPath;
5029 		if (mode == 1)
5030 			resultPath = pathA.intersected(pathN);
5031 		else if (mode == 2)
5032 			resultPath = pathA.united(pathN);
5033 		else if (mode == 3)
5034 		{
5035 			QPainterPath part1 = pathA.subtracted(pathN);
5036 			QPainterPath part2 = pathN.subtracted(pathA);
5037 			resultPath.addPath(part1);
5038 			resultPath.addPath(part2);
5039 		}
5040 		if (!resultPath.isEmpty())
5041 		{
5042 			FPointArray polyline;
5043 			polyline.resize(0);
5044 			polyline.fromQPainterPath(resultPath, true);
5045 			polyline.svgClosePath();
5046 			if (checkClip(polyline))
5047 			{
5048 				currentDC.clipPath = polyline.copy();
5049 				currentDC.clipValid = true;
5050 				createClipGroup();
5051 			}
5052 		}
5053 		else
5054 			currentDC.clipValid = false;
5055 	}
5056 }
5057 
handleEMFPSetClipRegion(QDataStream & ds,quint8 flagsL,quint8 flagsH)5058 void EmfPlug::handleEMFPSetClipRegion(QDataStream &ds, quint8 flagsL, quint8 flagsH)
5059 {
5060 	invalidateClipGroup();
5061 	if (emfStyleMapEMP.contains(flagsH))
5062 	{
5063 		if (emfStyleMapEMP[flagsH].Coords.isEmpty())
5064 		{
5065 			currentDC.clipPath.resize(0);
5066 			currentDC.clipPath.svgInit();
5067 			currentDC.clipValid = false;
5068 			return;
5069 		}
5070 		quint8 mode = flagsL & 0x0F;
5071 		if ((mode == 0) || (!currentDC.clipValid))
5072 		{
5073 			if (checkClip(emfStyleMapEMP[flagsH].Coords))
5074 			{
5075 				currentDC.clipPath = emfStyleMapEMP[flagsH].Coords.copy();
5076 				currentDC.clipValid = true;
5077 				createClipGroup();
5078 			}
5079 		}
5080 		else
5081 		{
5082 			FPointArray clipPath = emfStyleMapEMP[flagsH].Coords.copy();
5083 			QPainterPath pathN = clipPath.toQPainterPath(true);
5084 			QPainterPath pathA = currentDC.clipPath.toQPainterPath(true);
5085 			QPainterPath resultPath;
5086 			if (mode == 1)
5087 				resultPath = pathA.intersected(pathN);
5088 			else if (mode == 2)
5089 				resultPath = pathA.united(pathN);
5090 			else if (mode == 3)
5091 			{
5092 				QPainterPath part1 = pathA.subtracted(pathN);
5093 				QPainterPath part2 = pathN.subtracted(pathA);
5094 				resultPath.addPath(part1);
5095 				resultPath.addPath(part2);
5096 			}
5097 			if (!resultPath.isEmpty())
5098 			{
5099 				FPointArray polyline;
5100 				polyline.resize(0);
5101 				polyline.fromQPainterPath(resultPath, true);
5102 				polyline.svgClosePath();
5103 				if (checkClip(polyline))
5104 				{
5105 					currentDC.clipPath = polyline.copy();
5106 					currentDC.clipValid = true;
5107 					createClipGroup();
5108 				}
5109 			}
5110 			else
5111 				currentDC.clipValid = false;
5112 		}
5113 	}
5114 	else
5115 	{
5116 		currentDC.clipPath.resize(0);
5117 		currentDC.clipPath.svgInit();
5118 		currentDC.clipValid = false;
5119 	}
5120 }
5121 
handleEMFPSetClipPath(QDataStream & ds,quint8 flagsL,quint8 flagsH)5122 void EmfPlug::handleEMFPSetClipPath(QDataStream &ds, quint8 flagsL, quint8 flagsH)
5123 {
5124 	invalidateClipGroup();
5125 	if (emfStyleMapEMP.contains(flagsH))
5126 	{
5127 		quint8 mode = flagsL & 0x0F;
5128 		if ((mode == 0) || (!currentDC.clipValid))
5129 		{
5130 			if (checkClip(emfStyleMapEMP[flagsH].Coords))
5131 			{
5132 				currentDC.clipPath = emfStyleMapEMP[flagsH].Coords.copy();
5133 				currentDC.clipValid = true;
5134 				createClipGroup();
5135 			}
5136 		}
5137 		else
5138 		{
5139 			FPointArray clipPath = emfStyleMapEMP[flagsH].Coords.copy();
5140 			QPainterPath pathN = clipPath.toQPainterPath(true);
5141 			QPainterPath pathA = currentDC.clipPath.toQPainterPath(true);
5142 			QPainterPath resultPath;
5143 			if (mode == 1)
5144 				resultPath = pathA.intersected(pathN);
5145 			else if (mode == 2)
5146 				resultPath = pathA.united(pathN);
5147 			else if (mode == 3)
5148 			{
5149 				QPainterPath part1 = pathA.subtracted(pathN);
5150 				QPainterPath part2 = pathN.subtracted(pathA);
5151 				resultPath.addPath(part1);
5152 				resultPath.addPath(part2);
5153 			}
5154 			if (!resultPath.isEmpty())
5155 			{
5156 				FPointArray polyline;
5157 				polyline.resize(0);
5158 				polyline.fromQPainterPath(resultPath, true);
5159 				polyline.svgClosePath();
5160 				if (checkClip(polyline))
5161 				{
5162 					currentDC.clipPath = polyline.copy();
5163 					currentDC.clipValid = true;
5164 					createClipGroup();
5165 				}
5166 			}
5167 			else
5168 				currentDC.clipValid = false;
5169 		}
5170 	}
5171 }
5172 
handleEMFPSerializableObject(QDataStream & ds)5173 void EmfPlug::handleEMFPSerializableObject(QDataStream &ds)
5174 {
5175 	quint32 l;
5176 	quint16 w1, w2;
5177 	quint8 b1, b2, b3, b4, b5, b6, b7, b8;
5178 	ds >> l;
5179 	ds >> w1 >> w2;
5180 	ds >> b1 >> b2 >> b3 >> b4 >> b5 >> b6 >> b7 >> b8;
5181 	QString effID = QUuid(l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8).toString().toUpper();
5182 	m_Effects.clear();
5183 	SerializableObject_Valid = false;
5184 	if (effID == U_IE_BlurEffectGuid)
5185 	{
5186 		SerializableObject_Valid = true;
5187 		float edge;
5188 		ds >> edge;
5189 		ImageEffect ef;
5190 		ef.effectCode = ImageEffect::EF_BLUR;
5191 		ef.effectParameters = QString("%1 1.0").arg(edge / 255.0 * 30.0);
5192 		m_Effects.append(ef);
5193 	}
5194 	else if (effID == U_IE_BrightnessContrastEffectGuid)
5195 	{
5196 		SerializableObject_Valid = true;
5197 		qint32 brightness, contrast;
5198 		ds >> brightness >> contrast;
5199 		if (brightness != 0)
5200 		{
5201 			ImageEffect ef;
5202 			ef.effectCode = ImageEffect::EF_BRIGHTNESS;
5203 			ef.effectParameters = QString("%1").arg(brightness);
5204 			m_Effects.append(ef);
5205 		}
5206 		if (contrast != 0)
5207 		{
5208 			ImageEffect ef;
5209 			ef.effectCode = ImageEffect::EF_CONTRAST;
5210 			ef.effectParameters = QString("%1").arg(qMin(qMax(qRound(contrast * 1.27), -127), 127));
5211 			m_Effects.append(ef);
5212 		}
5213 	}
5214 	else if (effID == U_IE_ColorBalanceEffectGuid)
5215 		qDebug() << "ImageEffect\tColorbalance";
5216 	else if (effID == U_IE_ColorCurveEffectGuid)
5217 		qDebug() << "ImageEffect\tColorCurve";
5218 	else if (effID == U_IE_ColorLookupTableEffectGuid)
5219 		qDebug() << "ImageEffect\tColorLookupTable";
5220 	else if (effID == U_IE_ColorMatrixEffectGuid)
5221 		qDebug() << "ImageEffect\tColorMatrix";
5222 	else if (effID == U_IE_HueSaturationLightnessEffectGuid)
5223 		qDebug() << "ImageEffect\tHSL";
5224 	else if (effID == U_IE_LevelsEffectGuid)
5225 		qDebug() << "ImageEffect\tLevels";
5226 	else if (effID == U_IE_RedEyeCorrectionEffectGuid)
5227 		qDebug() << "ImageEffect\tRedEye";
5228 	else if (effID == U_IE_SharpenEffectGuid)
5229 	{
5230 		SerializableObject_Valid = true;
5231 		float radius, amount;
5232 		ds >> radius >> amount;
5233 		double amo = amount;
5234 		double rad = radius;
5235 		ImageEffect ef;
5236 		ef.effectCode = ImageEffect::EF_SHARPEN;
5237 		ef.effectParameters = QString("%1 %2").arg(qMin(rad, 10.0)).arg(qMin(amo / 100.0 * 5.0, 5.0));
5238 		m_Effects.append(ef);
5239 	}
5240 	else if (effID == U_IE_TintEffectGuid)
5241 		qDebug() << "ImageEffect\tTint";
5242 	else
5243 		SerializableObject_Valid = false;
5244 }
5245 
getEMFPBrush(quint32 brushID,bool directBrush)5246 void EmfPlug::getEMFPBrush(quint32 brushID, bool directBrush)
5247 {
5248 	if (directBrush)
5249 	{
5250 		quint8 r = brushID & 0xFF;
5251 		quint8 g = (brushID >> 8) & 0xFF;
5252 		quint8 b = (brushID >> 16) & 0xFF;
5253 		quint8 a = (brushID >> 24) & 0xFF;
5254 		QColor col(b, g, r, a);
5255 		currentDC.CurrColorFill = handleColor(col);
5256 		currentDC.CurrFillTrans = 1.0 - col.alphaF();
5257 		currentDC.brushStyle = U_BT_SolidColor;
5258 	}
5259 	else
5260 	{
5261 		if (emfStyleMapEMP.contains(brushID))
5262 		{
5263 			emfStyle sty = emfStyleMapEMP[brushID];
5264 			currentDC.CurrColorFill = sty.brushColor;
5265 			currentDC.brushStyle = sty.brushStyle;
5266 			currentDC.hatchStyle = sty.hatchStyle;
5267 			currentDC.CurrFillTrans = sty.fillTrans;
5268 			if (sty.brushStyle == U_BT_HatchFill)
5269 			{
5270 				currentDC.backColor = sty.penColor;
5271 				currentDC.backgroundMode = true;
5272 			}
5273 			else if (sty.brushStyle == U_BT_LinearGradient)
5274 			{
5275 				currentDC.gradientStart = sty.gradientStart;
5276 				currentDC.gradientEnd = sty.gradientEnd;
5277 				currentDC.gradientAngle = sty.gradientAngle;
5278 				currentDC.gradient = sty.gradient;
5279 			}
5280 			else if (sty.brushStyle == U_BT_PathGradient)
5281 			{
5282 				currentDC.gradientStart = sty.gradientStart;
5283 				currentDC.gradientAngle = sty.gradientAngle;
5284 				currentDC.gradient = sty.gradient;
5285 				currentDC.gradientPath = sty.gradientPath.copy();
5286 			}
5287 			else if (sty.brushStyle == U_BT_TextureFill)
5288 			{
5289 				currentDC.patternMode = sty.patternMode;
5290 				if (sty.patternName.isEmpty())
5291 				{
5292 					if (!emfStyleMapEMP[brushID].MetaFile)
5293 					{
5294 						QImage img = getImageDataFromStyle(brushID);
5295 						if (!img.isNull())
5296 						{
5297 							QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_emf_XXXXXX.png");
5298 							tempFile->setAutoRemove(false);
5299 							if (tempFile->open())
5300 							{
5301 								QString fileName = getLongPathName(tempFile->fileName());
5302 								if (!fileName.isEmpty())
5303 								{
5304 									tempFile->close();
5305 									img.save(fileName, "PNG");
5306 									ScPattern pat = ScPattern();
5307 									pat.setDoc(m_Doc);
5308 									int z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, 0, 0, 1, 1, 0, CommonStrings::None, CommonStrings::None);
5309 									PageItem* newItem = m_Doc->Items->at(z);
5310 									m_Doc->loadPict(fileName, newItem);
5311 									m_Doc->Items->takeAt(z);
5312 									newItem->isInlineImage = true;
5313 									newItem->isTempFile = true;
5314 									pat.width = newItem->pixm.qImage().width();
5315 									pat.height = newItem->pixm.qImage().height();
5316 									pat.scaleX = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
5317 									pat.scaleY = (72.0 / newItem->pixm.imgInfo.xres) * newItem->pixm.imgInfo.lowResScale;
5318 									pat.pattern = newItem->pixm.qImage().copy();
5319 									newItem->setWidth(pat.pattern.width());
5320 									newItem->setHeight(pat.pattern.height());
5321 									newItem->SetRectFrame();
5322 									newItem->gXpos = 0.0;
5323 									newItem->gYpos = 0.0;
5324 									newItem->gWidth = pat.pattern.width();
5325 									newItem->gHeight = pat.pattern.height();
5326 									pat.items.append(newItem);
5327 									QString patternName = "Pattern_"+newItem->itemName();
5328 									m_Doc->addPattern(patternName, pat);
5329 									emfStyleMapEMP[brushID].patternName = patternName;
5330 									importedPatterns.append(patternName);
5331 									currentDC.patternName = patternName;
5332 								}
5333 							}
5334 						}
5335 					}
5336 				}
5337 				else
5338 					currentDC.patternName = sty.patternName;
5339 			}
5340 		}
5341 	}
5342 }
5343 
getEMFPPen(quint32 penID)5344 void EmfPlug::getEMFPPen(quint32 penID)
5345 {
5346 	if (emfStyleMapEMP.contains(penID))
5347 	{
5348 		emfStyle sty = emfStyleMapEMP[penID];
5349 		currentDC.CurrColorStroke = sty.penColor;
5350 		currentDC.CurrStrokeTrans = sty.penTrans;
5351 		currentDC.LineW = sty.penWidth;
5352 		currentDC.penCap = sty.penCap;
5353 		currentDC.penJoin = sty.penJoin;
5354 		currentDC.penStyle = sty.penStyle;
5355 		currentDC.dashArray = sty.dashArray;
5356 		currentDC.dashOffset = sty.dashOffset;
5357 	}
5358 }
5359 
getEMFPFont(quint32 fontID)5360 void EmfPlug::getEMFPFont(quint32 fontID)
5361 {
5362 	if (emfStyleMapEMP.contains(fontID))
5363 	{
5364 		emfStyle sty = emfStyleMapEMP[fontID];
5365 		currentDC.fontName = sty.fontName;
5366 		currentDC.fontSize = sty.fontSize;
5367 		currentDC.fontUnit = sty.fontUnit;
5368 	}
5369 }
5370 
getEMFPStringFormat(quint32 fontID)5371 void EmfPlug::getEMFPStringFormat(quint32 fontID)
5372 {
5373 	if (emfStyleMapEMP.contains(fontID))
5374 	{
5375 		emfStyle sty = emfStyleMapEMP[fontID];
5376 		currentDC.hAlign = sty.hAlign;
5377 		currentDC.vAlign = sty.vAlign;
5378 		currentDC.verticalText = sty.verticalText;
5379 	}
5380 }
5381 
getEMPPathData(QDataStream & ds)5382 FPointArray EmfPlug::getEMPPathData(QDataStream &ds)
5383 {
5384 	FPointArray polyline;
5385 	polyline.resize(0);
5386 	polyline.svgInit();
5387 	quint32 dummy, count;
5388 	quint16 flags, dummy2;
5389 	ds >> dummy >> count;
5390 	ds >> flags >> dummy2;
5391 	bool compressedPoints    = (flags & 0x4000);
5392 	bool rleEncodedType      = (flags & 0x1000);
5393 	bool relativeCoordinates = (flags & 0x0800);
5394 	QList<QPointF> points;
5395 	QList<quint8> pTypes;
5396 	if (!relativeCoordinates)
5397 	{
5398 		for (quint32 a = 0; a < count; a++)
5399 		{
5400 			QPointF p = getEMFPPoint(ds, compressedPoints);
5401 			points.append(p);
5402 		}
5403 		for (quint32 b = 0; b < count; b++)
5404 		{
5405 			if (rleEncodedType)
5406 			{
5407 				quint8 cc, flg;
5408 				ds >> cc >> flg;
5409 				cc = cc & 0x3F;
5410 				for (quint8 ccc = 0; ccc < cc; ccc++)
5411 				{
5412 					pTypes.append(flg);
5413 				}
5414 				b += cc;
5415 			}
5416 			else
5417 			{
5418 				quint8 val;
5419 				ds >> val;
5420 				pTypes.append(val);
5421 			}
5422 		}
5423 		for (quint32 c = 0; c < count; c++)
5424 		{
5425 			QPointF p = points[c];
5426 			quint8 pfl = (pTypes[c] & 0xF0) >> 4;
5427 			quint8 pty = pTypes[c] & 0x0F;
5428 			if (pty == U_PPT_Start)
5429 				polyline.svgMoveTo(p.x(), p.y());
5430 			else if (pty == U_PPT_Line)
5431 				polyline.svgLineTo(p.x(), p.y());
5432 			else if (pty == U_PPT_Bezier)
5433 			{
5434 				QPointF p2 = points[c+1];
5435 				QPointF p3 = points[c+2];
5436 				polyline.svgCurveToCubic(p.x(), p.y(), p2.x(), p2.y(), p3.x(), p3.y());
5437 				c += 2;
5438 				pfl = (pTypes[c] & 0xF0) >> 4;
5439 			}
5440 			if (pfl & 0x08)
5441 				polyline.svgClosePath();
5442 		}
5443 	}
5444 	return polyline;
5445 }
5446 
getEMFPCurvePoints(QDataStream & ds,quint8 flagsL,quint32 count)5447 QPolygonF EmfPlug::getEMFPCurvePoints(QDataStream &ds, quint8 flagsL, quint32 count)
5448 {
5449 	bool compressedPoints    = (flagsL & 0x40);
5450 	bool relativeCoordinates = (flagsL & 0x08);
5451 	QPolygonF points;
5452 	if (!relativeCoordinates)
5453 	{
5454 		for (quint32 a = 0; a < count; a++)
5455 		{
5456 			QPointF p = getEMFPPoint(ds, compressedPoints);
5457 			points.append(p);
5458 		}
5459 	}
5460 	return points;
5461 }
5462 
getEMFPRect(QDataStream & ds,bool size)5463 QPolygonF EmfPlug::getEMFPRect(QDataStream &ds, bool size)
5464 {
5465 	QPolygonF result;
5466 	QPointF p1, p2, p3, p4;
5467 	if (size)
5468 	{
5469 		qint16 x1, y1, w, h;
5470 		ds >> x1 >> y1 >> w >> h;
5471 		p1 = QPointF(x1, y1);
5472 		p2 = QPointF(p1.x() + w, p1.y());
5473 		p3 = QPointF(p1.x() + w, p1.y() + h);
5474 		p4 = QPointF(p1.x(), p1.y() + h);
5475 	}
5476 	else
5477 	{
5478 		float x1, y1, w, h;
5479 		ds >> x1 >> y1 >> w >> h;
5480 		p1 = QPointF(x1, y1);
5481 		p2 = QPointF(p1.x() + w, p1.y());
5482 		p3 = QPointF(p1.x() + w, p1.y() + h);
5483 		p4 = QPointF(p1.x(), p1.y() + h);
5484 	}
5485 	result.append(convertEMFPLogical2Pts(p1, currentDC.emfPlusUnit));
5486 	result.append(convertEMFPLogical2Pts(p2, currentDC.emfPlusUnit));
5487 	result.append(convertEMFPLogical2Pts(p3, currentDC.emfPlusUnit));
5488 	result.append(convertEMFPLogical2Pts(p4, currentDC.emfPlusUnit));
5489 //	result.translate(-currentDC.originEMFP);
5490 	result.translate(currentDC.viewOrigin);
5491 	return result;
5492 }
5493 
getEMFPPoint(QDataStream & ds,bool size)5494 QPointF EmfPlug::getEMFPPoint(QDataStream &ds, bool size)
5495 {
5496 	QPointF p;
5497 	if (size)
5498 	{
5499 		qint16 x1, y1;
5500 		ds >> x1 >> y1;
5501 		p = QPointF(x1, y1);
5502 	}
5503 	else
5504 	{
5505 		float x1, y1;
5506 		ds >> x1 >> y1;
5507 		p = QPointF(x1, y1);
5508 	}
5509 	p = convertEMFPLogical2Pts(p, currentDC.emfPlusUnit);
5510 //	p -= currentDC.originEMFP;
5511 	p += currentDC.viewOrigin;
5512 	return p;
5513 }
5514 
getEMFPDistance(QDataStream & ds,bool size)5515 double EmfPlug::getEMFPDistance(QDataStream &ds, bool size)
5516 {
5517 	double p;
5518 	if (size)
5519 	{
5520 		qint16 x1;
5521 		ds >> x1;
5522 		p = x1;
5523 	}
5524 	else
5525 	{
5526 		float x1;
5527 		ds >> x1;
5528 		p = x1;
5529 	}
5530 	p = convertEMFPLogical2Pts(p, currentDC.emfPlusUnit);
5531 	return p;
5532 }
5533 
convertEMFPLogical2Pts(QPointF in,quint16 unit)5534 QPointF EmfPlug::convertEMFPLogical2Pts(QPointF in, quint16 unit)
5535 {
5536 	QPointF out = currentDC.m_WorldMapEMFP.map(in);
5537 	switch (unit)
5538 	{
5539 		case U_UT_World:
5540 		case U_UT_Display:
5541 			break;
5542 		case U_UT_Pixel:
5543 			if (emfPlusDual && emfMixed)
5544 			{
5545 				out.setX(out.x() / dpiX * 72.0);
5546 				out.setY(out.y() / dpiY * 72.0);
5547 			}
5548 			else
5549 			{
5550 				out.setX(out.x() / static_cast<double>(EmfPdpiX) * 72.0);
5551 				out.setY(out.y() / static_cast<double>(EmfPdpiY) * 72.0);
5552 			}
5553 			break;
5554 		case U_UT_Point:
5555 			break;
5556 		case U_UT_Inch:
5557 			out.setX(out.x() * 72.0);
5558 			out.setY(out.y() * 72.0);
5559 			break;
5560 		case U_UT_Document:
5561 			out.setX(out.x() / 300.0 * 72.0);
5562 			out.setY(out.y() / 300.0 * 72.0);
5563 			break;
5564 		case U_UT_Millimeter:
5565 			out.setX(out.x() / 10.0 / 2.54 * 72.0);
5566 			out.setY(out.y() / 10.0 / 2.54 * 72.0);
5567 			break;
5568 		default:
5569 			break;
5570 	}
5571 	return out;
5572 }
5573 
convertEMFPLogical2Pts(double in,quint16 unit)5574 double EmfPlug::convertEMFPLogical2Pts(double in, quint16 unit)
5575 {
5576 	QLineF dist = QLineF(0, 0, in, 0);
5577 	dist = currentDC.m_WorldMapEMFP.map(dist);
5578 	double out = dist.length();
5579 	switch (unit)
5580 	{
5581 		case U_UT_World:
5582 		case U_UT_Display:
5583 			break;
5584 		case U_UT_Pixel:
5585 			if (emfPlusDual && emfMixed)
5586 				out = out / dpiX * 72.0;
5587 			else
5588 				out = out / static_cast<double>(EmfPdpiX) * 72.0;
5589 			break;
5590 		case U_UT_Point:
5591 			break;
5592 		case U_UT_Inch:
5593 			out = out * 72.0;
5594 			break;
5595 		case U_UT_Document:
5596 			out = out / 300 * 72.0;
5597 			break;
5598 		case U_UT_Millimeter:
5599 			out = out / 10.0 / 2.54 * 72.0;
5600 			break;
5601 		default:
5602 			break;
5603 	}
5604 	return out;
5605 }
5606 
gdip_open_curve_tangents(QPolygonF & points,double tension)5607 QPolygonF EmfPlug::gdip_open_curve_tangents(QPolygonF &points, double tension)
5608 {
5609 	double coefficient = tension / 3.0;
5610 	int i;
5611 	int count = points.count();
5612 	QPolygonF tangents;
5613 	tangents.fill(QPointF(0,0), count);
5614 	if (count <= 2)
5615 		return tangents;
5616 	for (i = 0; i < count; i++)
5617 	{
5618 		int r = i + 1;
5619 		int s = i - 1;
5620 		if (r >= count)
5621 			r = count - 1;
5622 		if (s < 0)
5623 			s = 0;
5624 		tangents[i] += QPointF(coefficient * (points[r].x() - points[s].x()), coefficient * (points[r].y() - points[s].y()));
5625 	}
5626 	return tangents;
5627 }
5628 
gdip_closed_curve_tangents(QPolygonF & points,double tension)5629 QPolygonF EmfPlug::gdip_closed_curve_tangents(QPolygonF &points, double tension)
5630 {
5631 	double coefficient = tension / 3.0;
5632 	int i;
5633 	int count = points.count();
5634 	QPolygonF tangents;
5635 	tangents.fill(QPointF(0,0), count);
5636 	if (count <= 2)
5637 		return tangents;
5638 	for (i = 0; i < count; i++)
5639 	{
5640 		int r = i + 1;
5641 		int s = i - 1;
5642 		if (r >= count)
5643 			r -= count;
5644 		if (s < 0)
5645 			s += count;
5646 		tangents[i] += QPointF(coefficient * (points[r].x() - points[s].x()), coefficient * (points[r].y() - points[s].y()));
5647 	}
5648 	return tangents;
5649 }
5650 
append_curve(QPainterPath & path,QPolygonF & points,QPolygonF & tangents,bool type)5651 void EmfPlug::append_curve(QPainterPath &path, QPolygonF &points, QPolygonF &tangents, bool type)
5652 {
5653 	int i;
5654 	path.moveTo(points[0]);
5655 	for (i = 0; i < points.count() - 1; i++)
5656 	{
5657 		int j = i + 1;
5658 		path.cubicTo(points[i] + tangents[i], points[j] - tangents[j], points[j]);
5659 	}
5660 	if (type)
5661 	{
5662 		/* complete (close) the curve using the first point */
5663 		path.cubicTo(points[i] + tangents[i], points[0] - tangents[0], points[0]);
5664 		path.closeSubpath();
5665 	}
5666 }
5667 
GdipAddPathCurve(QPainterPath & path,QPolygonF & points,float tension)5668 void EmfPlug::GdipAddPathCurve(QPainterPath &path, QPolygonF &points, float tension)
5669 {
5670 	QPolygonF tangents = gdip_open_curve_tangents(points, tension);
5671 	append_curve(path, points, tangents, false);
5672 }
5673 
GdipAddPathClosedCurve(QPainterPath & path,QPolygonF & points,float tension)5674 void EmfPlug::GdipAddPathClosedCurve(QPainterPath &path, QPolygonF &points, float tension)
5675 {
5676 	QPolygonF tangents = gdip_closed_curve_tangents(points, tension);
5677 	append_curve(path, points, tangents, true);
5678 }
5679 
handleEMFPDrawImageData(QPointF p1,QPointF p2,QPointF p3,quint8 flagsH)5680 void EmfPlug::handleEMFPDrawImageData(QPointF p1, QPointF p2, QPointF p3, quint8 flagsH)
5681 {
5682 	if (emfStyleMapEMP[flagsH].MetaFile)
5683 	{
5684 		QString ext = "emf";
5685 		if (emfStyleMapEMP[flagsH].imageType < U_MDT_Emf)
5686 			ext = "wmf";
5687 		PageItem* ite = getVectorFileFromData(m_Doc, emfStyleMapEMP[flagsH].imageData, ext, baseX + p1.x(), baseY + p1.y(), QLineF(p1, p2).length(), QLineF(p1, p3).length());
5688 		if (ite != nullptr)
5689 		{
5690 			if (QLineF(p1, p2).angle() != 0)
5691 				ite->setRotation(-QLineF(p1, p2).angle(), true);
5692 			finishItem(ite, false);
5693 		}
5694 	}
5695 	else
5696 	{
5697 		QImage img = getImageDataFromStyle(flagsH);
5698 		if (!img.isNull())
5699 		{
5700 			QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_emf_XXXXXX.png");
5701 			tempFile->setAutoRemove(false);
5702 			if (tempFile->open())
5703 			{
5704 				QString fileName = getLongPathName(tempFile->fileName());
5705 				if (!fileName.isEmpty())
5706 				{
5707 					tempFile->close();
5708 					img.save(fileName, "PNG");
5709 					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);
5710 					PageItem* ite = m_Doc->Items->at(z);
5711 					finishItem(ite, false);
5712 					if (QLineF(p1, p2).angle() != 0)
5713 						ite->setRotation(-QLineF(p1, p2).angle(), true);
5714 					ite->isInlineImage = true;
5715 					ite->isTempFile = true;
5716 					if (SerializableObject_Valid)
5717 					{
5718 						ite->effectsInUse = m_Effects;
5719 						SerializableObject_Valid = false;
5720 						m_Effects.clear();
5721 					}
5722 					m_Doc->loadPict(fileName, ite);
5723 					ite->setImageScalingMode(false, false);
5724 					ite->updateClip();
5725 					if (currentDC.clipValid)
5726 					{
5727 						FPointArray cp = currentDC.clipPath.copy();
5728 						cp.translate(baseX, baseY);
5729 						cp.translate(-docX, -docY);
5730 						cp.translate(-ite->xPos(), -ite->yPos());
5731 						ite->PoLine = cp.copy();
5732 						FPoint wh = getMaxClipF(&ite->PoLine);
5733 						ite->setWidthHeight(wh.x(),wh.y());
5734 						ite->setTextFlowMode(PageItem::TextFlowDisabled);
5735 						m_Doc->adjustItemSize(ite);
5736 						ite->OldB2 = ite->width();
5737 						ite->OldH2 = ite->height();
5738 						ite->updateClip();
5739 					}
5740 				}
5741 			}
5742 			delete tempFile;
5743 		}
5744 	}
5745 }
5746 
getImageDataFromStyle(quint8 flagsH)5747 QImage EmfPlug::getImageDataFromStyle(quint8 flagsH)
5748 {
5749 	QImage img;
5750 	if (emfStyleMapEMP[flagsH].imageType == 1)
5751 		img.loadFromData(emfStyleMapEMP[flagsH].imageData);
5752 	else
5753 	{
5754 		int hWidth = qAbs(emfStyleMapEMP[flagsH].imageWidth);
5755 		int hHeight = qAbs(emfStyleMapEMP[flagsH].imageHeight);
5756 		QDataStream dsB(emfStyleMapEMP[flagsH].imageData);
5757 		dsB.setByteOrder(QDataStream::LittleEndian);
5758 		img = QImage(hWidth, hHeight, QImage::Format_ARGB32);
5759 		img.fill(0);
5760 		if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_32bppARGB)
5761 		{
5762 			for (qint32 yy = 0; yy < hHeight; yy++)
5763 			{
5764 				QRgb *dst = (QRgb*)img.scanLine(yy);
5765 				for (qint32 xx = 0; xx < hWidth; xx++)
5766 				{
5767 					quint8 r, g, b, a;
5768 					dsB >> b >> g >> r >> a;
5769 					*dst = qRgba(r, g, b, a);
5770 					dst++;
5771 				}
5772 			}
5773 		}
5774 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_32bppRGB)
5775 		{
5776 			for (qint32 yy = 0; yy < hHeight; yy++)
5777 			{
5778 				QRgb *dst = (QRgb*)img.scanLine(yy);
5779 				for (qint32 xx = 0; xx < hWidth; xx++)
5780 				{
5781 					quint8 r, g, b, a;
5782 					dsB >> b >> g >> r >> a;
5783 					*dst = qRgba(r, g, b, 255);
5784 					dst++;
5785 				}
5786 			}
5787 		}
5788 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_24bppRGB)
5789 		{
5790 			for (qint32 yy = 0; yy < hHeight; yy++)
5791 			{
5792 				QRgb *dst = (QRgb*)img.scanLine(yy);
5793 				for (qint32 xx = 0; xx < hWidth; xx++)
5794 				{
5795 					quint8 r, g, b;
5796 					dsB >> b >> g >> r;
5797 					*dst = qRgba(r, g, b, 255);
5798 					dst++;
5799 				}
5800 				aligntoQuadWord(dsB);
5801 			}
5802 		}
5803 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_16bppRGB555)
5804 		{
5805 			for (qint32 yy = 0; yy < hHeight; yy++)
5806 			{
5807 				QRgb *dst = (QRgb*)img.scanLine(yy);
5808 				for (qint32 xx = 0; xx < hWidth; xx++)
5809 				{
5810 					quint16 dt;
5811 					quint8 r, g, b;
5812 					dsB >> dt;
5813 					b = (dt & 0x1F) * 8;
5814 					g = ((dt >> 5) & 0x1F) * 8;
5815 					r = ((dt >> 10) & 0x1F) * 8;
5816 					*dst = qRgba(r, g, b, 255);
5817 					dst++;
5818 				}
5819 				aligntoQuadWord(dsB);
5820 			}
5821 		}
5822 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_16bppGrayScale)
5823 		{
5824 			for (qint32 yy = 0; yy < hHeight; yy++)
5825 			{
5826 				QRgb *dst = (QRgb*)img.scanLine(yy);
5827 				for (qint32 xx = 0; xx < hWidth; xx++)
5828 				{
5829 					quint16 r;
5830 					dsB >> r;
5831 					r = r >> 8;
5832 					*dst = qRgba(r, r, r, 255);
5833 					dst++;
5834 				}
5835 				aligntoQuadWord(dsB);
5836 			}
5837 		}
5838 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_8bppIndexed)
5839 		{
5840 			QVector<QRgb> colorTbl;
5841 			quint32 palFlags, colorsUsed;
5842 			dsB >> palFlags >> colorsUsed;
5843 			for (quint32 pa = 0; pa < colorsUsed; pa++)
5844 			{
5845 				quint32 brushID;
5846 				dsB >> brushID;
5847 				quint8 r = brushID & 0xFF;
5848 				quint8 g = (brushID >> 8) & 0xFF;
5849 				quint8 b = (brushID >> 16) & 0xFF;
5850 				quint8 a = (brushID >> 24) & 0xFF;
5851 				if (palFlags & 0x00000001)
5852 					colorTbl.append(qRgba(b, g, r, a));
5853 				else
5854 					colorTbl.append(qRgba(b, g, r, 255));
5855 			}
5856 			img = QImage(hWidth, hHeight, QImage::Format_Indexed8);
5857 			img.fill(0);
5858 			img.setColorTable(colorTbl);
5859 			for (qint32 yy = 0; yy < hHeight; yy++)
5860 			{
5861 				char *dst = (char*)img.scanLine(yy);
5862 				dsB.readRawData(dst, hWidth);
5863 				aligntoQuadWord(dsB);
5864 			}
5865 			img = img.convertToFormat(QImage::Format_ARGB32);
5866 		}
5867 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_4bppIndexed)
5868 		{
5869 			QVector<QRgb> colorTbl;
5870 			quint32 palFlags, colorsUsed;
5871 			dsB >> palFlags >> colorsUsed;
5872 			for (quint32 pa = 0; pa < colorsUsed; pa++)
5873 			{
5874 				quint32 brushID;
5875 				dsB >> brushID;
5876 				quint8 r = brushID & 0xFF;
5877 				quint8 g = (brushID >> 8) & 0xFF;
5878 				quint8 b = (brushID >> 16) & 0xFF;
5879 				quint8 a = (brushID >> 24) & 0xFF;
5880 				if (palFlags & 0x00000001)
5881 					colorTbl.append(qRgba(b, g, r, a));
5882 				else
5883 					colorTbl.append(qRgba(b, g, r, 255));
5884 			}
5885 			for (qint32 yy = 0; yy < hHeight; yy++)
5886 			{
5887 				QRgb *dst = (QRgb*)img.scanLine(yy);
5888 				for (qint32 xx = 0; xx < hWidth; xx += 2)
5889 				{
5890 					quint8 r, rh, rl;
5891 					dsB >> r;
5892 					rh = (r >> 4) & 0xF;
5893 					rl = r & 0xF;
5894 					if (rh < colorTbl.count())
5895 						*dst = colorTbl[rh];
5896 					dst++;
5897 					if (xx == hWidth - 1)
5898 						break;
5899 					if (rl < colorTbl.count())
5900 						*dst = colorTbl[rl];
5901 					dst++;
5902 				}
5903 				aligntoQuadWord(dsB);
5904 			}
5905 		}
5906 		else if (emfStyleMapEMP[flagsH].imagePixelFormat == U_PF_1bppIndexed)
5907 		{
5908 			QVector<QRgb> colorTbl;
5909 			quint32 palFlags, colorsUsed;
5910 			dsB >> palFlags >> colorsUsed;
5911 			for (quint32 pa = 0; pa < colorsUsed; pa++)
5912 			{
5913 				quint32 brushID;
5914 				dsB >> brushID;
5915 				quint8 r = brushID & 0xFF;
5916 				quint8 g = (brushID >> 8) & 0xFF;
5917 				quint8 b = (brushID >> 16) & 0xFF;
5918 				quint8 a = (brushID >> 24) & 0xFF;
5919 				if (palFlags & 0x00000001)
5920 					colorTbl.append(qRgba(b, g, r, a));
5921 				else
5922 					colorTbl.append(qRgba(b, g, r, 255));
5923 			}
5924 			img = QImage(hWidth, hHeight, QImage::Format_Mono);
5925 			img.fill(0);
5926 			img.setColorTable(colorTbl);
5927 			int bpl = img.bytesPerLine();
5928 			for (qint32 yy = 0; yy < hHeight; yy++)
5929 			{
5930 				char *dst = (char*)img.scanLine(yy);
5931 				dsB.readRawData(dst, bpl);
5932 			}
5933 			img = img.convertToFormat(QImage::Format_ARGB32);
5934 		}
5935 		else
5936 		{
5937 			qDebug() << QString("Format 0x%1").arg(emfStyleMapEMP[flagsH].imagePixelFormat, 8, 16, QChar('0'));
5938 			return img;
5939 		}
5940 	}
5941 	return img;
5942 }
5943