Skip to content

Outstanding work ​

Open items, grouped by area. Limitations describes current behaviour for users. This page lists what is still to be done and what data each item needs.

Windows reference images come from scripts/gdi-fixtures. The Windows fixtures workflow (.github/workflows/windows-fixtures.yml) runs those scripts on a GitHub-hosted Windows runner and pushes the output to a windows-fixtures/<run_id> branch. See scripts/gdi-fixtures/README.md.

Independent fractional RoundRect translation controls now cover 576 paths. Every native translation is exact; 228 replay paths match and all remaining coordinates differ by at most one FIX, with per-case bounds. Coordinate magnitude is ruled out as the cause; side-point and corner-end rounding remain open.

Current parity priorities (3 October 2026) ​

The full suite passes: 122 files, 4,092 tests. Passing the existing bounds does not mean pixel-exact playback. bun scripts/gdi-fixtures/report.ts uses available Windows fixture fonts, reports both zero-tolerance and >8-level RGB differences, includes overlap edges, and prints rendered/reference dimensions. On this machine, 391 of 611 comparisons are RGB-exact over their common device area, with no render failures; 390 of 611 also have complete RGB ink coverage (white margins ignored, alpha checked separately only where individual tests require it). No comparison omits reference ink through a smaller render extent, but 9 contain rendered ink beyond the captured reference. Expanded native playback now covers 92 formerly uncaptured extents and reproduces every original overlap pixel. The larger comparisons expose 6,618 additional differing pixels, chiefly text; 64 of these full-area controls are exact. The remaining 9 captures did not reproduce the original reference, and need independent capture investigation. This is a local baseline, not a claim of full-image or cross-environment parity: references are composited over white, alpha is not compared independently, dimensions can differ, and old font captures have incomplete provenance.

Work in this order, using native captures and tighter regression bounds for every confirmed fix:

