-
Notifications
You must be signed in to change notification settings - Fork 3
/
README
567 lines (449 loc) · 30.6 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
Overview:
libUEMF is a portable C99 implementation for reading/writing Enhanced Metafile (EMF),
Enhanced Metafile Format Plus (PMF), and Windows Metafile (WMF) files. libUEMF
avoids collisions with Microsoft defined functions and values, so portable programs
which use it and have a Windows version, do not require any conditional logic to
separate the native GDI support from the WMF/EMF/PMF support proviced by libUEMF. To
accomplish this libUEMF does not implement GDI calls. Instead, for each WMR/EMR/PMR
record type, and each object type incorporated into such a record, it provides
corresponding *_set, *_print, and *_swap functions. For PMF and WMF there are also
*_get functions, see below. For example, for the U_EMRBITBLT record there are
corresponding functions: U_EMRBITBLT_set, U_EMRBITBLT_print, and U_EMRBITBLT_swap. A
few additional functions are provided for assembling the EMF in memory, debugging, and
converting the EMF file to/from Little Endian representation. (EMF files' internal
data representation is always Little Endian.)
This code has been tested on 32 bit Ubuntu (LE), 32 bit Mingw, 64 bit CentOS, and 64
bit Solaris (BE).
libUEMF is released under the GPL 2 license, read the file 'COPYING' for more information
Version 0.2.8, released May 13, 2020.
To report bugs or provide feedback send email to David Mathog, [email protected].
--------------------------------------------------------------------------------------------
Sources:
EMF file Record structure information has been derived from Mingw, Wine, and libEMF
header files, and from Microsoft's EMF Information pdf, release date March 28,2012,
link from here:
http://msdn2.microsoft.com/en-us/library/cc230514.aspx
If the direct link fails the document may be found
by searching the web for: "[MS-EMF]: Enhanced Metafile Format".
WMF file Record structure information is from some of the same sources, as well as:
http://msdn2.microsoft.com/en-us/library/250370.aspx
If the direct link fails the document may be found
by searching the web for: "[MS-WMF]: Windows Metafile Format"
EMF+ file Record structure is from many helpful responses from Microsoft documentation support
and from:
http://msdn.microsoft.com/en-us/library/cc230724.aspx
If the direct link fails the document may be found
by searching the web for: "[MS-EMFPLUS]: Enhanced Metafile Format Plus Extensions"
Files:
README This file.
CMakeLists.txt Build instructions for cmake on linux. Not tested on OS X or
Windows.
COPYING GPL V2 license file.
DOXYFILE Doxygen configuration file, for generating documentation from the source files.
testbuild.sh Small bash script to build all programs. Modify as needed for target platform.
testit.sh Small bash script that generates all test files and compares
them with referencess supplied. This script should be edited
to match your test system before it is run!
uemf.c Contains the *_set functions needed to construct an EMF file.
Also contains auxilliary functions for debugging and constructing
EMF files in memory.
uemf.h Definitions and structures for EMF records and objects.
Prototypes for *_set and construction functions.
uemf_print.c Contains the *_print functions needed to print the contents of EMF records and objects.
uemf_print.h Prototypes for *_print functions.
uemf_endian.c Contains the *_swap functions needed to rearrange bytes between Big and Little Endian.
U_emf_endian() is the only function here that user could should call.
uemf_endian.h Prototype for U_emf_endian() and definitions for Endian type of the local machine.
uemf_safe.c Contains the *_safe functions for EMF records, which verify that all
offsets and counts stay within the declared size of a record. Also checks that
core record sizes are sane. U_emf_record_safe() is the only _safe function which
user code should call directly, and then ONLY after a previous call to
U_emf_record_sizeok(), which is in the endian file.
uemf_safe.h Prototype for U_emf_record_safe().
.
upmf.c Contains the *_set and *_get functions needed to construct or read an EMF+ file.
Also contains auxilliary functions for debugging and constructing
EMF+ files in memory.
upmf.h Definitions and structures for EMF+ records and objects.
Prototypes for *_set, *_get and construction functions.
upmf_print.c Contains the *_print functions needed to print the contents of EMF+ records and objects.
upmf_print.h Prototypes for *_print functions.
uwmf.c Contains the *_set and *_get functions needed to construct or read a WMF file.
Also contains auxilliary functions for debugging and constructing
WMF files in memory.
uwmf.h Definitions and structures for WMF records and objects.
Prototypes for *_set, *_get and construction functions.
uwmf_print.c Contains the *_print functions needed to print the contents of WMF records and objects.
uwmf_print.h Prototypes for *_print functions.
uwmf_endian.c Contains the *_swap functions needed to rearrange bytes between Big and Little Endian.
U_wmf_endian() is the only function here that user could should call.
uwmf_endian.h Prototype for U_wmf_endian() and definitions for Endian type of the local machine.
testbed_emf.c Program used for testing emf functions in libUEMF. Run it like: testbed_emf flags.
Run with no argument to see what the bit flag values are.
It creates a test file "test_libuemf.emf" which should be identical to
test_libuemf_ref.emf. (This file cannot be imported from EMF into PowerPoint
because it contains dotted lines. Use "testbed_emf 1" to generate a file without
any dotted lines. )
testbed_pmf.c Program used for testing EMF+ functions in libUEMF. Similar to testbed_emf.
testbed_wmf.c Program used for testing wmf functions in libUEMF. Similar to testbed_emf.
test_mapmodes_emf.c
Program used for testing emf functions in libUEMF. Generates one test file
in each MAPMODE, MM_TEXT through MM_ANISOTROPIC, optionally with offsets to the
bounds and with particular Viewport origin. (Bounds offset + Viewport Origin
sets the Window origin.)
test_mapmodes_wmf.c
Program used for testing wmf functions in libUEMF. Similar to test_mapmodes_emf.
reademf.c Utility that that reads an EMF file and emits its contents in text form.
Also processes EMF+ files.
Run it like: reademf target_file.emf
readwmf.c Utility that that reads an WMF file and emits its contents in text form.
Run it like: reademf target_file.wmf
cutemf.c Utility for removing specific records from an EMF file.
Run it like: cutemf '2,10,12...13' src_file.emf dst_file.emf
pmfdual2single.c Utility for reducing dual-mode EMF+ file to single mode. Removes all
nonessential EMF records.
Run it like: pmfdual2single dual_mode.emf single_mode.emf
test_libuemf_ref.emf
Example output from: testbed_emf 0
test_libuemf_p_ref.emf
Example output from: testbed_pmf 0
test_libuemf_ref30.emf
Example output from: testbed_emf 4
test_libuemf_ref.wmf
Example output from: testbed_wmf 0
test_libuemf_ref_emf.txt
Example output from: reademf test_libuemf_ref.emf
test_libuemf_ref_wmf.txt
Example output from: readwmf test_libuemf_ref.wmf
test_mm_<modes>_ref.emf
Example output from: test_mapmodes_emf -vX 2000 -vY 1000
emf-inout.cpp,example
emf-inout.h.example
emf-print.cpp.example
emf-print.h.example
Example code from Inkscape, demonstrates how to integrate libUEMF with another program.
--------------------------------------------------------------------------------------------
How to Build:
In Linux/Unix like environments build and install a shared library and the test and tool
programs:
cd <TOP_DIRECTORY>
#modify the destination in CMakeLists.txt if /usr/local is not acceptable
mkdir build
cd build
make
make install
cd ..
./testit.sh
rm -rf build
For simple development work use testbuild.sh to make debug versions without the shared
library.
(Sparc)[ Solaris 8 and 9 are Big Endian, and to work around some minor incompatibilities with more recent systems,
assuming gcc is installed in /opt/csw and PATH is set correctly to use it]
export CLIBS="-lm -L/opt/csw/lib -liconv"
export CFLAGS="-DSOL8 -DWORDS_BIGENDIAN -std=c99 -pedantic -Wall -g"
(win32) [This uses _wfopen() instead of fopen(), with filename translation from UTF-8 to
UTF-16LE. This will allow file opens to utilize unicode names. If WIN32 is omitted on Windows
file names must be all ASCII. This works in mingw.] Then compile with:
export CLIBS="-lm -liconv"
export CFLAGS="-DWIN32 -std=c99 -pedantic -Wall -g"
gcc $CFLAGS -o cutemf cutemf.c uemf.c uemf_endian.c uemf_utf.c $CLIBS
gcc $CFLAGS -o pmfdual2single pmfdual2single.c uemf.c uemf_endian.c uemf_utf.c upmf.c $CLIBS
gcc $CFLAGS -o reademf reademf.c uemf.c uemf_endian.c uemf_safe.c uemf_print.c uemf_utf.c upmf.c upmf_print.c $CLIBS
gcc $CFLAGS -o readwmf readwmf.c uemf.c uemf_endian.c uemf_safe.c uemf_print.c uemf_utf.c upmf.c upmf_print.c uwmf.c uwmf_endian.c uwmf_print.c $CLIBS
gcc $CFLAGS -o testbed_emf testbed_emf.c uemf.c uemf_endian.c uemf_safe.c uemf_print.c uemf_utf.c upmf.c upmf_print.c $CLIBS
gcc $CFLAGS -o testbed_pmf testbed_pmf.c uemf.c uemf_endian.c uemf_safe.c uemf_utf.c upmf.c $CLIBS
gcc $CFLAGS -o testbed_wmf testbed_wmf.c uemf.c uemf_endian.c uemf_safe.c uemf_print.c uemf_utf.c upmf.c upmf_print.c uwmf.c uwmf_endian.c $CLIBS
gcc $CFLAGS -o test_mapmodes_emf test_mapmodes_emf.c uemf.c uemf_endian.c uemf_safe.c uemf_print.c uemf_utf.c upmf.c upmf_print.c $CLIBS
Extra debugging on linux may be enabled in testbed for use under Valgrind. To build that way do instead:
gcc -std=c99 -pedantic -Wall -g -DU_VALGRIND -o testbed_emf testbed_emf.c uemf.c uemf_endian.c uemf_print.c uemf_utf.c -lm
and then compile as above for linux.
Dependencies:
libiconv (if not built into your compiler)
libpng (in the Inkscape examples)
--------------------------------------------------------------------------------------------
Testing
All modules must also compile without warning under the more restrictive:
ls -1 *.c \
| extract -fmt 'gcc -Werror=format-security -Wall -Wformat -Wformat-security -W -Wno-pointer-sign -O2 -c -o deleteme.o [1,]' \
| execinput
--------------------------------------------------------------------------------------------
Using libUEMF:
To write an EMF file the code first runs two initialization functions: emf_start() and htable_create().
Then a U_EMRHEADER record is created. This and all subsequent records are appended to the EMF file in
memory with emf_append(). Whichever other EMR records are desired are also added. The last EMR record
added must be the single instance of U_EMREOF. Then the code calls emf_finish(), emf_free(), and
htable_free(). Conversion of byte order on Big Endian machines to Little Endian is carried out
automatically in emf_finish(), if it is required.
To input an EMF file it is is opened and the data read into a buffer in memory with emf_readdata(). On a
Big Endian machine this will also swap machine dependent byte orders as needed. At that point end user code
generally has to do something with the data in each record. The simplest case is to just print it, as shown
in reademf.c. More typically it must map the operations into its own graphics model, as shown in the
emf32*.*.example files from Inkscape. Basically the processing program needs to enter a loop, processing
one record at a time, pulling the record size and type from the first two uint32_t values present in each
record. It then enters a switch statement with one case for each EMR record type. Each case: statement
will generally define a pointer to that type of data object. Accessing the data from that pointer is
illustrated in the code for the corresponding *_print function.
While libUEMF implements _print and _swap functions for all supported EMR records, end user code would
never call any of these directly. Instead it should either pass a single EMR record
to U_emf_onerec_print() (see reademf.c) or the entire completed EMF file in memory buffer to U_emf_endian()
(see testbed.c).
WMF support is similar, except the functions are wmf_start(), wmf_readdata(), and so forth. It is a good
idea to separate end user WMF and EMF generating code into different modules, in order to avoid accidentally
writing EMR records to a WMF file and vice versa. WHile EMF objects are aligned in memory and so may be
accessed using the supplied structs, the ones for WMF files are not usually aligned and so must be accessed
using the supplied *_get functions. (The difference may not be evident on an x86 platform, but on RISC directly
trying to access objects in memory will result in access violations.)
Things to be aware of in EMF files:
The usual idea when employing a graphics file type like EMF is to copy a description of the objects in a
drawing from one program to another. Many of the record types in an EMF file can be thought of as objects,
they are lines or shapes or bitmaps or text. However, Microsoft's GDI implements binary and ternary raster
operations (see the descriptions in uemf.h) and most of these operations are not object like, instead they
combine things on the drawing surface. (There is in each case a copy operation which is object like.)
Consequently, EMF files which use these other raster operations are not particularly easy to import as
graphic objects. For instance, when PowerPoint rotates an image and saves it in an EMF the result is not
a single rotated image object. Instead there is an image containing the rotated image, which is followed by
masking operations to make the regions outside of the image transparent. There appears to be no standard
for when and where these subsequent operations will be applied. That is, there is no equivalent of
"begin path" and "end path" to delineate the start and end of such a compound operation. So a program
reading such a file has no easy way of figuring out which previous object is being modified by a subsequent
raster operation. The testbed program provided in this package generates a region which applies all
binary raster operations in vertical slices to two images. The expected result appears in Windows "Preview",
but if that region is imported into PowerPoint and converted to objects within that program the result looks
nothing like what Preview shows.
Support for U_EMREXTTEXTOUTW is much more common than for U_EMRSMALLTEXT. The latter is easier to use,
since it does not require a Dx array for each text string, but the objects will not import into PowerPoint,
for instance.
There are two types of dotted/dashed lines. The first uses a set of predefined flags to set the pattern
and the latter is end user user defined. Both are restricted to lines of width 1. These built in types are
problematic as key applications cannot handle them properly. PowerPoint cannot convert either type to its
internal object format. The first form loses the pattern and comes through as solid lines. The second type
is toxic - even a single dotted line of the second type will prevent the entire EMF from being converted.
The safest choice is to avoid these patterned line styles entirely. Convert all dots and dashes to separate
line draws before writing those into the EMF file. libUEMF has no problem reading these records, so code
should accept them for input.
As with most graphics file formats there is no single object representation of a complex text string (varying
font size, super/sub script, bold, italic,.etc.). Such text must be decomposed into multiple text strings,
each with its own formatting. It is unlikely that a subsequent program reading these records from the EMF
will be able to reassemble them back into a single complex text string.
If a font used in an EMF file is not present on both the sending and receiving systems text will not look the
same on both. Font substitution is usually silent in most programs, so it may not be evident why the text looks
a little odd. However, if text is simple, that is, consists of just one line of text without size, color,
or other changes, then it will look approximately correct after font substitution.
Things to be aware of in WMF files:
WMF graphics are quite limited when compared to EMF graphics. When reading a WMF file it is essential that
end user code always create a specified object, even if that object is just a placeholder with no real
function. If any "create" operation presented by the WMF file is not handled then the object indices used
further along in the WMF file will be off, with very bad results! WMF "regions" are not supported by libUEMF,
however, if an operation creates regions, this type of placeholder must still be created.
In theory WMF supports mapmodes other than Anisotropic. However, since many programs do not handle
these other modes it is strongly suggested that any WMF files generated use Anisotropic. For this
reason there is no test_mapmodes_wmf program - windows XP preview did not show anything when WMF
files in the other modes were produced. With no positive control there was no way to verify that they
were valid.
Things to be aware of in EMF+ files:
EMF+ files are usually stored in files with an ".emf" file extension. In this package EMF+ programs,
functions, and definitions use PMF or PMR to distinguish them from the EMF and WMF material. ("EMF+"
is not an allowed variable or function name in C.) Dual mode EMF+ files contain both EMF and
EMF+ records. HOWEVER, those generated by PowerPoint are defective in that they drop all text
information from the drawing in the EMF+ representation. There is no simple way to line up the
EMF and EMF+ records in their representations to determine which ones correspond to which drawing
object. So it is generally not possible to see which elements are represented in both
representations, or which are missing in one representation. The example file generated by this library
has only EMF+ records plus the few EMF records needed to wrap them.
Text in EMF+ is placed not from the baseline, as in EMF, but from the upper left corner of the Em square.
Use the utility function U_PMR_drawstring() to draw text onto a baseline. Font
substitutions result in badly placed text because even fonts that look similar on the screen may have
different font metrics. Specifically, font substitutions look worse in EMF+ files than they do
in EMF files. There is no way to embed fonts, or their font information in the EMF+ file.
Consequently the text representation within an EMF+ file is not very portable between systems - it will
only render correctly if the second system has all of the fonts used in the document. The testbed_pmf.c
program contains some metrics for common fonts which may be used with U_PMR_drawstring()
to accurately place text.
--------------------------------------------------------------------------------------------
History
(Note, version numbers in files represent the libUEMF release where it was last modified, so not
all files will show the same version numbers in each release.)
0.2.8 2020-05-13
Fixed warnings from newer compilers.
Fixed truncation of one string in testbed outputs files,
from 32 to 31 bytes (seen on CentOS 8 with gcc 8.3.1
but not CentOS 7 with gcc 4.8.5)
0.2.7 2019-10-10
Added CMakeLists.txt for linux.
Added cmake instructions in README.
Fixed typo in README build instructions.
Error checking added to testit.sh.
Increased max records in cutemf from 10K to 10M.
0.2.6 2019-03-21
Fixed typo in upmf.c discovered by David Binderman.
0.2.5 2017-01-03
Fixed a misplaced paren in uemf.h (thanks to Tavmjong Bah for noticing it)
Added more U_SIZE_* definitions in uemf.h for "cores" of record types with final
variable length arrays, such as U_SIZE_EMRNAMEDESCAPE
Removed redundant U_SIZE_BITMAPINFOHEADER definition from uwmf.h
0.2.4 2016-01-26
Record EXTSELECTCLIPRGN is supposed to be valid when the RgnDataSize is 0 if the RegionMode
is "COPY". Modified safe and print routines so that they would handle this situation.
U_PMR_DrawDriverstring seen for the first time and it crashed reademf. Reason, there was a spurious
"Tension" value in the structure, which offset values in the record.
0.2.3 2015-05-28
Fixed an assortment of warnings and a couple of bugs flagged by clang static analysis.
0.2.2 2015-04-28
Added lu_crc32 sums to record information in print statements. Affects only reademf and readwmf.
The point of this exercise is to enable the detection of differences in binary fields
which are not expanded by the print functions. This (re)uses code from Alexander Peslyak.
lu_ in name because crc32 conflicts with other libraries, like png.
Minor changes to some wmf function parameter types.
Minor changes to upmf.c so that it compiles cleanly with clang.
Restrict IS_MEM_UNSAFE 2nd parameter to be int or larger and test for negative values.
Updated the examples from Inkscape.
0.2.1 2015-04-23
Bug in safety check on EMREXTCREATEFONTINDIRECTW because it had alternative "standard" record sizes.
Changed warnings on unimplemented EMF record types encounterd in swap or safe from stdout to stderr.
Added memory checking for WMF polyline and polygon records, for the variable part and some others.
Note: U_WMRCREATEREGION_get does not check that the variable part stays within the record. Current
implementation seems to be broken since it does not show up in XP preview.
0.2.0 2015-03-20
Added UEMF _safe functions to better handle corrupt records, where variable sizes fields might
have been specified to read past the end of memory. These are records with offsets, arrays
with counts, and bitmaps. Also any record which specifies a size smaller than the minimum
for that record type.
Added similar code for EMF+.
These changed the API so the minor version number was bumped by 1.
0.1.18 2015-01-15
Pierre-Francois Carpentier sent some EMF examples which used U_EMR_EXTSELECTCLIPRGN, which had
not previously been encountered and showed that the handling of regions was broken.
Added tests for U_EMRFILLRGN, U_EMRFRAMERGN, U_EMRFRAMERGN, U_EMREXTSELECTCLIPRGN to testbed_emf.
0.1.18 2014-04-28
Fixed typo in testbed_wmf.c. "include,include" in one place should have been
"exclude,exclude".
0.1.17 2014-04-25
Added text clipping tests to testbed_emf.c, testbed_wmf.c, and testbed_pmf.c.
Added option to omit clipping tests in testbed's.
0.1.16 2014-04-14
Fixed bug in U_WMRRESTOREDC_set.
Added clipping tests to testbed_wmf.c.
0.1.15 2014-04-04
Changed record flags for U_EMRSELECTCLIPPATH record, it consumes a path but does not ALTER (which
forced a premature draw.)
Added U_EMROFFSETCLIPRGN test to testbed_emf.c.
Changed location on dist drawing where clipping appears.
0.1.14 2014-03-27
Fixed bug, in U_PMF_RECTN_set() in upmf.c. Never tested.
Fixed a few potential bugs in upmf.c if a null pointer was passed for
certain function arguments. (Previously unhandled cases.)
Fixed bug, operations setting variables that are never read along those
execution paths: upmf_print.c, uemf.c, uwmf.c, uemf_endian.cm upmf.c.
Fixed potential (but very unlikely) memory leaks in upmf.c and uemf_utf.c.
Added test of U_PMF_RECTN_set to testbed_pmf.c.
Changed U_wmr_names() and U_wmr_escnames() to const char* (from char*).
Changed method for suppressing unused parameter warnings.
0.1.13 2014-03-21
Fixed bug, cutemf was messing up the object count (pens, brushes, etc.).
Added cutemf can now take ranges of lines.
Added testbed_emf generates clipping records for rect and path (but not region).
0.1.12 2014-02-14
Documentation change, U_WMRCREATEPATTERNBRUSH is obsolete.
Changed wmf_finish() so that it accurately reflects the largest number of objects used,
previously it showed the number of appends, which was much larger.
0.1.11 2014-01-29
Fixed bug in uwmf.c (wrong minimum record size on U_WMRTEXTOUT)
Fixed bug in uwmf.c (U_WMRCREATEPATTERNBRUSH not right)
Fixed bug in uwmf_print.c (U_WMRTEXTOUT_print, x,y were reversed)
Added error handling to uemf_utf.c for cases where src is a null pointer.
Added a test of createpatternbrush to testlib_wmf
0.1.10 2014-01-14
Slight changes in documentation for uemf.h.
Fixed typo in uemf_endian.c.
Fixed a tiny bug in uemf.c (if memory allocation failed a struct would have
been deleted before the struct itself.
0.1.9 2013-12-02
Added U_PMF_DASHEDLINEDATA_set3 (dot/dash pattern from bits in a uint32_t).
Finally was able to make linear gradient gradientfill records work. Updated
testbed_emf.c to include that.
0.1.8 2013-11-28
Fixed a bug in U_PMF_REGIONNODEPATH_print(), returned size was 4 too small.
Changed formatting of U_PMF_REGIONNODECHILDNODES_print() output to improve readability
of nested region structures in reademf.
0.1.7 2013-11-20
Added EMF+ support.
Converted U_RGA and similar from defines to functions, because the method being used
in the define (from C99) was not exactly compatible with C++ compilation.
Fixed error in test_mapmodes_emf.c where truncation float to integer was used where round
have been, resulting in an off by 1 error on some platforms.
Eliminated PU_W* pointers.
Cleaned up Doxygen comments.
0.1.6. 2013-04-18
Added tests which vary background mode, background color, and text color.
Slight modification to testit.sh.
Updated example files.
0.1.5. 2013-02-13
Added missing parameter for WMF RESTOREDC_set/get.
Replaced all sizeof() in uwmf.c that referred to UWMF structures with their
U_SIZE_* equivalents.
Added DIB related WMF _get functions. (Which were missing). These are U_BITMAPCOREHEADER_get,
U_BITMAPINFOHEADER_get, wget_dib_params
Added const where appropriate to wmf _get functions.
Added comprehensive cap,join,miter tests to testbeds.
Fixed bug in gradient4_swap().
Fixed bug in emr_arc_points_common(), used vector where unit vectors were
needed, sometimes flipped direction for arcs/chords.
Fixed bug in U_WMFTEXTOUT_get().
Changed all dst->Dst and src->Src as call variables in WMF code.
Denigrated htable_*() for emf, these become emf_htable_*(), to match naming convention
used for wmf_table_*().
0.1.4 2013-02-04
Added code to handle DIB formats that use clrUsed=0 to mean "maximum number of color entries",
this showed up in several places, including uemf.c and uemf_print.c.
Added some labels to test drawings, slightly rearranged image section, added
PNG and JPG image tests and clrUsed=0 images.
Modified uemf_endian.c to suppress some compiler warnings.
Changed get_DIB_params to return the Compression enumeration.
Fixed a typo in uwmf_print.c.
0.1.3 2013-01-29 Add modes to EMF test programs that changes worldtransform, so
that the resulting test files will exercise rotation transforms.
Added flags indication for testbed programs.
Added test for ROUNDRECT records. Swapped argument orders for those _get/_set operations.
0.1.2 2013-01-25 Fixed bug revealed by newer gcc on Solaris, assignment of aligned 32 bit to unaligned
16 bit segfaulted.
0.1.1 2013-01-24 Fixed a few compiler warnings under g++, mostly having to do
with signed unsigned comparisons. Eliminated
an unused variable from wmf_finish and two stray lines from U_WMRHEADER_set.
Cleaned up doxygen comments.
0.1.0 2013-01-09 Added WMF functions.
Simplified print functions. Changed output format of reademf slightly,
from U_EMRXXX to U_EMR_XXX - easier to read the new way.
0.0.11 2012-12-04 Moved UTF and related functions out of uemf.c uemf.h and into uemf_utf.c uemf_utf.h.
0.0.10 2012-11-28 Discovered that not enough space was being allocated for some UTF conversions. To be
safe need 4 bytes per glyph + 1 for UTF-8.
0.0.9 2012-09-26 Some "uninitialized variable warnings" for certain versions of
gcc. These were, as far as I could tell, all spurious, but to quiet them
the variables in question were all initialized to 0.
Fixed header related print/swap functions - depending on what type of header there
could be an access violation.
Fixed U_Utf16leToUtf8, could leak memory if the conversion failed.
Fixed sections which were not testing for all types of EMF headers.
Added RGBA_to_RGBA() so that extractions of subsets of bitmaps (offset, different size)
can be handled.
Added cutemf. Utility to remove records from an EMF file.
Added test_mapmodes. Program to generate test files in each MAPMODE.
Added test_mm_(mode)_ref.emf files. These are reference for:
test_mapmodes -vX 2000 -vY 1000
0.0.8 2012-09-10 Fixed bug in htable_insert, failed to celear newly added table
slots. Fixed test for EMR_GRADIENTFILL triangle mode (rectangle still produces toxic EMF files.)
Fixed bug in gradientfill_swap on Solaris.
0.0.7 2012-08-30 Added/fixed tests for hatched, DIB, and mono strokes.
Corrected error in U_EMREXTCREATEPEN_set.
0.0.6 2012-08-21 Added/fixed tests for hatched, DIB, and mono fills.
0.0.5 2012-08-08 Minor changes to uemf.c to suppress compiler warnings. Fixed
one bug in SET_CB_FROM_PXBMI macro (which was not triggered in testbed
because all images were the same size).
0.0.4 2012-07-25 More tests in testbed.c. Found and fixed bugs in
U_POLYPOLYLINE and U_POLYPOLYGON related code.
0.0.3 2012-07-24 Warnings related to printing size_t on 64 bit Linux. Correct
fix is to use "zd", but gcc -std=c99 does not support that on Solaris 9,
the only available big endian system. So use cast or the size_t to (int)
and stick with %d format specifier. This should be OK as the sizes involved
should not be all that large.
Bug in core9 affecting U_EMRARC_swap(), and related, on Big Endian.
0.0.2 2012-07-12 first release