Name Date Size

.. 2016-01-27 09:01:29 456

CMakeLists.txt 2015-06-08 09:01:23 365

makefile.in 2013-08-31 18:05:13 273

Makefile_insert 2015-04-27 20:49:22 673

README 2015-04-27 20:49:22 32.2 KiB

symbol_convert.c 2014-03-26 21:46:17 42.2 KiB

symbol_convert.h 2013-08-31 18:05:13 1.6 KiB

uemf.c 2016-01-27 02:05:21 212 KiB

uemf.h 2016-01-27 09:01:29 187.7 KiB

uemf_endian.c 2015-04-27 20:49:22 91.6 KiB

uemf_endian.h 2015-04-27 20:49:22 1.7 KiB

uemf_print.c 2016-01-27 02:05:21 102.8 KiB

uemf_print.h 2015-05-22 01:06:06 7.5 KiB

uemf_safe.c 2016-01-27 02:05:21 47.9 KiB

uemf_safe.h 2015-04-27 09:30:27 650

uemf_utf.c 2014-03-26 21:36:31 20.4 KiB

uemf_utf.h 2014-01-18 00:24:11 1.8 KiB

upmf.c 2016-01-27 02:05:21 357.6 KiB

upmf.h 2016-01-27 02:05:21 186.8 KiB

upmf_print.c 2016-01-27 02:05:21 126.4 KiB

upmf_print.h 2015-05-22 01:06:06 9.5 KiB

uwmf.c 2015-05-22 01:06:06 239 KiB

uwmf.h 2016-01-27 09:01:29 146.1 KiB

uwmf_endian.c 2015-05-28 22:42:38 64.2 KiB

uwmf_endian.h 2015-05-22 01:06:06 639

uwmf_print.c 2015-05-22 01:06:06 70.5 KiB

uwmf_print.h 2015-04-27 20:49:22 1.4 KiB