PriorityGapEvidence and next step
1End-to-end reference validity and coverageResolve the nine remaining uncaptured extents, then the text residuals exposed by the 92 validated expanded native captures. emfrec-ca-control-log-ramp retains a 15.61% >8-level residual despite exact channel-curve tests: differences are isolated to 16 rows around colour-band transitions. The 144 halftone-transitions captures expose replicated and filtered enlargement paths; their selection rule remains unresolved. Another 240 fixed-geometry halftone-selection controls isolate source-content selection and reject a distinct-7-bit-colour threshold: 144 are exact and 96 filtered controls retain individual strict bounds. Fifty histogram-preserving halftone-arrangement captures show that spatial permutations change the branch, rejecting palette/histogram-only selection; 24 replay controls are exact. The eight pen anchor/dash reference-scaling discrepancies are closed.
2Text coverage and rasterisationtextx-plus-antialias, textx-plus-antialiasgridfit, textx-plus-cleartype and gpx-rec-textcontrast retain roughly 3.15%, 2.51%, 10.06% and 2.84% beyond eight levels. The three textx-plus antialias/ClearType PNGs were reproduced exactly with current native fonts, ruling out font drift for those comparisons. The 3,328 baseline-controlled text-coverage captures isolate glyphs from DrawString layout; 2,400 grayscale controls at quarter-pixel origins and every captured contrast mapping are exact. A further 1,664 ClearType captures verify 576 quarter-origin RGB controls and all per-channel contrast mappings. GDI+ coverage now truncates subpixel samples and reports natural widths to font hint programs. Fractional DriverString origins now preserve both grayscale phases and ClearType x phases. Of 144 independent DrawString controls, 88 closed glyph/format controls are exact. Independent 1/64-pixel x origins establish nearest-quarter grayscale placement: 1,280 additional controls are exact. A further 2,304 vertical-origin captures establish nearest-quarter grayscale y placement, closing another 1,280 controls with no capture regressions. Another 384 ClearType controls pin integer vertical placement. ClearType x origins now round to the nearest sixth pixel while retaining that fraction through scan conversion, closing 384 fine-origin RGB controls and preserving all prior exact captures. Fine-origin channel differences fall from 42,600 to 22,432. Some formerly inexact captures retain larger local residuals; diagonal/base outline hinting remains open. Another 432 private diagnostic-font GetGlyphOutline controls isolate exact vector normalization and one-unit projection/movement errors. The candidate primitive correction regresses existing exact real-font controls and is not shipped. Another 1,728 independent GDI+ private-font captures pin 375 exact controls individually; the candidate still loses prior exact real-font controls and increases eleven formerly inexact diagnostic residuals. Another 576 signed native outlines and 2,304 signed GDI+ images isolate projection, original-distance scaling and movement arithmetic; 436 outlines and 1,344 signed images are currently exact with individual bounds. The candidate closes all signed outlines but increases four formerly inexact signed image residuals and still loses fifteen prior exact real-font controls, so it remains excluded from production.
3Path-gradient and image-sampling arithmeticIndependent FocusScales, folded contour coverage and curve subdivision are corrected. Seven rectangle/ellipse controls and seven triangle controls are within one channel level; both collapsed triangle focus lines are within one channel level. Ellipse wrap fixtures differ at zero tolerance on 51–52% of pixels, mostly small channel changes; plain Bicubic PNG is RGB-exact across all 16,000 fixture pixels (previously 7,127 differing pixels, maximum seven). All 144 native arithmetic controls are exact, including premultiplied alpha. Another 384 independent phase captures improve from 347 to 380 exact with no per-case regression; four positive-boundary unit-scale copy controls remain open. Sixty-four independent crop/mirror controls improve from 10,474 to 132 differing pixels. SVG already offers device-resolution resampling through imageResampling: 'exact'; seven Chromium image/effect/transform controls match PNG RGB byte for byte in that mode. A chained exclusion clip is corrected, closing 4,000 SVG-vs-PNG pixels; native clip/z-order residuals remain ten one-level pixels. Default renderer scaling is preserved. High-quality interpolation and rectangular blend gradients also retain widespread 1–3-level errors. Across 252 independent contour/order controls, 212 are within one level; the remaining 40 retain 57 boundary/overlap pixels beyond one level. Measure native intermediate arithmetic. Linear Blend tables are already exact.
4Red-eye and HALFTONE generalisationRed-eye Only playback retains 12/99/582 differing pixels (left/both/whole) in this baseline. The darkness falloff now applies symmetrically around its sector mean below twice that mean; 103 nonzero-darkness controls are exact across 264 independent captures, including 31 held-out controls. Two formerly inexact split fields retain slightly larger centroid residuals; pure-red native outputs show capture-order sensitivity. Another 216 central kernel captures close 72 nearest-branch controls and measure 96 filtered 2x/3x responses exactly. A fractional 2.37x impulse rejects the same integrated-tent formula (fourteen channel levels); no general selector/kernel is shipped. Close the remaining pupil/centre model and enlargement-kernel formula on independent captures. Keep the existing exact mixed-axis fixtures exact.
5Fractional and transformed geometryScaled EMF inside-frame retains 80 pixels; scaled WMF shapes retain seven. Clockwise RoundRect rounding is corrected on 432 independent controls: 87/216 clockwise paths and all 72 even-FIX controls are exact, with remaining coordinate error at most one FIX and prior exact controls preserved. Continue with half-FIX side/corner ties, arc geometry, square-capped curves, rotated/sheared and dashed nonuniform GDI pens, and unprobed EMF+ inset/compound figures.

Completion requires exact full-output comparisons (including alpha and painted pixels outside the current overlap), matching native environments, independent scale/transform captures, and PNG/SVG verification. Existing tolerance bounds must not be increased to make a candidate fix pass.

