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