emf-converter 4.3.5 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -202,7 +202,7 @@ Everything below is verified against output painted by Windows itself; `src/gdi-
202
202
  - **Clipping**: every GDI and GDI+ region combine mode exact for every clip (vector where possible, otherwise scan-converted to pixel regions, which is how GDI stores them), path clips with their fill mode, and region offsets.
203
203
  - **EMF+**: fills, pens and clips follow the recorded `SmoothingMode` with GDI+'s own fill rasteriser (8 x 4-sample antialiasing, blend arithmetic) and pen widener (joins, caps, dash caps, compound lines, inset alignment); `DrawImage` with every InterpolationMode/PixelOffsetMode kernel, ImageAttributes wrap modes, drawn in record order under the live clip; embedded metafiles replayed as vectors; continuation records reassembled; compressed textures and images decoded before replay.
204
204
  - **Text**: see [Exact text](#exact-text).
205
- - **WMF**: played as `PlayMetaFile` plays it (GM_COMPATIBLE whole-pixel rules, mapping modes, bitmaps, pattern brushes, clipping and regions, palettes, flood fills, text spacing and justification, right-to-left layout); an EMF embedded in `MFCOMMENT` escapes is played instead, as Windows does.
205
+ - **WMF**: fractional `PS_INSIDEFRAME` rectangles retain a small residual at some wider half-pixel widths. The mirrored line fixtures match Windows exactly. Metric map modes default to a 96 dpi reference device; `wmfReferenceDpi` accepts a scalar or `{ x, y }` to reproduce another device.
206
206
 
207
207
  ### Supported records
208
208
 
@@ -214,9 +214,9 @@ Everything below is verified against output painted by Windows itself; `src/gdi-
214
214
 
215
215
  Everything is measured against output painted by Windows itself; `src/gdi-parity.fixture.test.ts` holds the exact per-fixture bounds. Open work items are tracked in [docs/outstanding-work.md](docs/outstanding-work.md).
216
216
 