Closed in this pass: native axis-aligned Bicubic arithmetic makes the PNG fixture RGB-exact across all 16,000 pixels, with all 144 arithmetic controls exact and no per-case regressions across 64 independent crop/mirror and 384 independent phase controls. Native pen playback now names a pixel source rectangle, and the generator disables process DPI virtualisation; the six anchor-cap and two scale3-dash references now match exactly. PolyTextOut now preserves C1 glyphs as native metafile playback does, reducing its recorded fixture from 39 differing pixels to 12; eight focused controls pin both record families and IGNORELANGUAGE. EMF+ coverage masks retain underline/strike-out bars, use GDI+'s 16-shade mapping, and run its grayscale subpixel interpreter. ClearType uses natural-width interpreter flags and truncates subpixel coverage. Eighty-eight expanded playback references now validate ink beyond the old native surfaces without replacing the original PNGs. Solid GDI pens under unequal axis scales now use native elliptical geometry: all 216 image controls are exact, and all 3,600 widened outlines and a further 16,128 independent direction/corner controls are exact. Path-gradient boundaries share the fixed-point flattener and match all 1,556 native Flatten vertices; gradient contour and scanline corrections tighten twenty-one PNG/SVG focus controls to a one-level channel bound. Fractional text origins close 2,400 grayscale and 288 ClearType controls; nearest-quarter grayscale x placement closes another 1,280 independent fine-origin controls and 88 DrawString controls. The end-to-end unhinted antialias text fixture falls from 1,300 to 650 differing pixels. Native captures and environment manifests accompany these changes.

EMF+ image effects ​

The 74 Dual effect fixtures (plus-effect-*) and 74 Only equivalents (plus-only-effect-*) are in the parity test. They have been regenerated on Windows with corrected metafile type constants. src/emf-plus-image-effects.fixture.test.ts also checks the effect algorithms against the effected bitmaps that GDI+ records into each fixture.

  • Not exact yet:
    • Red-eye uses a measured sector/centre model, with remaining pupil, dark-pixel and multi-area residuals; see the detailed limitations.
    • The rotated blur's effected bitmap is exact and its playback is within 0.010% (plus-effect-blur-r3-rotate30, two pixels over 8 levels; 0.22% before the blur's first halo column was sampled at the right edge).

Blur and sharpen are exact. Large blur reproduces the native per-axis algorithm (reduce each row by the factor measured at all 957 quarter radii, filter with the centre weight applied as two rounded halves, enlarge, then the same for columns, with products kept to 1/256 of a level), and the kernel weights are float32 values formed in truncating arithmetic (accumulated offset, ordered sum, multiply by the reciprocal normaliser; see blurKernel). They match native noise images at random radii from 1 to 255, ramps, impulses, the 957-radius and two-pixel-wide captures, the 504-draw expanded capture (fourteen rectangles, twelve radii, opaque/translucent patterns) and 150 narrow and edge-reaching draws, pixel for pixel. Expanded blur follows the native reduction (a cropped source rectangle reduces from its own corner, only its own samples are enlarged, samples beyond the buffer are transparent, a lone sample is continued toward a transparent neighbour).

Sharpen strength now uses the native rational amount curve, quantized to 1/64 with half-down rounding. It matches every integer amount 0–100 and 19 radii when tested independently of blur convolution.

  • JPEG coverage: accurate integer IDCT, triangle chroma upsampling and fixed-point colour conversion now match the committed standalone JPEG and JPEG-TIFF references exactly. CMYK, arithmetic-coded and 12-bit JPEG still use a less exact fallback. GIF and lossless TIFF references remain exact, including offset/palette GIFs, LZW/multipage/bilevel TIFF, Deflate strips and uncompressed/Deflate tiles.

EMF+ rotated high-quality DrawImage ​

A rotated or sheared HighQualityBicubic/HighQualityBilinear DrawImage (a 3-point destination) is modelled from native draws of solid, noise, impulse and transparent-bordered images (System.Drawing, public API) over angles 5 to 70 degrees and scales 0.4 to 6 (gpx-image-rotated-highqualitybicubic 0.142% before, 0.013% now, two pixels over 8 levels):

  • If either source axis is unscaled (its device length rounded up is within one pixel of the source length: 20 texels at scales 0.905 to 1.05), GDI+ point-samples with the plain Bicubic (a = -0.5) or Bilinear kernel, with no half-pixel shift.
  • Otherwise the area-integrated kernel applies. Under PixelOffsetMode Half/HighQuality the sample grid sits half a device pixel further along each of the image's own axes (coverage unchanged; impulse responses match within 4 levels, where they were 3,500 pixels off before on noise).
  • The far (right and bottom) edges fade: native alpha is the kernel's alpha minus a share of the alpha the kernel has at the edge, zero at the edge and rejoining the kernel one device pixel in, independent of angle and scale (cubic table in fadeAt; linear for the tent). The earlier "15 to 17 levels low over the last 0.3 pixels" was this fade plus the shift.
  • A tap outside the source rectangle but inside the bitmap reads the bitmap (every interpolation mode, measured on sub-rectangle draws); only taps outside the bitmap are transparent. The previous transparent-outside-the-rectangle rule held only for whole-bitmap draws.

