summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/libuemf/README
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/libuemf/README')
-rw-r--r--src/3rdparty/libuemf/README579
1 files changed, 579 insertions, 0 deletions
diff --git a/src/3rdparty/libuemf/README b/src/3rdparty/libuemf/README
new file mode 100644
index 0000000..3e00958
--- /dev/null
+++ b/src/3rdparty/libuemf/README
@@ -0,0 +1,579 @@
+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.6, released Mar 21, 2019.
+
+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, demonstrates 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:
+ export CFLAGS="-std=c99 -pedantic -Wall -fPIC -g -c"
+ gcc $CFLAGS uemf.c
+ gcc $CFLAGS uemf_print.c
+ gcc $CFLAGS uemf_endian.c
+ gcc $CFLAGS uemf_safe.c
+ gcc $CFLAGS uemf_utf.c
+ gcc $CFLAGS uwmf.c
+ gcc $CFLAGS uwmf_print.c
+ gcc $CFLAGS uwmf_endian.c
+ gcc $CFLAGS upmf.c
+ gcc $CFLAGS upmf_print.c
+ unset CFLAGS
+ gcc -shared -Wl,-soname,libuemf.so.0 \
+ -o libuemf.so.0.0.3 uemf.o uemf_utf.o uemf_safe.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
+ export CFLAGS="-std=c99 -pedantic -Wall -g"
+ export CLIBS="-luemf -lm"
+ gcc $CFLAGS -o cutemf cutemf.c $CLIBS
+ gcc $CFLAGS -o pmfdual2single pmfdual2single.c $CLIBS
+ gcc $CFLAGS -o reademf reademf.c $CLIBS
+ gcc $CFLAGS -o readwmf readwmf.c $CLIBS
+ gcc $CFLAGS -o testbed_emf testbed_emf.c $CLIBS
+ gcc $CFLAGS -o testbed_emf testbed_wmf.c $CLIBS
+ gcc $CFLAGS -o test_mapmodes_emf test_mapmodes_emf.c $CLIBS
+
+ For simple development work just build the example programs statically. Set these
+ two variables up first:
+
+ (linux)
+ export CFLAGS="-std=c99 -pedantic -Wall -g"
+ export CLIBS=-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]
+ 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.]
+ export CLIBS="-lm -liconv"
+ export CFLAGS="-DWIN32 -std=c99 -pedantic -Wall -g"
+
+ Then compile with:
+
+ 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.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
+