217
- - **Colour adjustment and image effects**: The `HALFTONE` stretch mode reproduces Windows' halftone engine for 32-bit output: an enlargement smooths isolated pixels and then takes the nearest source pixel, and a reduction averages each pixel's footprint and then sharpens. All seven plain `HALFTONE` fixtures (2x, 3x, 0.5x, 0.65x and 1.37x) match exactly. It is not verified for a stretch that enlarges one axis and reduces the other. `EMR_SETCOLORADJUSTMENT` is applied to the source of `HALFTONE` `StretchBlt` and `StretchDIBits` calls, as in GDI. Windows does not publish its adjustment formulas. The converter uses a model fitted to two Windows captures: contrast and brightness on CIE L*, colourfulness and red-green tint on u'v' chromaticity, with gamma as the source encoding, so a gamma on its own changes nothing. Windows also dithers the adjusted colours over 32 levels per channel, and that pattern is not reproduced. On the fixtures, 0% to 15.1% of pixels differ by more than 24. The log filter uses an unverified curve, and the illuminant is ignored. EMF+ image effects (`SerializableObject`) are applied to the image's pixels before it is drawn. MS-EMFPLUS does not specify the algorithms, so they were measured against the effected bitmaps GDI+ itself writes into its recordings. Colour matrix, lookup table, brightness/contrast, colour balance, levels and sharpen match GDI+ exactly; blur matches to within one level (GDI+ blurs along rows only, plus a vertical blur of the top row, and so does the converter); colour curves match exactly for exposure, density, midtone and black saturation and to within one level on up to 2.3% of pixels for contrast, highlight, shadow and white saturation, whose control points were measured at intensity ±50 and are scaled for other values; hue/saturation/lightness uses GDI+'s integer HSL, but its hue rounding is only partly reproduced, so lightness and saturation changes differ on under 1% of pixels and a hue rotation is more than two levels off on 0.3% to 32% of pixels (up to 11 levels); tint is within two levels (three on 0.07% of pixels); red-eye correction is an approximation, as GDI+'s pupil detection and textured repaint are not reproduced (up to 17% of pixels differ). GDI+ follows each effect draw with a plain draw of the bitmap it effected, so Windows' playback depends on the effect only where that bitmap is translucent; played back, the image effect fixtures match Windows to within one level, except one edge of a rotated blurred draw (0.22% of pixels). An effect is applied to the draw's source rectangle only, reading one more column and row, as GDI+ does; a blur with `expandEdge` blurs transparency in at the edges but, as in GDI+, draws nothing beyond the source rectangle. When the source rectangle is not in pixels, the effect is applied to the whole image. GDI+ records a colour curve effect under the lookup table's identifier and its own playback draws the image without the effect; the converter does the same. An effect is skipped when the image cannot be decoded to pixels: PNG and BMP always can be, while JPEG, GIF, TIFF and similar formats need a canvas backend (a browser or `@napi-rs/canvas`).
218
- - **Pen transforms**: EMF+ pen transforms (uniform, nonuniform and skewed) match GDI+ exactly on the 17 pen-transform fixtures, including dashes, which GDI+ lays out along the path in world space at the untransformed pen width. The fixtures include dashes only under a non-uniform scale. Dashes under a uniform scale follow the same rule but have not been checked. A pen transform that cannot be inverted is ignored. Of the anchor caps, only `ArrowAnchor` is drawn with its real shape. The others are drawn as their base cap.
219
- - **Text**: ANSI, multi-string and small-text records now render; the Windows text fixtures retain a few glyph-edge differences and a `PolyTextOut` C1 control-glyph difference (under 0.1% of pixels; bounds in `src/emf-text-records.fixture.test.ts`). ANSI decoding uses the host's `TextDecoder` for common Windows code pages; unsupported encodings (including Johab and OEM on standard runtimes) fall back to Windows-1252. Vertical `ETO_PDY` advances require the `fonts` engine. Without `fonts`, SVG text measurements use deterministic estimates, so precise justification requires supplying the matching fonts.
217
+ - **Colour adjustment and image effects**: all eleven EMF+ image effects are supported. Complete native tables cover every legal ColorCurve intensity. Deferred draws retain their effects. JPEG, GIF and TIFF have bundled decoders for environments without Canvas. HSL, tint, red-eye, blur, sharpen and GDI colour adjustment retain measured differences; see [the detailed limitations](docs/limitations.md) and the native fixture bounds.
218
+ - **Pen transforms**: EMF+ pen transforms (uniform, nonuniform and skewed) match GDI+ exactly on the 17 pen-transform fixtures, including dashes, which GDI+ lays out along the path in world space at the untransformed pen width. Native fixtures verify dashes under both uniform and non-uniform scales. GDI+ rejects singular pen transforms; the converter ignores such malformed transform data. Square, round, diamond and arrow anchor caps use their native shapes; the new centered-cap fixtures match every pixel with and without antialiasing.
219
+ - **Text**: ANSI, multi-string and small-text records now render; the Windows text fixtures retain a few glyph-edge differences and a `PolyTextOut` C1 control-glyph difference (under 0.1% of pixels; bounds in `src/emf-text-records.fixture.test.ts`). ANSI decoding uses the host's `TextDecoder` for common Windows code pages; Johab and OEM CP437 use bundled Windows mappings. Vertical `ETO_PDY` advances work with and without the `fonts` engine. Without `fonts`, SVG text measurements use deterministic estimates, so precise justification requires supplying the matching fonts.
220
220
  - **Wide pens and paths**: flat-capped GDI pens 7 px and wider can differ by a few pixels at round joins, and dashed wide Bezier curves follow `WidenPath` (which Windows' direct drawing does not quite match); at most 0.2% of pixels on the fixtures. `EMR_WIDENPATH` does not reproduce the extra inner join triangles GDI's own `WidenPath` emits (visible only when the widened outline is itself stroked). EMF+ 1-pixel antialiased lines can differ by one antialiasing sample at their ends, some closed widened outlines by one sample along an edge, and Inset or compound pens on closed figures are approximate.
221
221
  - **GM_COMPATIBLE recordings**: EMF files do not record the graphics mode, and Windows plays RoundRect, Arc, Chord, Pie and null-pen Ellipse records back differently from how a GM_COMPATIBLE application drew them on screen; the converter follows Windows' playback.
222
222
  - **Small EMF+ residuals**: rotated `HighQualityBicubic` `DrawImage` edge pixels (0.14%), one-level differences at exact half-level `Blend` knots, and a few pixels of a metafile nested in `DrawImage` under a scale.
@@ -0,0 +1,131 @@
1
+ Bundled image decoders and their dependencies. These notices apply to the bundled third-party code.
2
+
3
+ ===== jpeg-js =====
4
+
5
+ Copyright (c) 2014, Eugene Ware
6
+ All rights reserved.
7
+
8
+ Redistribution and use in source and binary forms, with or without
9
+ modification, are permitted provided that the following conditions are met:
10
+
11
+ 1. Redistributions of source code must retain the above copyright
12
+ notice, this list of conditions and the following disclaimer.
13
+ 2. Redistributions in binary form must reproduce the above copyright
14
+ notice, this list of conditions and the following disclaimer in the
15
+ documentation and/or other materials provided with the distribution.
16
+ 3. Neither the name of Eugene Ware nor the names of its contributors
17
+ may be used to endorse or promote products derived from this software
18
+ without specific prior written permission.
19
+
20
+ THIS SOFTWARE IS PROVIDED BY EUGENE WARE ''AS IS'' AND ANY
21
+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ DISCLAIMED. IN NO EVENT SHALL EUGENE WARE BE LIABLE FOR ANY
24
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+
32
+ ===== gifuct-js =====
33
+
34
+ The MIT License (MIT)
35
+
36
+ Copyright (c) 2015 Matt Way
37
+
38
+ Permission is hereby granted, free of charge, to any person obtaining a copy
39
+ of this software and associated documentation files (the "Software"), to deal
40
+ in the Software without restriction, including without limitation the rights
41
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
42
+ copies of the Software, and to permit persons to whom the Software is
43
+ furnished to do so, subject to the following conditions:
44
+
45
+ The above copyright notice and this permission notice shall be included in all
46
+ copies or substantial portions of the Software.
47
+
48
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
50
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
51
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
52
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
53
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
54
+ SOFTWARE.
55
+
56
+
57
+
58
+ ===== js-binary-schema-parser =====
59
+
60
+ The MIT License (MIT)
61
+
62
+ Copyright (c) 2015 Matt Way
63
+
64
+ Permission is hereby granted, free of charge, to any person obtaining a copy
65
+ of this software and associated documentation files (the "Software"), to deal
66
+ in the Software without restriction, including without limitation the rights
67
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
68
+ copies of the Software, and to permit persons to whom the Software is
69
+ furnished to do so, subject to the following conditions:
70
+
71
+ The above copyright notice and this permission notice shall be included in all
72
+ copies or substantial portions of the Software.
73
+
74
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
75
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
76
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
77
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
78
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
79
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
80
+ SOFTWARE.
81
+
82
+
83
+
84
+ ===== utif =====
85
+
86
+ MIT License
87
+
88
+ Copyright (c) 2017 Photopea
89
+
90
+ Permission is hereby granted, free of charge, to any person obtaining a copy
91
+ of this software and associated documentation files (the "Software"), to deal
92
+ in the Software without restriction, including without limitation the rights
93
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
94
+ copies of the Software, and to permit persons to whom the Software is
95
+ furnished to do so, subject to the following conditions:
96
+
97
+ The above copyright notice and this permission notice shall be included in all
98
+ copies or substantial portions of the Software.
99
+
100
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
101
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
102
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
103
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
104
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
105
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
106
+ SOFTWARE.
107
+
108
+
109
+ ===== pako =====
110
+
111
+ (The MIT License)
112
+
113
+ Copyright (C) 2014-2017 by Vitaly Puzrin and Andrei Tuputcyn
114
+
115
+ Permission is hereby granted, free of charge, to any person obtaining a copy
116
+ of this software and associated documentation files (the "Software"), to deal
117
+ in the Software without restriction, including without limitation the rights
118
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
119
+ copies of the Software, and to permit persons to whom the Software is
120
+ furnished to do so, subject to the following conditions:
121
+
122
+ The above copyright notice and this permission notice shall be included in
123
+ all copies or substantial portions of the Software.
124
+
125
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
126
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
127
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
128
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
129
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
130
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
131
+ THE SOFTWARE.
package/dist/index.d.mts CHANGED
@@ -108,6 +108,11 @@ declare function svgTreeToJsx(node: SvgNode, options?: SvgJsxOptions): string;
108
108
  * Configuration options for EMF/WMF conversion.
109
109
  */
110
110
  interface EmfConvertOptions {
111
+ /** WMF playback-device pixels per inch; defaults to 96 on each axis. */
112
+ wmfReferenceDpi?: number | {
113
+ x: number;
114
+ y: number;
115
+ };
111
116
  /** Maximum output width in pixels. */
112
117
  maxWidth?: number;
113
118
  /** Maximum output height in pixels. */
package/dist/index.d.ts CHANGED
@@ -108,6 +108,11 @@ declare function svgTreeToJsx(node: SvgNode, options?: SvgJsxOptions): string;
108
108
  * Configuration options for EMF/WMF conversion.
109
109
  */
110
110
  interface EmfConvertOptions {
111
+ /** WMF playback-device pixels per inch; defaults to 96 on each axis. */
112
+ wmfReferenceDpi?: number | {
113
+ x: number;
114
+ y: number;
115
+ };
111
116
  /** Maximum output width in pixels. */
112
117
  maxWidth?: number;
113
118
  /** Maximum output height in pixels. */