Remaining: the rotated interior colour differs by up to about 9 levels on noise at upscales (the impulse response itself is within 4), HighQualityBilinear is within 3 to 4 levels of the tent model at 2x to 5x, an upscale between 1.1x and 2x still has the largest noise residual, and the far-edge fade table is measured at scales of 2 or more (a smaller scale does not follow it as closely). Rotated draws also snap all three destination corners to 1/16 pixel on the DrawImage path (6 levels at a far edge), but doing so made the effect fixtures worse, so only the origin is snapped.

EMF+ gradients ​

Linear Blend tables are closed: buildLinearRampTable reproduces all 4,352 native three-point ramps (opaque and translucent) exactly; GDI+ forms each knot in float32 arithmetic that truncates toward zero. Path-gradient sampling and edge coverage retain the zero-tolerance differences listed above.

GDI color adjustment and HALFTONE ​

  • Colour adjustment is reproduced from native colour cubes: curve stages (gamma, reference black/white, contrast, brightness, log, negative) are exact, illuminants 1-5, 7 and 8 use native cubes, and colorfulness/tint match the native cubes on 99.5-99.8% of channels (the chroma stage reads the unrounded palette level and rounds before the curves). Windows' 66x65 ordered dither over 32 levels per channel is reproduced, including mirrored destinations, brush origins, StretchDIBits, axis-aligned PlgBlt and the mixed-axis phase rule; rotated blits follow the session's first-HALFTONE-blit rule. The turned u' is floored at 0, which makes strongly rotated blues (tint beyond about 50) match. The matrix is the one derived from the BT.709 primaries and D65 white (7 decimals), which removed most exact-half ties (0.05-0.4% of channels still differ by one level), and an illuminant combined with colorfulness/tint now carries the illuminant's unclamped linear output (ILLUMINANT_MATRICES) into the chroma stage. Remaining: a few strongly blue colours under illuminant + chroma (the illuminant's blue corner is not linear), and a few mixed-axis pixels under colour adjustment (emfrec-halftone-ramp-0p5x-2y-ca 0.111%, -2x-0p5y-ca 0.07%). When columns are reduced and rows enlarged under a dithered adjustment, Windows sharpens the last row against a further row that is the last source row replicated and dithered at the next pattern row. Reducing both axes (also StretchDIBits) is now exact: rows rounded to integers first, columns unrounded, sharpen on the unrounded image.
  • Mixed-axis stretching: all 96 native size/pattern combinations are byte-exact (single-row destinations and the exact-tie checker patterns are closed: the reduction uses 13-bit cumulative shares per footprint, and a 2-row source squeezed to 1 row is despeckled and, with at least 2x enlargement, reduced to its last row; the enlargement weights are whole 13-bit shares built by cumulative rounding up, and a mirrored enlarged axis reverses the finished rows). Unresolved: the generating formula of the enlargement kernel (halftoneEnlargeTaps). Black-box extraction of the integer weight rows (random-data capture of the single-axis response, solved to exact integers) for about 410 size pairs shows the structure (area resample, destination-space FIR sampling one kernel at k / ratio, cumulative round-up shares), but no closed form fits it: box-plus-triangle with a free tail, polynomial and spline families of up to 40 parameters, quantised sampling positions and cascaded box filters were all tried and rejected, and only a 96-step interpolation table solved against the measured rows reproduces them (about 98% of the rows it was solved on, about 95% of the rows of sizes held out of the solve). Far taps (a source pixel 1.4-1.5 pixels from the destination centre) also deviate by a share or two in a few rows for ratios just above an integer, which the table cannot absorb. Further native size pairs would tighten the table; the exact formula would remove it.
  • Enlargement pre-smoothing (despeckle): measured from native captures and now exact on every black/white 4x4 pattern (also at the image edges), every pattern up to 5x3, and several hundred random black/white, grey, palette and noise images from 2x2 to 40x40 at 2x, 3x and 4x/1x2 ratios (src/halftone-despeckle.fixture.test.ts). Unverified: brightness ties between the two diagonals of a block beyond the single measured case, the exact brightness weights (4R + 8G + B fits every sample but is a fit), and patterns larger than the sizes above that mix many overlapping checker runs.

Further parity rounds (3 October 2026) ​

Three additional parallel rounds ship four bounded runtime corrections: the half-open unit-scale Bicubic copy interval, high-quality interpolation when only one axis is scaled, preservation of explicitly supplied font projection/freedom vector words, and premultiplied path-gradient interpolation for uniform surrounds with unequal alpha. No existing per-case bounds were relaxed.

  • Bicubic: 936 independent copy controls improve from 866 to 930 exact; differing pixels fall from 3,340 to 368. All 144 arithmetic controls remain exact; the positive phase endpoint still needs dispatch evidence.
  • High-quality sampling: 288 controls reduce differing pixels from 37,414 to 35,702 and maximum channel error from 64 to 3. Another 192 independent crop/mirror/alpha controls improve from 29,711 to 27,888 differing pixels, without per-case regressions. Remaining integrated-kernel arithmetic stays open.
  • Font vectors: 448 new native outlines improve from 203 to 267 exact, closing 64 direct-vector controls. Another 2,560 GDI+ images, 384 opcode outlines and 3,072 opcode images pin the broader arithmetic candidates. Combined-rounding exceptions fail independent MDRP controls; the general projection/movement candidate still loses exact real-font or unequal-vector controls and remains excluded.
  • Path-gradient alpha: 360 new native controls validate the uniform-surround correction. In the 120 independent uniform-alpha subgroup, pixels beyond one channel level fall from 145,136 to 16; controls within one level rise from 22 to 109. Varying surrounds and the prior 57 focus-boundary pixels beyond one level remain open.
  • HALFTONE: discrete nearest-source runs and quantised tent weights reproduce 2,112 response lines. Vertical-first integer intermediate rounding predicts all 432 new central RGB crops, including 48 independent held-out controls, and all 144 prior filtered crops exactly. The model remains test-only until content selection, edges, alpha and runs outside lengths 2�4 are verified.
  • References: all 92 expanded captures reproduce their original overlap exactly and regenerate byte-for-byte in isolated processes. Eight recordings require explicit recorded-frame/per-record playback. Four mixed-axis checker extents are now covered, leaving nine uncaptured text extents. The report retains 391/611 common-area exact comparisons and improves complete RGB ink coverage to 390/611, with no render failures or missing reference ink.

GDI path geometry ​

RoundRect controls now match native GetPath captures without exceptions. The compatible-mode cases also match at 1/16-pixel precision, including mirrored viewports and clockwise paths; path-probe regenerates both captures.

  • Native wide-path-probe now covers 2,136 three-point paths with 2–64 px pens, all cap/join combinations and near reversals. All 128 round-cap/round-join fills match exactly in the regression test. Miter limit tests now follow native whole-pixel rounding of the fixed-point left-side vector (and its negation for the right side); 766 of 768 decisions around 384 measured thresholds match. The two retained decisions share a 7 px perpendicular error. All 228 square/flat-cap miter fills at 2/5 px now match exactly, including near reversals. Selecting cap/join arc vertices from the unrounded pen boundary point also fixes missed/extra endpoints. These changes reduce differing fills from 86 to 68, without changing any formerly exact fill in the capture. The half-pixel rounding of the flattened-pen perpendicular is a closed rule (no per-width table): the point of the pen edge between the support vertex and its interpolation partner, plus a half-unit bias along the segment, plus half a unit lower when the edge's extent in that channel is odd (half a unit higher on the edge that closes the pen), with a rounding boundary rounding up except in y for a segment running upward, and a reversed segment parallel to the closing edge resting on that edge's first vertex; vertical segments follow from the same rule (no horizontal bias). flat-pen-probe captures 1,176 native perpendiculars at fractional and wider-than-100 px widths, and a test checks every one. Two vertices resting on the same pen vertex at a flat-capped round join enclose no other pen vertex. All 2,136 native wide-path fills and all 768 miter-limit decisions now match.

  • wide-outline-probe captures 72 polyline/ellipse outlines across four widths and every cap/join combination. All 36 ellipse outlines match every native vertex, including the duplicated inner triangles; emfrec-path-widen-outline now matches exactly (previously 1.184% mismatches).

  • Native wmf-insideframe-curves now covers 100 ellipse/RoundRect/chord/pie/arc cases at 0.5–10 px. Fractional fitting and widening, plus scaling RoundRect corners onto the inset box, reduce closed-curve mismatches from 1.67–2.79% to 0.11–0.16%; arc retained 0.039% until the arc geometry below. Small boundary differences remain.

  • Arc, Chord and Pie geometry follows native GetPath captures (arc-path-probe: 900 arcs under both arc directions, arc-paths.json and arc-paths-cw.json, and 260 arcs on a 40,000 px circle, arc-precise.json, where one FIX is 3 millionths of the radius). The model, which reproduces 898 of 900 counter-clockwise and 898 of 900 clockwise paths exactly (the other four one FIX off in one point; before: 662 and 234 one FIX off, 4 up to 5 FIX), and the 260 large-circle arcs to within 3 FIX at a radius of 320,000 FIX:

    • An arc radial's angle is Windows' own approximate arc tangent: in each octant the slope (smaller over larger component) goes through 32 equal slope intervals with linear interpolation of the exact arc tangent at the knots, so the angle sits up to 80 microradians below the true one (a sawtooth every 1/32 of the slope; measured to 2 microradians). The direction is the radial over the box's half axes, measured on the unrounded logical coordinates (not on device-rounded points).
    • Points are those of a regular 128-gon inscribed in the unit circle (polygonTrig), linear in the angle between its vertices, so they sit up to 1 - cos(pi / 128) inside the circle (the old table of 33 fitted node values was this polygon plus the arc-tangent error, mistaken for node errors). Arcs whose two radials are 3 degrees apart or less as angles in [0, 2 pi) (not across the 0 axis, and not the same radial twice) use exact cosines and sines for their points, but not for the control distance.
    • Each piece (the arc cut at the quadrant boundaries) is a cubic with end points P0, P3 (the polygon points) whose controls divide P -> X at kappa = 4/3 c / (1 + c), c being the polygon cosine of half the piece's sweep and X the intersection of the lines x . P0 = 1 and x . P3 = 1 (each a sag outside the true tangent). This single rule replaces the earlier anchored-piece and quadrant-interior models.
    • A whole quadrant between other pieces takes the full ellipse's own Bezier, and so does the first piece of an arc starting on 90 or 180 degrees (270 and 0 mirrored for a clockwise arc, which is the y mirror image) and the last piece of one ending on 270 or 360 (90 and 180 clockwise); a whole-quadrant first or last piece of the other kind, and an arc that is just that one quadrant, is built like any partial piece (as if a zero-length piece came first or last).
    • Arcs are measured as before for the radials, and a RoundRect scales its corner onto the drawn box from the unrounded device size: fractional extents under a cosmetic pen, whole FIX (truncated) under wide and null pens, replacing the earlier even-pixel rule, which matched only the 12 x 9 corner of wmf-shapes (wmf-roundrect-corners: 75 wide-pen and 25 null-pen corners at two scales; mismatches 500 and 813 pixels to 0 and 0). wmf-insideframe-curved-chord/pie/arc and the inside-frame Chord/Pie/Arc pixels are exact, and wmf-shapes-scaled fell from 0.158% to 0.008% (7 pixels).
    • AngleArc takes its angles directly (no radial, no arc tangent): the same polygon trigonometry and piece rule, with exact trigonometry for sweeps of 3 degrees or less, now give 599 of 600 native paths exactly (angle-arc-paths.json, in the arc-path-probe group; before: 71, with 86 having a different number of Beziers). An arc of less than 90 degrees is a single Bezier even across a multiple of 90 degrees (the earlier rule cut it there); from 90 degrees on it is cut at the multiples of 90 and ends with a zero-length piece on a boundary, as before.
    • Not reproduced: four paths with one control or end point one FIX off (arcs close to a full turn or to the 3 degree threshold, where the exact value is within 0.15 FIX of a rounding boundary), arcs of under 1 degree (a native point is up to 2 FIX away at a radius of 320,000 FIX, from fixed-point arithmetic that is not modelled), and the zero-length leading or trailing Bezier Windows emits where an arc starts or ends exactly on a boundary (dropped by the comparison).
  • Flat-capped round joins no longer include a vertex that lies exactly on the second ray, and keep a steep segment's extreme-x vertex on the left side (flat/round 5,999 random paths: 86 differing to 1). A wide pen on a curve is widened with per-segment curve rules: the pen rests on a flattened curve's support vertices and round joins, a joint between two cubics takes the tangent of the cubic with the longer control arm, and a curve end's perpendicular and square-cap extension follow its end tangent. curve-widen-probe captures 320 native WidenPath outlines (80 Beziers, 80 each of arcs, chords and pies; flat, square and round caps; round, bevel and miter joins): the Beziers are exact. Open: dash placement along curved Beziers, square caps on arcs, and line-to-curve corners of chords and pies.

    Rectangular inside-frame native sweeps now cover 0.5–10 px widths and are exact; fractional transformed cases remain open.

  • PS_INSIDEFRAME geometry follows GetPath captures (GM_ADVANCED for EMF, GM_COMPATIBLE for WMF, five and six scales, 1,200 boxes per shape):

    • The pen width along each axis, wx and wy, is its logical width times that axis' scale in whole FIX of a device pixel (not the isotropic width: 1,200 of 1,200 boxes against 664 of 1,200). A pen under 1.5 pixels along both axes (24 FIX) is cosmetic and leaves the box alone; a box narrower than the pen along either axis is drawn unchanged (EMF).
    • EMF Rectangle: the left edge moves in by ceil(wx / 2), the right by floor(wx / 2), the top and bottom by ceil(wy / 2) each. Every other box shape: floor on the left and ceil on the right (an odd width puts these edges on half a FIX; the Ellipse path is then the box [left, right] with its first half (points 0 to 5 and 12) one FIX to the right, exact for 127 of 127 captured odd-width Ellipses; the RoundRect's first corners follow the same shift except for the rounding of its four side points, correct in about two cases of three) and ceil(wy / 2) on the top and bottom. WMF (compatible mode, whole-pixel boxes): Rectangle left ceil(wx / 2) and right floor(wx / 2) of the pixel box, other shapes floor both sides, top and bottom ceil (WMF 1,200 of 1,200 boxes).
    • An EMF Arc, Chord or Pie measures its radials' angles on the box as given and carries them onto the framed box about its centre (the same rule as WMF; measuring them on the framed box leaves 0.7% to 1.2% of the pixels off). A RoundRect corner is scaled onto the framed box as floor(min(corner, box) * framed / box) from the unrounded corner and box extents (about 95% of the corner extents on GM_ADVANCED captures, 308 of 600 whole paths on the WMF scaled captures against 43 with the earlier pen-width model; the rest are a FIX off).
    • New capture group emf-insideframe (emf-insideframe-{rect,ellipse,roundrect,arc,chord,pie,polygon}: pens of 1 to 16 px, GM_ADVANCED, the Polygon as control; emf-insideframe-scaled: the shapes under a 1.37 world scale). The unscaled sheets are pixel-exact; the scaled one keeps 80 of 170,962 pixels (0.096% with the box rule alone).

Text ​

  • Unresolved differences: ClearType, EMF+ antialiased text and TextContrast retain the fixture residuals above. PolyTextOut C1 suppression is fixed; the remaining 12 pixels in its original fixture and three pixels in the Arial C1 controls are glyph-edge differences. Courier C1 controls are exact.
  • Fonts in fixtures: runner fonts can differ from original captures. New captures include font hashes and native library versions. Current native fonts exactly reproduce the three textx-plus antialias/ClearType PNGs; other old captures still lack complete provenance.

Tooling ​

  • Regenerating existing groups: running existing fixture groups on the Windows runner can change their PNGs, because the runner's OS, fonts and DPI can differ. Compare before replacing committed fixtures.

Every new generator run writes an environment-<groups>.json manifest associating reference hashes with Windows/native-library versions, screen DPI and installed font hashes. This makes subsequent environment changes detectable; it cannot recover the environment of earlier captures.

Released under the Apache-2.0 License.