emf-converter 4.3.1 → 4.3.3

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
@@ -196,7 +196,7 @@ A three-phase pipeline: **parse → replay → export**. The header parser reads
196
196
 
197
197
  Everything below is verified against output painted by Windows itself; `src/gdi-parity.fixture.test.ts` holds the per-fixture bounds.
198
198
 
199
- - **GDI shapes** (`gdi-raster.ts`, `gdi-raster-widen.ts`): 28.4 fixed-point geometry; GDI's fill rule (ALTERNATE/WINDING); one-pixel lines by GDI's diamond rule with its tie-breaks; GDI's own Bezier flattener, ellipse, rounded-rectangle, arc (GDI's trigonometry table and `SetArcDirection`), chord and pie construction; cosmetic dash styles (dash 18/6, dot 3/3, ...) and geometric dashes; wide pens widened from GDI's own pen polygons with every cap and join and the miter limit; rotated and skewed world transforms. Pixel-exact on the shape fixtures.
199
+ - **GDI shapes** (`gdi-raster.ts`, `gdi-raster-widen.ts`): 28.4 fixed-point geometry; GDI's fill rule (ALTERNATE/WINDING); one-pixel lines by GDI's diamond rule with its tie-breaks; GDI's own Bezier flattener, ellipse, rounded-rectangle, arc (GDI's trigonometry table and `SetArcDirection`), chord and pie construction; cosmetic dash styles (dash 18/6, dot 3/3, ...) and geometric dashes; wide pens widened from GDI's own pen polygons with every cap and join and the miter limit; rotated and skewed world transforms. Pixel-exact on the shape fixtures. A path bracket's GDI geometry has the points, point types, figure starts and direction that Windows' `GetPath` reports (checked against the Windows data in Wine's `gdi32` path tests).
200
200
  - **Raster operations**: all 256 ROP3 codes for `BitBlt`/`StretchBlt`/`StretchDIBits`/`PatBlt`, exact per bit against the destination, brush and source, with GDI's stretch modes, mirrored rectangles and rotated destinations (each device pixel mapped back to one source texel). Every `SetROP2` mode, including the bitwise AND/OR/XOR family, for shapes, paths and pattern-brush fills.
201
201
  - **Brushes**: hatch, monochrome and DIB pattern brushes anchored to the brush origin, with the background mode; GDI+ solid, hatch, texture (bilinear, WrapMode-aware, as GDI+ samples them), linear gradients (GDI+'s own interpolation table: preset colours, blend shapes, gamma correction, every WrapMode) and path gradients (true boundary-shaped falloff, every WrapMode).
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.
@@ -214,8 +214,8 @@ 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.
216
216
 
217
- - **Colour adjustment and image effects**: The `HALFTONE` stretch mode resamples with an area-averaging box filter. Integer enlargements match Windows exactly; reductions do not, because Windows' halftone engine uses a narrower kernel and its own colour mapping (1.05% of pixels differ on the fixture). `EMR_SETCOLORADJUSTMENT` is applied to the source of `HALFTONE` `StretchBlt` and `StretchDIBits` calls, as in GDI. Windows does not publish its adjustment formulas, so gamma, reference black/white, contrast, brightness, colourfulness, red-green tint, negative and log filter use documented approximations, and Windows' dithering of the adjusted colours is not reproduced (6.6% of pixels differ by more than 24 on the fixture). The illuminant is ignored. EMF+ image effects (`SerializableObject`) are applied to the image's pixels before it is drawn. Colour matrix and lookup table effects follow GDI+'s definitions; MS-EMFPLUS does not specify the algorithms of the others (blur, sharpen, brightness/contrast, levels, colour balance, colour curves, hue/saturation/lightness, tint, red-eye), so those use documented approximations and have not been checked against GDI+ output. An effect is applied to the draw's source rectangle only, and a blur with `expandEdge` grows it by the blur radius, as GDI+ does. When the source rectangle is not in pixels, the effect is applied to the whole image without that growth. 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**: nonuniform and skewed EMF+ pen transforms are drawn with the transformed (elliptical or sheared) nib, but unlike uniform ones they are not yet verified against Windows output, and a singular pen transform is ignored.
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. Colour matrix and lookup table effects follow GDI+'s definitions; MS-EMFPLUS does not specify the algorithms of the others (blur, sharpen, brightness/contrast, levels, colour balance, colour curves, hue/saturation/lightness, tint, red-eye), so those use documented approximations and have not been checked against GDI+ output. An effect is applied to the draw's source rectangle only, and a blur with `expandEdge` grows it by the blur radius, as GDI+ does. When the source rectangle is not in pixels, the effect is applied to the whole image without that growth. 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
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.
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.