README

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 Mageia, and 64
bit Solaris (BE).
libUEMF is released under the GPL 2 license, read the file 'COPYING' for more information
Version 0.2.1, released April 23, 2015.
To report bugs or provide feedback send email to David Mathog, mathog@caltech.edu.
--------------------------------------------------------------------------------------------
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.
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 demonstrate how to integrate libUEMF with another program.
--------------------------------------------------------------------------------------------
How to Build:
In Linux/Unix like environments (omit -g flag for production versions):
Build and install a shared library (example, details may vary) and then build and link
the example programs to the shared library:
gcc -std=c99 -pedantic -Wall -fPIC -g -c uemf.c
gcc -std=c99 -pedantic -Wall -fPIC -g -c uemf_print.c
gcc -std=c99 -pedantic -Wall -fPIC -g -c uemf_endian.c
gcc -std=c99 -pedantic -Wall -fPIC -g -c uemf_utf.c
gcc -std=c99 -pedantic -Wall -fPIC -g -c uwmf.c
gcc -std=c99 -pedantic -Wall -fPIC -g -c uwmf_print.c
gcc -std=c99 -pedantic -Wall -fPIC -g -c uwmf_endian.c
gcc -std=c99 -pedantic -Wall -fPIC -g -c upmf.c
gcc -std=c99 -pedantic -Wall -fPIC -g -c upmf_print.c
gcc -shared -Wl,-soname,libuemf.so.0 \
-o libuemf.so.0.0.3 uemf.o uemf_utf.o uemf_print.o uemf_endian.o uwmf.o uwmf_print.o uwmf_endian.o upmf.o upmf_print.o -lc
ln -s libuemf.so.0.0.3 libuemf.so.0
ln -s libuemf.so.0 libuemf.so
/bin/cp -f libuemf.so* /usr/local/lib
ldconfig
gcc -std=c99 -pedantic -Wall -g -o cutemf cutemf.c -luemf -lm
gcc -std=c99 -pedantic -Wall -g -o pmfdual2single pmfdual2single.c -luemf -lm
gcc -std=c99 -pedantic -Wall -g -o reademf reademf.c -luemf -lm
gcc -std=c99 -pedantic -Wall -g -o readwmf readwmf.c -luemf -lm
gcc -std=c99 -pedantic -Wall -g -o testbed_emf testbed_emf.c -luemf -lm
gcc -std=c99 -pedantic -Wall -g -o testbed_emf testbed_wmf.c -luemf -lm
gcc -std=c99 -pedantic -Wall -g -o test_mapmodes_emf test_mapmodes_emf.c -luemf -lm
For simple development work just build the example programs statically linked:
gcc -std=c99 -pedantic -Wall -g -o cutemf cutemf.c uemf.c uemf_endian.c uemf_utf.c -lm
gcc -std=c99 -pedantic -Wall -g -o pmfdual2single pmfdual2single.c uemf.c uemf_endian.c uemf_utf.c upmf.c -lm
gcc -std=c99 -pedantic -Wall -g -o reademf reademf.c uemf.c uemf_endian.c uemf_utf.c uemf_print.c upmf.c upmf_print.c -lm
gcc -std=c99 -pedantic -Wall -g -o readwmf readwmf.c uemf.c uemf_endian.c uemf_utf.c uemf_print.c uwmf.c uwmf_endian.c uwmf_print.c upmf.c upmf_print.c -lm
gcc -std=c99 -pedantic -Wall -g -o testbed_emf testbed_emf.c uemf.c uemf_endian.c uemf_utf.c -lm
gcc -std=c99 -pedantic -Wall -g -o testbed_pmf testbed_pmf.c uemf.c uemf_endian.c uemf_utf.c upmf.c upmf.h -lm
gcc -std=c99 -pedantic -Wall -g -o testbed_wmf testbed_wmf.c uemf.c uemf_endian.c uemf_utf.c uwmf.c uwmf_endian.c -lm
gcc -std=c99 -pedantic -Wall -g -o test_mapmodes_emf test_mapmodes_emf.c uemf.c uemf_endian.c uemf_utf.c -lm
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
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:
gcc -DSOL8 -DWORDS_BIGENDIAN -std=c99 -pedantic -Wall -g -o cutemf cutemf.c uemf.c uemf_endian.c uemf_utf.c -lm -L/opt/csw/lib -liconv
gcc -DSOL8 -DWORDS_BIGENDIAN -std=c99 -pedantic -Wall -g -o pmfdual2single pmfdual2single.c uemf.c uemf_endian.c uemf_utf.c upmf.c -lm -L/opt/csw/lib -liconv
gcc -DSOL8 -DWORDS_BIGENDIAN -std=c99 -pedantic -Wall -g -o reademf reademf.c uemf.c uemf_endian.c uemf_utf.c uemf_print.c upmf.c upmf_print.c -lm -L/opt/csw/lib -liconv
gcc -DSOL8 -DWORDS_BIGENDIAN -std=c99 -pedantic -Wall -g -o readwmf readwmf.c uemf.c uemf_endian.c uemf_utf.c uemf_print.c uwmf.c uwmf_endian.c uwmf_print.c upmf.c upmf_print.c -lm -L/opt/csw/lib -liconv
gcc -DSOL8 -DWORDS_BIGENDIAN -std=c99 -pedantic -Wall -g -o testbed_emf testbed_emf.c uemf.c uemf_endian.c uemf_utf.c -lm -L/opt/csw/lib -liconv
gcc -DSOL8 -DWORDS_BIGENDIAN -std=c99 -pedantic -Wall -g -o testbed_pmf testbed_pmf.c uemf.c uemf_endian.c uemf_utf.c upmf.c upmf.h -lm -L/opt/csw/lib -liconv
gcc -DSOL8 -DWORDS_BIGENDIAN -std=c99 -pedantic -Wall -g -o testbed_wmf testbed_wmf.c uemf.c uemf_endian.c uemf_utf.c uwmf.c uwmf_endian.c -lm -L/opt/csw/lib -liconv
gcc -DSOL8 -DWORDS_BIGENDIAN -std=c99 -pedantic -Wall -g -o test_mapmodes_emf test_mapmodes_emf.c uemf.c uemf_endian.c uemf_utf.c -lm -L/opt/csw/lib -liconv
(Note: WORDS_BIGENDIAN would also be produced by autconf's configure, if that was used.)
Define WIN32 when compiling for Windows. 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. To build on mingw use:
gcc -DWIN32 -std=c99 -pedantic -Wall -g -o cutemf cutemf.c uemf.c uemf_endian.c uemf_utf.c -lm -liconv
gcc -DWIN32 -std=c99 -pedantic -Wall -g -o pmfdual2single pmfdual2single.c uemf.c uemf_endian.c uemf_utf.c upmf.c -lm -liconv
gcc -DWIN32 -std=c99 -pedantic -Wall -g -o reademf reademf.c uemf.c uemf_endian.c uemf_utf.c uemf_print.c upmf.c upmf_print.c -lm -liconv
gcc -DWIN32 -std=c99 -pedantic -Wall -g -o readwmf readwmf.c uemf.c uemf_endian.c uemf_utf.c uemf_print.c uwmf.c uwmf_endian.c uwmf_print.c upmf.c upmf_print.c -lm -liconv
gcc -DWIN32 -std=c99 -pedantic -Wall -g -o testbed_emf testbed_emf.c uemf.c uemf_endian.c uemf_utf.c -lm -liconv
gcc -DWIN32 -std=c99 -pedantic -Wall -g -o testbed_pmf testbed_pmf.c uemf.c uemf_endian.c uemf_utf.c upmf.c upmf.h -lm -liconv
gcc -DWIN32 -std=c99 -pedantic -Wall -g -o testbed_wmf testbed_wmf.c uemf.c uemf_endian.c uemf_utf.c uwmf.c uwmf_endian.c -lm -liconv
gcc -DWIN32 -std=c99 -pedantic -Wall -g -o test_mapmodes_emf test_mapmodes_emf.c uemf.c uemf_endian.c uemf_utf.c -lm -liconv
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.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