From ad388702b83b7b4229f58061db844b8dd5224f9c Mon Sep 17 00:00:00 2001 From: Universe Date: Thu, 27 Aug 2026 07:20:50 +0900 Subject: [PATCH 1/2] websem: close SVG diffuse-lighting rows --- crates/n0/src/drawlist.rs | 22 + crates/n0/src/glyphless.rs | 35 +- crates/n0/src/paint.rs | 150 +++- crates/n0_cli/README.md | 66 +- crates/rframe/src/filter.rs | 88 ++- crates/rframe/src/lib.rs | 6 +- crates/rframe/tests/filter_contract.rs | 124 +++- crates/websem/src/svg.rs | 281 +++++++- crates/websem/tests/unsupported_corpus.rs | 30 + docs/wg/consolidation/svg-engine-of-record.md | 117 +++- docs/wg/consolidation/web-checklist.md | 77 ++- fixtures/web-first/README.md | 5 + fixtures/web-first/STATUS.md | 83 ++- .../svg-filter-diffuse-blur-after.png | Bin 0 -> 2249 bytes .../svg-filter-diffuse-blur-before.png | Bin 0 -> 2426 bytes .../svg-filter-diffuse-child-order.png | Bin 0 -> 3303 bytes .../svg-filter-diffuse-color-linear.png | Bin 0 -> 1060 bytes .../svg-filter-diffuse-color-srgb.png | Bin 0 -> 1071 bytes .../svg-filter-diffuse-composite-out.png | Bin 0 -> 905 bytes .../svg-filter-diffuse-constant-default.png | Bin 0 -> 897 bytes ...svg-filter-diffuse-constant-empty-zero.png | Bin 0 -> 162 bytes ...filter-diffuse-constant-negative-clamp.png | Bin 0 -> 162 bytes ...ilter-diffuse-constant-number-exponent.png | Bin 0 -> 814 bytes ...vg-filter-diffuse-constant-number-plus.png | Bin 0 -> 814 bytes .../svg-filter-diffuse-constant-zero.png | Bin 0 -> 162 bytes .../svg-filter-diffuse-convolve-before.png | Bin 0 -> 834 bytes ...g-filter-diffuse-distant-angle-default.png | Bin 0 -> 827 bytes ...svg-filter-diffuse-distant-angle-large.png | Bin 0 -> 991 bytes ...ilter-diffuse-distant-azimuth-negative.png | Bin 0 -> 897 bytes ...ter-diffuse-distant-elevation-negative.png | Bin 0 -> 496 bytes .../chromium/svg-filter-diffuse-distant.png | Bin 0 -> 897 bytes .../svg-filter-diffuse-gradient-alpha.png | Bin 0 -> 471 bytes .../svg-filter-diffuse-input-default.png | Bin 0 -> 1071 bytes .../svg-filter-diffuse-input-source-alpha.png | Bin 0 -> 1071 bytes ...vg-filter-diffuse-input-source-graphic.png | Bin 0 -> 1071 bytes ...filter-diffuse-kernel-unit-length-drop.png | Bin 0 -> 1142 bytes ...iffuse-kernel-unit-length-invalid-drop.png | Bin 0 -> 1142 bytes ...lter-diffuse-light-color-alpha-ignored.png | Bin 0 -> 1030 bytes ...ilter-diffuse-light-color-currentcolor.png | Bin 0 -> 1030 bytes ...svg-filter-diffuse-light-color-default.png | Bin 0 -> 1004 bytes ...svg-filter-diffuse-light-color-invalid.png | Bin 0 -> 1004 bytes .../svg-filter-diffuse-light-color-rgb.png | Bin 0 -> 1030 bytes ...lter-diffuse-light-color-srgb-function.png | Bin 0 -> 1030 bytes ...filter-diffuse-light-color-transparent.png | Bin 0 -> 162 bytes .../svg-filter-diffuse-missing-light.png | Bin 0 -> 169 bytes .../svg-filter-diffuse-nested-light.png | Bin 0 -> 169 bytes .../svg-filter-diffuse-nonlight-child.png | Bin 0 -> 897 bytes ...svg-filter-diffuse-object-box-overflow.png | Bin 0 -> 169 bytes .../svg-filter-diffuse-output-alpha.png | Bin 0 -> 1071 bytes ...g-filter-diffuse-point-primitive-units.png | Bin 0 -> 3407 bytes .../svg-filter-diffuse-point-x-negative.png | Bin 0 -> 2806 bytes .../svg-filter-diffuse-point-y-negative.png | Bin 0 -> 3119 bytes .../svg-filter-diffuse-point-z-negative.png | Bin 0 -> 162 bytes .../chromium/svg-filter-diffuse-point.png | Bin 0 -> 3303 bytes .../svg-filter-diffuse-region-percent.png | Bin 0 -> 527 bytes .../svg-filter-diffuse-spot-cone-active.png | Bin 0 -> 3505 bytes .../svg-filter-diffuse-spot-cone-default.png | Bin 0 -> 3925 bytes .../svg-filter-diffuse-spot-cone-negative.png | Bin 0 -> 3505 bytes .../svg-filter-diffuse-spot-cone-outside.png | Bin 0 -> 3925 bytes .../svg-filter-diffuse-spot-degenerate.png | Bin 0 -> 162 bytes ...g-filter-diffuse-spot-exponent-default.png | Bin 0 -> 3487 bytes ...lter-diffuse-spot-exponent-lower-clamp.png | Bin 0 -> 3487 bytes ...lter-diffuse-spot-exponent-upper-clamp.png | Bin 0 -> 1437 bytes ...vg-filter-diffuse-spot-primitive-units.png | Bin 0 -> 2408 bytes .../svg-filter-diffuse-spot-target-x.png | Bin 0 -> 3298 bytes .../svg-filter-diffuse-spot-target-y.png | Bin 0 -> 3332 bytes .../svg-filter-diffuse-spot-target-z.png | Bin 0 -> 3173 bytes .../chromium/svg-filter-diffuse-spot.png | Bin 0 -> 3720 bytes .../chromium/svg-filter-diffuse-stroke.png | Bin 0 -> 2079 bytes .../svg-filter-diffuse-surface-default.png | Bin 0 -> 928 bytes .../svg-filter-diffuse-surface-empty-zero.png | Bin 0 -> 168 bytes .../svg-filter-diffuse-surface-max.png | Bin 0 -> 392 bytes .../svg-filter-diffuse-surface-negative.png | Bin 0 -> 906 bytes ...filter-diffuse-surface-number-exponent.png | Bin 0 -> 897 bytes ...svg-filter-diffuse-surface-number-plus.png | Bin 0 -> 897 bytes .../svg-filter-diffuse-surface-zero.png | Bin 0 -> 168 bytes .../svg-filter-diffuse-target-clip.png | Bin 0 -> 527 bytes .../svg-filter-diffuse-target-mask.png | Bin 0 -> 527 bytes .../svg-filter-diffuse-target-opacity.png | Bin 0 -> 999 bytes .../svg-filter-diffuse-transform-axis.png | Bin 0 -> 1294 bytes ...-filter-diffuse-transform-quarter-turn.png | Bin 0 -> 992 bytes ...vg-filter-diffuse-transform-reflection.png | Bin 0 -> 162 bytes .../chromium/svg-filter-diffuse-use.png | Bin 0 -> 1071 bytes .../chromium/svg-filter-diffuse-viewbox.png | Bin 0 -> 3217 bytes fixtures/web-first/oracle-bake.json | 641 +++++++++++++++++- fixtures/web-first/primitives.json | 568 ++++++++++++++++ .../svg-filter-diffuse-blur-after.svg | 1 + .../svg-filter-diffuse-blur-before.svg | 1 + .../svg-filter-diffuse-child-order.svg | 1 + .../svg-filter-diffuse-color-linear.svg | 1 + .../svg-filter-diffuse-color-srgb.svg | 1 + .../svg-filter-diffuse-composite-out.svg | 1 + .../svg-filter-diffuse-constant-default.svg | 1 + ...svg-filter-diffuse-constant-empty-zero.svg | 1 + ...filter-diffuse-constant-negative-clamp.svg | 1 + ...ilter-diffuse-constant-number-exponent.svg | 1 + ...vg-filter-diffuse-constant-number-plus.svg | 1 + .../svg-filter-diffuse-constant-zero.svg | 1 + .../svg-filter-diffuse-convolve-before.svg | 1 + ...g-filter-diffuse-distant-angle-default.svg | 1 + ...svg-filter-diffuse-distant-angle-large.svg | 1 + ...ilter-diffuse-distant-azimuth-negative.svg | 1 + ...ter-diffuse-distant-elevation-negative.svg | 1 + .../web-first/svg-filter-diffuse-distant.svg | 1 + .../svg-filter-diffuse-gradient-alpha.svg | 1 + .../svg-filter-diffuse-input-default.svg | 1 + .../svg-filter-diffuse-input-source-alpha.svg | 1 + ...vg-filter-diffuse-input-source-graphic.svg | 1 + ...filter-diffuse-kernel-unit-length-drop.svg | 16 + ...iffuse-kernel-unit-length-invalid-drop.svg | 16 + ...lter-diffuse-light-color-alpha-ignored.svg | 1 + ...ilter-diffuse-light-color-currentcolor.svg | 1 + ...svg-filter-diffuse-light-color-default.svg | 1 + ...svg-filter-diffuse-light-color-invalid.svg | 1 + .../svg-filter-diffuse-light-color-rgb.svg | 1 + ...lter-diffuse-light-color-srgb-function.svg | 1 + ...filter-diffuse-light-color-transparent.svg | 1 + .../svg-filter-diffuse-missing-light.svg | 1 + .../svg-filter-diffuse-nested-light.svg | 1 + .../svg-filter-diffuse-nonlight-child.svg | 1 + ...svg-filter-diffuse-object-box-overflow.svg | 1 + .../svg-filter-diffuse-output-alpha.svg | 1 + ...g-filter-diffuse-point-primitive-units.svg | 1 + .../svg-filter-diffuse-point-x-negative.svg | 1 + .../svg-filter-diffuse-point-y-negative.svg | 1 + .../svg-filter-diffuse-point-z-negative.svg | 1 + .../web-first/svg-filter-diffuse-point.svg | 1 + .../svg-filter-diffuse-region-percent.svg | 1 + .../svg-filter-diffuse-spot-cone-active.svg | 1 + .../svg-filter-diffuse-spot-cone-default.svg | 1 + .../svg-filter-diffuse-spot-cone-negative.svg | 1 + .../svg-filter-diffuse-spot-cone-outside.svg | 1 + .../svg-filter-diffuse-spot-degenerate.svg | 1 + ...g-filter-diffuse-spot-exponent-default.svg | 1 + ...lter-diffuse-spot-exponent-lower-clamp.svg | 1 + ...lter-diffuse-spot-exponent-upper-clamp.svg | 1 + ...vg-filter-diffuse-spot-primitive-units.svg | 1 + .../svg-filter-diffuse-spot-target-x.svg | 1 + .../svg-filter-diffuse-spot-target-y.svg | 1 + .../svg-filter-diffuse-spot-target-z.svg | 1 + .../web-first/svg-filter-diffuse-spot.svg | 1 + .../web-first/svg-filter-diffuse-stroke.svg | 1 + .../svg-filter-diffuse-surface-default.svg | 1 + .../svg-filter-diffuse-surface-empty-zero.svg | 1 + .../svg-filter-diffuse-surface-max.svg | 1 + .../svg-filter-diffuse-surface-negative.svg | 1 + ...filter-diffuse-surface-number-exponent.svg | 1 + ...svg-filter-diffuse-surface-number-plus.svg | 1 + .../svg-filter-diffuse-surface-zero.svg | 1 + .../svg-filter-diffuse-target-clip.svg | 1 + .../svg-filter-diffuse-target-mask.svg | 1 + .../svg-filter-diffuse-target-opacity.svg | 1 + .../svg-filter-diffuse-transform-axis.svg | 1 + ...-filter-diffuse-transform-quarter-turn.svg | 1 + ...vg-filter-diffuse-transform-reflection.svg | 1 + fixtures/web-first/svg-filter-diffuse-use.svg | 1 + .../web-first/svg-filter-diffuse-viewbox.svg | 1 + fixtures/web-first/unsupported/README.md | 8 +- ...g-filter-diffuse-composition-precision.svg | 13 + ...svg-filter-diffuse-transform-precision.svg | 11 + .../svg-filter-lighting-color-css.svg | 9 + .../svg-filter-lighting-color-inherit.svg | 9 + .../svg-filter-lighting-color-syntax.svg | 9 + .../svg-filter-lighting-color-var.svg | 9 + .../unsupported/svg-filter-primitive.svg | 4 +- 165 files changed, 2406 insertions(+), 60 deletions(-) create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-blur-after.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-blur-before.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-child-order.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-color-linear.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-color-srgb.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-composite-out.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-constant-default.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-constant-empty-zero.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-constant-negative-clamp.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-constant-number-exponent.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-constant-number-plus.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-constant-zero.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-convolve-before.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-distant-angle-default.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-distant-angle-large.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-distant-azimuth-negative.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-distant-elevation-negative.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-distant.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-gradient-alpha.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-input-default.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-input-source-alpha.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-input-source-graphic.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-kernel-unit-length-drop.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-kernel-unit-length-invalid-drop.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-light-color-alpha-ignored.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-light-color-currentcolor.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-light-color-default.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-light-color-invalid.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-light-color-rgb.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-light-color-srgb-function.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-light-color-transparent.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-missing-light.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-nested-light.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-nonlight-child.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-object-box-overflow.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-output-alpha.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-point-primitive-units.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-point-x-negative.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-point-y-negative.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-point-z-negative.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-point.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-region-percent.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-cone-active.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-cone-default.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-cone-negative.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-cone-outside.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-degenerate.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-exponent-default.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-exponent-lower-clamp.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-exponent-upper-clamp.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-primitive-units.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-target-x.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-target-y.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot-target-z.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-spot.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-stroke.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-surface-default.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-surface-empty-zero.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-surface-max.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-surface-negative.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-surface-number-exponent.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-surface-number-plus.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-surface-zero.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-target-clip.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-target-mask.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-target-opacity.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-transform-axis.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-transform-quarter-turn.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-transform-reflection.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-use.png create mode 100644 fixtures/web-first/chromium/svg-filter-diffuse-viewbox.png create mode 100644 fixtures/web-first/svg-filter-diffuse-blur-after.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-blur-before.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-child-order.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-color-linear.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-color-srgb.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-composite-out.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-constant-default.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-constant-empty-zero.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-constant-negative-clamp.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-constant-number-exponent.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-constant-number-plus.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-constant-zero.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-convolve-before.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-distant-angle-default.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-distant-angle-large.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-distant-azimuth-negative.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-distant-elevation-negative.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-distant.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-gradient-alpha.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-input-default.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-input-source-alpha.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-input-source-graphic.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-kernel-unit-length-drop.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-kernel-unit-length-invalid-drop.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-light-color-alpha-ignored.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-light-color-currentcolor.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-light-color-default.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-light-color-invalid.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-light-color-rgb.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-light-color-srgb-function.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-light-color-transparent.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-missing-light.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-nested-light.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-nonlight-child.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-object-box-overflow.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-output-alpha.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-point-primitive-units.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-point-x-negative.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-point-y-negative.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-point-z-negative.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-point.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-region-percent.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-cone-active.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-cone-default.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-cone-negative.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-cone-outside.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-degenerate.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-exponent-default.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-exponent-lower-clamp.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-exponent-upper-clamp.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-primitive-units.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-target-x.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-target-y.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot-target-z.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-spot.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-stroke.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-surface-default.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-surface-empty-zero.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-surface-max.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-surface-negative.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-surface-number-exponent.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-surface-number-plus.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-surface-zero.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-target-clip.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-target-mask.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-target-opacity.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-transform-axis.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-transform-quarter-turn.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-transform-reflection.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-use.svg create mode 100644 fixtures/web-first/svg-filter-diffuse-viewbox.svg create mode 100644 fixtures/web-first/unsupported/svg-filter-diffuse-composition-precision.svg create mode 100644 fixtures/web-first/unsupported/svg-filter-diffuse-transform-precision.svg create mode 100644 fixtures/web-first/unsupported/svg-filter-lighting-color-css.svg create mode 100644 fixtures/web-first/unsupported/svg-filter-lighting-color-inherit.svg create mode 100644 fixtures/web-first/unsupported/svg-filter-lighting-color-syntax.svg create mode 100644 fixtures/web-first/unsupported/svg-filter-lighting-color-var.svg diff --git a/crates/n0/src/drawlist.rs b/crates/n0/src/drawlist.rs index ac3504b8..76ba8ad2 100644 --- a/crates/n0/src/drawlist.rs +++ b/crates/n0/src/drawlist.rs @@ -125,6 +125,22 @@ pub(crate) enum ResolvedFilterConvolveEdgeMode { None, } +#[derive(Debug, Clone, Copy, PartialEq)] +pub(crate) enum ResolvedFilterLightSource { + Distant { + direction: [f32; 3], + }, + Point { + location: [f32; 3], + }, + Spot { + location: [f32; 3], + target: [f32; 3], + falloff_exponent: f32, + cutoff_angle: f32, + }, +} + /// The private filter-operation vocabulary admitted by the painter. #[derive(Debug, Clone, PartialEq)] pub(crate) enum ResolvedFilterPrimitive { @@ -189,6 +205,12 @@ pub(crate) enum ResolvedFilterPrimitive { edge_mode: ResolvedFilterConvolveEdgeMode, preserve_alpha: bool, }, + DiffuseLighting { + surface_scale: f32, + diffuse_constant: f32, + color: n0_model::model::Color, + light: ResolvedFilterLightSource, + }, Merge, } diff --git a/crates/n0/src/glyphless.rs b/crates/n0/src/glyphless.rs index bcd6c168..26e51327 100644 --- a/crates/n0/src/glyphless.rs +++ b/crates/n0/src/glyphless.rs @@ -24,7 +24,7 @@ use n0_model::model::{ use n0_model::path::ResolvedPathArtifact; use rframe::{ ClipPath, FilterBlend, FilterColorSpace, FilterComposite, FilterConvolveEdgeMode, - FilterDisplacementChannel, FilterInput, FilterMorphology, FilterPrimitive, + FilterDisplacementChannel, FilterInput, FilterLightSource, FilterMorphology, FilterPrimitive, FilterTurbulenceKind, Frame, FrameItem, Geometry, MaskMode, PaintStack, ScopeEffect, VisualRef, }; @@ -34,8 +34,8 @@ use crate::drawlist::{ ResolvedClipGeometryKind, ResolvedClipLayer, ResolvedClipPath, ResolvedFilter, ResolvedFilterBlend, ResolvedFilterColorSpace, ResolvedFilterComposite, ResolvedFilterConvolveEdgeMode, ResolvedFilterDisplacementChannel, ResolvedFilterInput, - ResolvedFilterMorphology, ResolvedFilterNode, ResolvedFilterPrimitive, - ResolvedFilterTurbulenceKind, ResolvedMaskMode, StrokeDashPhase, + ResolvedFilterLightSource, ResolvedFilterMorphology, ResolvedFilterNode, + ResolvedFilterPrimitive, ResolvedFilterTurbulenceKind, ResolvedMaskMode, StrokeDashPhase, }; use crate::frame::FrameExecutionError; use crate::paint::PaintCtx; @@ -1054,6 +1054,35 @@ fn compile_filter(filter: &rframe::Filter) -> ResolvedFilter { }, preserve_alpha, }, + FilterPrimitive::DiffuseLighting { + surface_scale, + diffuse_constant, + color, + light, + } => ResolvedFilterPrimitive::DiffuseLighting { + surface_scale, + diffuse_constant, + color: compile_color(color), + light: match light { + FilterLightSource::Distant { direction } => { + ResolvedFilterLightSource::Distant { direction } + } + FilterLightSource::Point { location } => { + ResolvedFilterLightSource::Point { location } + } + FilterLightSource::Spot { + location, + target, + falloff_exponent, + cutoff_angle, + } => ResolvedFilterLightSource::Spot { + location, + target, + falloff_exponent, + cutoff_angle, + }, + }, + }, FilterPrimitive::Merge => ResolvedFilterPrimitive::Merge, }, }) diff --git a/crates/n0/src/paint.rs b/crates/n0/src/paint.rs index bcb69078..85963eff 100644 --- a/crates/n0/src/paint.rs +++ b/crates/n0/src/paint.rs @@ -29,7 +29,7 @@ use skia_safe::{ image::CachingHint, path_effect::PathEffect, shaders, stroke_rec::InitStyle, Blender, Canvas, ClipOp, Color, Color4f, ColorChannel, ColorMatrix, ColorSpace, CubicResampler, Data, Font, ISize, Image, ImageFilter, ImageInfo, Matrix, OpBuilder, Paint, PaintCap, PaintJoin, - PaintStyle, Path, PathBuilder, PathDirection, PathFillType, PathOp, Point, RRect, Rect, + PaintStyle, Path, PathBuilder, PathDirection, PathFillType, PathOp, Point, Point3, RRect, Rect, SamplingOptions, Shader, StrokeRec, }; @@ -37,8 +37,9 @@ use crate::drawlist::{ DrawList, ItemKind, PostPaintOpacity, ResolvedClipGeometry, ResolvedClipGeometryKind, ResolvedClipLayer, ResolvedClipPath, ResolvedFilter, ResolvedFilterBlend, ResolvedFilterColorSpace, ResolvedFilterComposite, ResolvedFilterConvolveEdgeMode, - ResolvedFilterDisplacementChannel, ResolvedFilterInput, ResolvedFilterMorphology, - ResolvedFilterPrimitive, ResolvedFilterTurbulenceKind, ResolvedMaskMode, StrokeDashPhase, + ResolvedFilterDisplacementChannel, ResolvedFilterInput, ResolvedFilterLightSource, + ResolvedFilterMorphology, ResolvedFilterPrimitive, ResolvedFilterTurbulenceKind, + ResolvedMaskMode, StrokeDashPhase, }; /// The gradient family whose local matrix could not be represented by the @@ -2339,6 +2340,34 @@ fn sk_convolve_tile_mode(mode: ResolvedFilterConvolveEdgeMode) -> skia_safe::Til } } +fn sk_lighting_color(color: n0_model::model::Color, space: ResolvedFilterColorSpace) -> Color { + let argb = color.argb(); + let channel = |shift| ((argb >> shift) & 0xff_u32) as u8; + let to_linear_byte = |component: u8| { + let component = f32::from(component) / 255.0; + let linear = if component <= 0.04045 { + component / 12.92 + } else { + ((component + 0.055) / 1.055).powf(2.4) + }; + (linear * 255.0).round() as u8 + }; + let (r, g, b) = (channel(16), channel(8), channel(0)); + match space { + ResolvedFilterColorSpace::Srgb => Color::from_argb(u8::MAX, r, g, b), + ResolvedFilterColorSpace::LinearRgb => Color::from_argb( + u8::MAX, + to_linear_byte(r), + to_linear_byte(g), + to_linear_byte(b), + ), + } +} + +fn sk_point3(point: [f32; 3]) -> Point3 { + Point3::new(point[0], point[1], point[2]) +} + /// Build one checked private filter graph and its final-composition policy. fn build_filter(filter: &ResolvedFilter) -> Result { let explicit_transparent_source = if filter.source_is_transparent { @@ -2419,6 +2448,7 @@ fn build_filter(filter: &ResolvedFilter) -> Result { ColorRestore::Floating }) } + ResolvedFilterPrimitive::DiffuseLighting { .. } => Some(ColorRestore::Default), ResolvedFilterPrimitive::SolidColor { .. } => None, _ => inherited_color_restore, }; @@ -2899,6 +2929,67 @@ fn build_filter(filter: &ResolvedFilter) -> Result { || node.color_space == ResolvedFilterColorSpace::Srgb, ) } + ResolvedFilterPrimitive::DiffuseLighting { + surface_scale, + diffuse_constant, + color, + light, + } => { + let input = inputs + .pop() + .expect("diffuse lighting has one checked input"); + procedural_provenance = false; + procedural_unorm8_blend = false; + let color = sk_lighting_color(color, node.color_space); + let filter = match light { + ResolvedFilterLightSource::Distant { direction } => { + skia_safe::image_filters::distant_lit_diffuse( + sk_point3(direction), + color, + surface_scale, + diffuse_constant, + input.image_filter, + crop, + ) + } + ResolvedFilterLightSource::Point { location } => { + skia_safe::image_filters::point_lit_diffuse( + sk_point3(location), + color, + surface_scale, + diffuse_constant, + input.image_filter, + crop, + ) + } + ResolvedFilterLightSource::Spot { + location, + target, + falloff_exponent, + cutoff_angle, + } => skia_safe::image_filters::spot_lit_diffuse( + sk_point3(location), + sk_point3(target), + falloff_exponent, + cutoff_angle, + color, + surface_scale, + diffuse_constant, + input.image_filter, + crop, + ), + } + .ok_or_else(|| { + "the backend could not construct a diffuse-lighting operation".to_string() + })?; + ( + Some(filter), + node.color_space, + input.source_dependent, + input.requires_exact_restore + || node.color_space == ResolvedFilterColorSpace::Srgb, + ) + } ResolvedFilterPrimitive::Merge => { let mut inputs = inputs.into_iter(); let image_filter = if let Some(first) = inputs.next() { @@ -3000,10 +3091,11 @@ mod filter_policy_tests { use std::sync::Arc; use n0_model::math::RectF; - use n0_model::model::Color32F; + use n0_model::model::{Color as ModelColor, Color32F}; use crate::drawlist::{ - ResolvedFilterConvolveEdgeMode, ResolvedFilterMorphology, ResolvedFilterNode, + ResolvedFilterConvolveEdgeMode, ResolvedFilterLightSource, ResolvedFilterMorphology, + ResolvedFilterNode, }; use super::{ @@ -3277,6 +3369,54 @@ mod filter_policy_tests { .expect("preserved alpha remains a checked native operation"); assert!(alpha_preserving.source_preflatten); } + + #[test] + fn every_checked_diffuse_light_kind_builds_with_its_color_space_policy() { + let lights = [ + ResolvedFilterLightSource::Distant { + direction: [0.5, -0.5, std::f32::consts::FRAC_1_SQRT_2], + }, + ResolvedFilterLightSource::Point { + location: [4.0, 8.0, 12.0], + }, + ResolvedFilterLightSource::Spot { + location: [2.0, 3.0, 8.0], + target: [7.0, 6.0, 0.0], + falloff_exponent: 8.0, + cutoff_angle: 35.0, + }, + ]; + for color_space in [ + ResolvedFilterColorSpace::Srgb, + ResolvedFilterColorSpace::LinearRgb, + ] { + for light in lights { + let filter = ResolvedFilter { + region: REGION, + nodes: Arc::from([ResolvedFilterNode { + inputs: Arc::from([ResolvedFilterInput::SourceAlpha]), + region: REGION, + color_space, + primitive: ResolvedFilterPrimitive::DiffuseLighting { + surface_scale: -2.0, + diffuse_constant: 0.75, + color: ModelColor(0xffff_b347), + light, + }, + }]), + may_paint_transparent_input: true, + source_is_transparent: false, + }; + let built = build_filter(&filter).expect("checked native diffuse light builds"); + assert!(!built.source_preflatten); + assert_eq!( + built.restore_blender.is_some(), + color_space == ResolvedFilterColorSpace::Srgb, + "sRGB lighting uses the architecture-neutral outer restore; gamma conversion ends it" + ); + } + } + } } /// Product-build preflight for a resolved image-filter graph. Replay repeats diff --git a/crates/n0_cli/README.md b/crates/n0_cli/README.md index 993ea3bb..f367c3ec 100644 --- a/crates/n0_cli/README.md +++ b/crates/n0_cli/README.md @@ -259,8 +259,11 @@ cargo run -p n0_cli --bin n0 -- \ authored result names. Its current operations are `feGaussianBlur`, integer `feOffset`, zero-input `feFlood`, all seven `feComposite` operators, all sixteen two-input `feBlend` modes, ordered `feMerge`/`feMergeNode`, - native one-input `feDropShadow`, and one-input `feColorMatrix` and - `feComponentTransfer`, plus one-input `feMorphology`. Inputs + native one-input `feDropShadow`, one-input `feColorMatrix`, + `feComponentTransfer`, `feMorphology`, `feConvolveMatrix`, and + `feDiffuseLighting` with one direct `feDistantLight`, `fePointLight`, or + `feSpotLight` child, plus zero-input `feTurbulence` and two-input + `feDisplacementMap`. Inputs resolve to `SourceGraphic`, `SourceAlpha`, the previous result, or an earlier named result before the frame; unknown values follow Chromium's measured first/previous fallback. @@ -430,6 +433,36 @@ cargo run -p n0_cli --bin n0 -- \ accepted kernel-size strategy through 256 stay admitted. Representative fallback branches are celled; the wider invalid-spelling matrix is measured, not all separately celled. + Diffuse lighting consumes one input's alpha as a height field and carries one + already-resolved distant, point, or spot light. The first recognized direct + light child wins; non-light children are ignored, nested lights do not + participate, and no light produces transparent black. The operation's own + output is opaque across its primitive subregion, including opaque black at + zero diffuse constant. Missing input follows the established first/previous + graph fallback; SourceGraphic and SourceAlpha therefore give the same + illumination for the same source coverage. + `surfaceScale` and `diffuseConstant` carry signed SVG numbers with initial + one; an exactly empty attribute becomes zero, malformed nonempty text uses + the initial, surface height keeps its sign, and a negative diffuse constant + clamps to zero. Distant angles are signed and periodic. Point and spot + coordinates default independently to zero. Under object-box primitive units, + their x/y coordinates use the target axes and z uses the normalized diagonal. + Spot exponent defaults to one and clamps to 1–128. A missing, zero, or + out-of-range cone angle uses the measured 90-degree behavior; an in-range + negative angle equals its positive magnitude. + Direct `lighting-color` carries initial white, admitted sRGB forms, + `currentColor`, reset/invalid fallback, non-inheritance, and ignored authored + alpha. The light channels adapt to the selected filter color space; missing + interpolation is linearRGB and explicit sRGB differs. CSS lighting color, + explicit inheritance, `var()`, and wider color functions refuse by stable + name. General affine target mappings and diffuse output used as the + foreground of `feComposite` `in`/`atop` against a source-derived second input + have two further precision patrols. Axis maps, reflection, exact quarter + turns, other composite operators, blend/merge, neighboring one-input spatial + operations, regions, ``, `viewBox`, stroke and gradient alpha, and target + opacity/clip/mask are Chromium-baked exact. Chromium ignores sampled valid + and invalid `kernelUnitLength` spellings; two cells carry the diffuse drop, + while that shared row and `feSpecularLighting` remain open. Turbulence carries both procedural formulas: the case-sensitive values `turbulence` and `fractalNoise`, one/two-axis non-negative `baseFrequency`, integer `numOctaves` capped at nine, signed `seed`, and the case-sensitive @@ -498,27 +531,34 @@ cargo run -p n0_cli --bin n0 -- \ Initializing Skia before drawlist replay selects the fused AVX2 path on x86. The 700-cell baseline is byte-exact on ARM and hosted x86 without a tolerance. The forty-one-cell convolution rung keeps the complete 741-cell - gate byte-exact on ARM and hosted x86 without a new tolerance. All three - hundred eighty Chromium-baked filter cells are exact on both hosts. + gate byte-exact on ARM and hosted x86 without a new tolerance. The + seventy-one-cell diffuse-lighting rung keeps the complete 812-cell gate + byte-exact without a new tolerance. All four hundred fifty-one + Chromium-baked filter cells are exact. The filter estate contains 26 chassis/blur cells, 60 shadow-graph, 28 native drop-shadow, 27 color-matrix, 32 component-transfer, 38 blend, 37 morphology, - 91 turbulence/displacement, and 41 convolution-rung cells. The complete corpus - contains 741 Chromium-baked cells plus 10 sampled frames, with 146 named + 91 turbulence/displacement, 41 convolution-rung, and 71 diffuse-lighting + cells. The complete corpus contains 812 Chromium-baked cells plus 10 sampled + frames, with 152 named refusal rows. `feFlood`, `feComposite`, `feMerge`, `feMergeNode`, `feDropShadow`, `feColorMatrix`, - `feComponentTransfer`, `feBlend`, - `feMorphology`, `feConvolveMatrix`, `feTurbulence`, `feDisplacementMap`, + `feComponentTransfer`, `feBlend`, `feMorphology`, `feConvolveMatrix`, + `feDiffuseLighting`, `feDistantLight`, `fePointLight`, `feSpotLight`, + `feTurbulence`, `feDisplacementMap`, `feFuncR`, `feFuncG`, `feFuncB`, `feFuncA`, `k1`–`k4`, `amplitude`, `exponent`, `intercept`, `slope`, `tableValues`, blend-only `mode`, `baseFrequency`, `numOctaves`, `seed`, `stitchTiles`, displacement `scale`, `xChannelSelector`, and `yChannelSelector`, `bias`, `divisor`, `edgeMode`, `kernelMatrix`, - convolution `order`, `preserveAlpha`, `targetX`, and `targetY` close; - `feOffset`, `feGaussianBlur`, ``, + convolution `order`, `preserveAlpha`, `targetX`, `targetY`, `azimuth`, + `diffuseConstant`, `elevation`, `limitingConeAngle`, `pointsAtX`, + `pointsAtY`, `pointsAtZ`, and `surfaceScale` close; + `feOffset`, `feGaussianBlur`, `feSpecularLighting`, ``, `filter`, `color-interpolation-filters`, `in`, `in2`, `operator`, `result`, - `radius`, `kernelUnitLength`, `dx`, `dy`, `stdDeviation`, `flood-color`, and - `flood-opacity` remain open for the named precision, applicability, resource, - cascade, or value remainder. + `radius`, `kernelUnitLength`, `lighting-color`, `specularExponent`, `x`, `y`, + `z`, `dx`, `dy`, `stdDeviation`, `flood-color`, and `flood-opacity` remain + open for the named precision, applicability, resource, cascade, or value + remainder. A stroke is centred, its width is a cascaded length in either spelling — numbers, absolute units, `em`/`rem` against an authored or default font-size, percentages against the normalized diagonal, and pure-length diff --git a/crates/rframe/src/filter.rs b/crates/rframe/src/filter.rs index 4d8a12cf..3c15ceba 100644 --- a/crates/rframe/src/filter.rs +++ b/crates/rframe/src/filter.rs @@ -8,7 +8,7 @@ use std::sync::Arc; -use cg::CGColor32F; +use cg::{CGColor, CGColor32F}; use math2::Rectangle; use math2::transform::AffineTransform; @@ -112,6 +112,27 @@ pub enum FilterConvolveEdgeMode { None, } +/// One already-resolved light source for a surface-lighting operation. +/// +/// Source angles and coordinate-unit conventions stop at the producer. The +/// contract carries the direction or three-dimensional points consumed by +/// the image operation, with no element or attribute vocabulary attached. +#[derive(Clone, Copy, Debug, PartialEq)] +pub enum FilterLightSource { + Distant { + direction: [f32; 3], + }, + Point { + location: [f32; 3], + }, + Spot { + location: [f32; 3], + target: [f32; 3], + falloff_exponent: f32, + cutoff_angle: f32, + }, +} + /// Four exact byte lookup tables for one non-premultiplied RGBA operation. /// /// Channel order is named at construction and access, so a producer cannot @@ -236,6 +257,15 @@ pub enum FilterPrimitive { edge_mode: FilterConvolveEdgeMode, preserve_alpha: bool, }, + /// Diffuse illumination derived from one input's alpha height field. + DiffuseLighting { + surface_scale: f32, + diffuse_constant: f32, + /// Opaque resolved sRGB light colour. A painter adapts its channels + /// to the operation's declared interpolation space. + color: CGColor, + light: FilterLightSource, + }, Merge, } @@ -329,6 +359,9 @@ pub enum FilterProgramError { InvalidConvolveMatrix { node: usize, }, + InvalidDiffuseLighting { + node: usize, + }, } impl std::fmt::Display for FilterProgramError { @@ -392,6 +425,10 @@ impl std::fmt::Display for FilterProgramError { f, "filter node {node} has an invalid convolution order, kernel, target, gain, or bias" ), + Self::InvalidDiffuseLighting { node } => write!( + f, + "filter node {node} has an invalid diffuse-light parameter, colour, or light source" + ), } } } @@ -418,7 +455,8 @@ impl FilterProgram { | FilterPrimitive::ColorMatrix { .. } | FilterPrimitive::ComponentTransfer { .. } | FilterPrimitive::Morphology { .. } - | FilterPrimitive::ConvolveMatrix { .. } => Some(1), + | FilterPrimitive::ConvolveMatrix { .. } + | FilterPrimitive::DiffuseLighting { .. } => Some(1), FilterPrimitive::SolidColor { .. } | FilterPrimitive::Turbulence { .. } => Some(0), FilterPrimitive::Composite { .. } | FilterPrimitive::Blend { .. } @@ -530,6 +568,19 @@ impl FilterProgram { { return Err(FilterProgramError::InvalidConvolveMatrix { node: index }); } + FilterPrimitive::DiffuseLighting { + surface_scale, + diffuse_constant, + color, + light, + } if !surface_scale.is_finite() + || !diffuse_constant.is_finite() + || diffuse_constant < 0.0 + || color.a() != u8::MAX + || !valid_light(light) => + { + return Err(FilterProgramError::InvalidDiffuseLighting { node: index }); + } FilterPrimitive::Offset { .. } | FilterPrimitive::SolidColor { .. } | FilterPrimitive::Composite { .. } @@ -541,6 +592,7 @@ impl FilterProgram { | FilterPrimitive::Turbulence { .. } | FilterPrimitive::DisplacementMap { .. } | FilterPrimitive::ConvolveMatrix { .. } + | FilterPrimitive::DiffuseLighting { .. } | FilterPrimitive::Merge => {} } } @@ -572,6 +624,7 @@ impl FilterProgram { preserve_alpha, .. } => !preserve_alpha && bias > 0.0, + FilterPrimitive::DiffuseLighting { .. } => true, FilterPrimitive::GaussianBlur { .. } | FilterPrimitive::Offset { .. } | FilterPrimitive::Composite { .. } @@ -584,6 +637,37 @@ impl FilterProgram { } } +fn valid_light(light: FilterLightSource) -> bool { + match light { + FilterLightSource::Distant { direction } => { + direction.into_iter().all(f32::is_finite) + && direction + .into_iter() + .all(|component| (-1.0..=1.0).contains(&component)) + && direction + .into_iter() + .map(|component| component * component) + .sum::() + > 0.0 + } + FilterLightSource::Point { location } => location.into_iter().all(f32::is_finite), + FilterLightSource::Spot { + location, + target, + falloff_exponent, + cutoff_angle, + } => { + location.into_iter().all(f32::is_finite) + && target.into_iter().all(f32::is_finite) + && falloff_exponent.is_finite() + && (1.0..=128.0).contains(&falloff_exponent) + && cutoff_angle.is_finite() + && cutoff_angle != 0.0 + && (-90.0..=90.0).contains(&cutoff_angle) + } + } +} + /// Why a checked program cannot be applied as one resolved filter effect. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum FilterError { diff --git a/crates/rframe/src/lib.rs b/crates/rframe/src/lib.rs index 7a038f99..ba655af6 100644 --- a/crates/rframe/src/lib.rs +++ b/crates/rframe/src/lib.rs @@ -26,9 +26,9 @@ pub use clip::{ }; pub use filter::{ Filter, FilterBlend, FilterChannelTables, FilterColorSpace, FilterComposite, - FilterConvolveEdgeMode, FilterDisplacementChannel, FilterError, FilterInput, FilterMorphology, - FilterNode, FilterPrimitive, FilterProgram, FilterProgramError, FilterTurbulenceKind, - MAX_FILTER_CONVOLVE_KERNEL_VALUES, MAX_FILTER_NODES, + FilterConvolveEdgeMode, FilterDisplacementChannel, FilterError, FilterInput, FilterLightSource, + FilterMorphology, FilterNode, FilterPrimitive, FilterProgram, FilterProgramError, + FilterTurbulenceKind, MAX_FILTER_CONVOLVE_KERNEL_VALUES, MAX_FILTER_NODES, }; pub use frame::{ Frame, FrameItem, FrameItems, FrameItemsError, FrameNode, Geometry, Identity, MAX_SCOPE_DEPTH, diff --git a/crates/rframe/tests/filter_contract.rs b/crates/rframe/tests/filter_contract.rs index 8fec5d45..1e694be3 100644 --- a/crates/rframe/tests/filter_contract.rs +++ b/crates/rframe/tests/filter_contract.rs @@ -6,9 +6,9 @@ use math2::Rectangle; use math2::transform::AffineTransform; use rframe::{ Filter, FilterBlend, FilterChannelTables, FilterColorSpace, FilterComposite, - FilterConvolveEdgeMode, FilterDisplacementChannel, FilterError, FilterInput, FilterMorphology, - FilterNode, FilterPrimitive, FilterProgram, FilterProgramError, FilterTurbulenceKind, - MAX_FILTER_CONVOLVE_KERNEL_VALUES, MAX_FILTER_NODES, + FilterConvolveEdgeMode, FilterDisplacementChannel, FilterError, FilterInput, FilterLightSource, + FilterMorphology, FilterNode, FilterPrimitive, FilterProgram, FilterProgramError, + FilterTurbulenceKind, MAX_FILTER_CONVOLVE_KERNEL_VALUES, MAX_FILTER_NODES, }; fn blur(input: FilterInput, sigma_x: f32, sigma_y: f32) -> FilterNode { @@ -734,6 +734,124 @@ fn convolution_has_one_input_and_a_bounded_finite_checked_kernel() { } } +#[test] +fn diffuse_lighting_has_one_input_and_a_checked_shared_light_source() { + let region = Rectangle::from_xywh(0.0, 0.0, 10.0, 10.0); + let lighting = |inputs: Arc<[FilterInput]>, surface_scale, diffuse_constant, color, light| { + FilterNode::new( + inputs, + region, + FilterColorSpace::LinearRgb, + FilterPrimitive::DiffuseLighting { + surface_scale, + diffuse_constant, + color, + light, + }, + ) + }; + let distant = FilterLightSource::Distant { + direction: [0.5, -0.5, std::f32::consts::FRAC_1_SQRT_2], + }; + + assert_eq!( + FilterProgram::new(Arc::from([lighting( + Arc::from([]), + 1.0, + 1.0, + cg::CGColor::WHITE, + distant, + )])), + Err(FilterProgramError::InvalidInputCount { + node: 0, + expected: 1, + actual: 0, + }) + ); + + for light in [ + distant, + FilterLightSource::Point { + location: [-4.0, 8.0, 12.0], + }, + FilterLightSource::Spot { + location: [2.0, 3.0, 8.0], + target: [7.0, 6.0, 0.0], + falloff_exponent: 128.0, + cutoff_angle: -35.0, + }, + ] { + let program = FilterProgram::new(Arc::from([lighting( + Arc::from([FilterInput::SourceAlpha]), + -3.0, + 0.0, + cg::CGColor::from_rgb(0x25, 0x63, 0xeb), + light, + )])) + .expect("a finite diffuse operation with any resolved light kind is admitted"); + assert!(program.may_paint_transparent_input()); + } + + for node in [ + lighting( + Arc::from([FilterInput::Source]), + f32::INFINITY, + 1.0, + cg::CGColor::WHITE, + distant, + ), + lighting( + Arc::from([FilterInput::Source]), + 1.0, + -1.0, + cg::CGColor::WHITE, + distant, + ), + lighting( + Arc::from([FilterInput::Source]), + 1.0, + 1.0, + cg::CGColor::from_rgba(255, 255, 255, 128), + distant, + ), + lighting( + Arc::from([FilterInput::Source]), + 1.0, + 1.0, + cg::CGColor::WHITE, + FilterLightSource::Distant { + direction: [0.0, 0.0, 0.0], + }, + ), + lighting( + Arc::from([FilterInput::Source]), + 1.0, + 1.0, + cg::CGColor::WHITE, + FilterLightSource::Point { + location: [0.0, f32::NAN, 0.0], + }, + ), + lighting( + Arc::from([FilterInput::Source]), + 1.0, + 1.0, + cg::CGColor::WHITE, + FilterLightSource::Spot { + location: [0.0, 0.0, 1.0], + target: [0.0, 0.0, 0.0], + falloff_exponent: 129.0, + cutoff_angle: 0.0, + }, + ), + ] { + assert_eq!( + FilterProgram::new(Arc::from([node])), + Err(FilterProgramError::InvalidDiffuseLighting { node: 0 }) + ); + } +} + #[test] fn a_filter_invocation_names_when_its_source_is_fully_transparent() { let region = Rectangle::from_xywh(0.0, 0.0, 10.0, 10.0); diff --git a/crates/websem/src/svg.rs b/crates/websem/src/svg.rs index 6495107f..c2124cb6 100644 --- a/crates/websem/src/svg.rs +++ b/crates/websem/src/svg.rs @@ -137,7 +137,7 @@ use math2::transform::AffineTransform; use rframe::{ ClipGeometry, ClipLayer, ClipPath, FillRule, Filter, FilterBlend, FilterChannelTables, FilterColorSpace, FilterComposite, FilterConvolveEdgeMode, FilterDisplacementChannel, - FilterInput, FilterMorphology, FilterNode, FilterPrimitive, FilterProgram, + FilterInput, FilterLightSource, FilterMorphology, FilterNode, FilterPrimitive, FilterProgram, FilterTurbulenceKind, Frame, FrameItem, FrameItems, FrameItemsError, FrameNode, Geometry, Identity, MAX_FILTER_CONVOLVE_KERNEL_VALUES, Mask, MaskMode, PaintAlphaFactor, PaintStack, PathData, Provenance, Scope, ScopeEffect, ScopeOpacity, Stroke, StrokeCap, StrokeDash, @@ -4941,6 +4941,209 @@ mod filter_resource { }) } + /// One lighting-family SVGAnimatedNumber value as Chromium 149 exposes + /// it. An exactly empty attribute is the animated-number zero; ASCII + /// whitespace-only and every other malformed spelling use the field's + /// initial value. + fn lighting_number(element: HtmlElement<'_>, name: &str, initial: f32) -> f32 { + if get_attr(element, name).as_deref() == Some("") { + 0.0 + } else { + svg_number(element, name, initial) + } + } + + fn patrol_lighting_style(element: HtmlElement<'_>, owner: &str) -> Result<(), CompileError> { + let Some(style) = get_attr(element, "style") else { + return Ok(()); + }; + if style.contains('\\') { + return Err(CompileError::UnsupportedFilter(format!( + "inline style on <{owner}> contains a CSS escape; property identity cannot be proven by the direct decoder" + ))); + } + if css_declares_property(&style, "lighting-color") { + return Err(CompileError::UnsupportedFilter(format!( + "CSS lighting-color on <{owner}> is not represented by the pinned cascade; its direct presentation attribute is a separate ingress" + ))); + } + Ok(()) + } + + fn lighting_color(element: HtmlElement<'_>, owner: &str) -> Result { + let absolute = match get_attr(element, "lighting-color") { + None => AbsoluteColor::WHITE, + Some(raw) => { + let lowered = raw.to_ascii_lowercase(); + let trimmed = trim_svg_whitespace(&lowered); + if lowered.contains("var(") { + return Err(CompileError::UnsupportedFilter(format!( + "{owner} lighting-color resolves through var(), whose substitution is not represented at this Stylo pin" + ))); + } + if trimmed == "inherit" { + return Err(CompileError::UnsupportedFilter(format!( + "{owner} lighting-color uses inherit, which needs the unavailable cascaded lighting-color longhand" + ))); + } + if matches!(trimmed, "initial" | "unset" | "revert" | "revert-layer") { + AbsoluteColor::WHITE + } else { + match parse_color_attribute(&raw) { + Some(ParsedColorAttribute::Absolute(color)) => color, + Some(ParsedColorAttribute::CurrentColor) => element + .borrow_data() + .map(|data| data.styles.primary().clone_color()) + .unwrap_or(AbsoluteColor::WHITE), + Some(ParsedColorAttribute::BeyondSlice(reason)) => { + return Err(CompileError::UnsupportedFilter(format!( + "{owner} lighting-color is outside the admitted color slice: {reason}" + ))); + } + // An invalid presentation hint contributes initial white. + None => AbsoluteColor::WHITE, + } + } + } + }; + let color = admitted_srgb(absolute, 1.0).map_err(|reason| { + CompileError::UnsupportedFilter(format!( + "{owner} lighting-color is outside the admitted color slice: {reason}" + )) + })?; + // Blink adapts only RGB into the operation space. Authored color + // alpha has no effect on either lighting primitive. + Ok(CGColor::from_rgb(color.r(), color.g(), color.b())) + } + + fn lighting_point( + element: HtmlElement<'_>, + units: Units, + target_box: Rectangle, + x_name: &str, + y_name: &str, + z_name: &str, + ) -> [f32; 3] { + let x = lighting_number(element, x_name, 0.0); + let y = lighting_number(element, y_name, 0.0); + let z = lighting_number(element, z_name, 0.0); + match units { + Units::UserSpaceOnUse => [x, y, z], + Units::ObjectBoundingBox => { + // Blink's Resolve3dPoint uses the normalized diagonal for Z, + // with this exact float operation order. + let z_basis = ((target_box.width * target_box.width + + target_box.height * target_box.height) + / 2.0) + .sqrt(); + [ + target_box.x + x * target_box.width, + target_box.y + y * target_box.height, + z * z_basis, + ] + } + } + } + + fn diffuse_light_source( + primitive: HtmlElement<'_>, + primitive_units: Units, + target_box: Rectangle, + override_skips: &HashMap, + ) -> Result, CompileError> { + let mut child = primitive.first_element_child(); + while let Some(candidate) = child { + child = candidate.next_element_sibling(); + let tag = candidate.local_name_string(); + if !matches!( + tag.as_str(), + "feDistantLight" | "fePointLight" | "feSpotLight" + ) { + continue; + } + if let Some(reason) = override_skips.get(&candidate.node_id()) { + return Err(CompileError::UnsupportedFilter(format!( + "the <{tag}> authored state is overridden at document load: {reason}" + ))); + } + let light = match tag.as_str() { + "feDistantLight" => { + let radians = |degrees: f32| degrees * (std::f32::consts::PI / 180.0); + let azimuth = radians(lighting_number(candidate, "azimuth", 0.0)); + let elevation = radians(lighting_number(candidate, "elevation", 0.0)); + FilterLightSource::Distant { + direction: [ + azimuth.cos() * elevation.cos(), + azimuth.sin() * elevation.cos(), + elevation.sin(), + ], + } + } + "fePointLight" => FilterLightSource::Point { + location: lighting_point(candidate, primitive_units, target_box, "x", "y", "z"), + }, + "feSpotLight" => { + let limiting_cone_angle = lighting_number(candidate, "limitingConeAngle", 0.0); + FilterLightSource::Spot { + location: lighting_point( + candidate, + primitive_units, + target_box, + "x", + "y", + "z", + ), + target: lighting_point( + candidate, + primitive_units, + target_box, + "pointsAtX", + "pointsAtY", + "pointsAtZ", + ), + falloff_exponent: lighting_number(candidate, "specularExponent", 1.0) + .clamp(1.0, 128.0), + cutoff_angle: if limiting_cone_angle == 0.0 + || !(-90.0..=90.0).contains(&limiting_cone_angle) + { + 90.0 + } else { + limiting_cone_angle + }, + } + } + _ => unreachable!("recognized light tag"), + }; + let finite = match light { + FilterLightSource::Distant { direction } => { + direction.into_iter().all(f32::is_finite) + } + FilterLightSource::Point { location } => location.into_iter().all(f32::is_finite), + FilterLightSource::Spot { + location, + target, + falloff_exponent, + cutoff_angle, + } => { + location.into_iter().all(f32::is_finite) + && target.into_iter().all(f32::is_finite) + && falloff_exponent.is_finite() + && cutoff_angle.is_finite() + } + }; + if !finite { + // Chromium's native lighting builder contributes transparent + // black when a finite authored number overflows during + // object-box point resolution. State that image explicitly; + // never let a backend construction failure become an + // unfiltered fallback. + return Ok(None); + } + return Ok(Some(light)); + } + Ok(None) + } + fn composite_operator(element: HtmlElement<'_>) -> FilterComposite { match get_attr(element, "operator") .as_deref() @@ -5790,6 +5993,15 @@ mod filter_resource { axis_or_quarter_turn && [a, b, c, d].into_iter().all(f32::is_finite) } + /// Native lighting agrees for translations, axis maps, reflections, and + /// exact quarter turns. General rotations and shears change the pinned + /// backend's mapped height-field sampling by observable channel values. + fn diffuse_lighting_mapping_is_admitted(target_to_frame: AffineTransform) -> bool { + let [[a, c, _], [b, d, _]] = target_to_frame.matrix; + let axis_or_quarter_turn = (b == 0.0 && c == 0.0) || (a == 0.0 && d == 0.0); + axis_or_quarter_turn && [a, b, c, d].into_iter().all(f32::is_finite) + } + fn filter_crosses_clip_path(target: HtmlElement<'_>) -> Result { let mut current = Some(target); while let Some(element) = current { @@ -6056,6 +6268,35 @@ mod filter_resource { ), } } + "feDiffuseLighting" => { + patrol_color_style(element)?; + patrol_lighting_style(element, "feDiffuseLighting")?; + match diffuse_light_source( + element, + primitive_units, + target_box, + override_skips, + )? { + Some(light) => ( + vec![resolve_input(element, "in", previous, &names)], + FilterPrimitive::DiffuseLighting { + surface_scale: lighting_number(element, "surfaceScale", 1.0), + diffuse_constant: lighting_number(element, "diffuseConstant", 1.0) + .max(0.0), + color: lighting_color(element, "feDiffuseLighting")?, + light, + }, + ), + // A lighting primitive without one recognized direct + // light child contributes transparent black. + None => ( + Vec::new(), + FilterPrimitive::SolidColor { + color: CGColor32F::TRANSPARENT, + }, + ), + } + } "feMerge" => { patrol_color_style(element)?; let mut inputs = Vec::new(); @@ -6197,9 +6438,12 @@ mod filter_resource { let mut has_turbulence = false; let mut has_displacement_map = false; let mut has_convolve_matrix = false; + let mut has_diffuse_lighting = false; + let mut has_diffuse_lighting_composition_boundary = false; let mut has_source_dependent_morphology = false; let mut has_source_dependent_active_morphology = false; let mut has_source_dependent_convolve_matrix = false; + let mut lighting_dependencies = Vec::with_capacity(nodes.len()); for node in &nodes { let source_dependent = node.inputs().iter().any(|input| match *input { FilterInput::Source | FilterInput::SourceAlpha => true, @@ -6237,7 +6481,30 @@ mod filter_resource { has_convolve_matrix = true; has_source_dependent_convolve_matrix |= source_dependent; } + let lighting_dependent = + matches!(node.primitive(), FilterPrimitive::DiffuseLighting { .. }) + || node.inputs().iter().any(|input| match *input { + FilterInput::Source | FilterInput::SourceAlpha => false, + FilterInput::Node(index) => lighting_dependencies[index], + }); + has_diffuse_lighting |= + matches!(node.primitive(), FilterPrimitive::DiffuseLighting { .. }); + if matches!( + node.primitive(), + FilterPrimitive::Composite { + operator: FilterComposite::In | FilterComposite::Atop + } + ) && node.inputs().first().is_some_and(|input| match *input { + FilterInput::Source | FilterInput::SourceAlpha => false, + FilterInput::Node(index) => lighting_dependencies[index], + }) && node.inputs().get(1).is_some_and(|input| match *input { + FilterInput::Source | FilterInput::SourceAlpha => true, + FilterInput::Node(index) => source_dependencies[index], + }) { + has_diffuse_lighting_composition_boundary = true; + } source_dependencies.push(source_dependent); + lighting_dependencies.push(lighting_dependent); } if has_blend { if !blend_mapping_is_admitted(target_to_frame) { @@ -6283,6 +6550,18 @@ mod filter_resource { .to_string(), )); } + if has_diffuse_lighting && !diffuse_lighting_mapping_is_admitted(target_to_frame) { + return Err(CompileError::UnsupportedFilter( + "feDiffuseLighting's target mapping crosses the pinned-backend lighting-filter transform precision boundary" + .to_string(), + )); + } + if has_diffuse_lighting_composition_boundary { + return Err(CompileError::UnsupportedFilter( + "feDiffuseLighting as the foreground of feComposite in/atop against a source-derived second input crosses the pinned-backend lighting-composition precision boundary" + .to_string(), + )); + } if has_source_dependent_convolve_matrix && filter_source_has_paint_server(target)? { return Err(CompileError::UnsupportedFilter( "feConvolveMatrix's source image crosses the pinned-backend convolution-filter paint-server precision boundary" diff --git a/crates/websem/tests/unsupported_corpus.rs b/crates/websem/tests/unsupported_corpus.rs index b73977ff..28a39252 100644 --- a/crates/websem/tests/unsupported_corpus.rs +++ b/crates/websem/tests/unsupported_corpus.rs @@ -200,6 +200,16 @@ const CORPUS: &[(&str, Departure, &str)] = &[ DeclaredByBestEffort, "displacement-filter transform precision boundary", ), + ( + "svg-filter-diffuse-composition-precision", + DeclaredByBestEffort, + "lighting-composition precision boundary", + ), + ( + "svg-filter-diffuse-transform-precision", + DeclaredByBestEffort, + "lighting-filter transform precision boundary", + ), ( "svg-filter-effect-stack-precision", DeclaredByBestEffort, @@ -237,6 +247,26 @@ const CORPUS: &[(&str, Departure, &str)] = &[ "small-kernel precision boundary", ), ("svg-filter-href", DeclaredByBestEffort, "href inheritance"), + ( + "svg-filter-lighting-color-css", + DeclaredByBestEffort, + "CSS lighting-color", + ), + ( + "svg-filter-lighting-color-inherit", + DeclaredByBestEffort, + "lighting-color uses inherit", + ), + ( + "svg-filter-lighting-color-syntax", + DeclaredByBestEffort, + "lighting-color is outside the admitted color slice", + ), + ( + "svg-filter-lighting-color-var", + DeclaredByBestEffort, + "lighting-color resolves through var()", + ), ( "svg-filter-list", DeclaredByBestEffort, diff --git a/docs/wg/consolidation/svg-engine-of-record.md b/docs/wg/consolidation/svg-engine-of-record.md index 7433f9e0..03b7a21c 100644 --- a/docs/wg/consolidation/svg-engine-of-record.md +++ b/docs/wg/consolidation/svg-engine-of-record.md @@ -67,9 +67,9 @@ from the dated addenda below: modes, ordered `feMerge`/`feMergeNode`, native one-input `feDropShadow`, one-input `feColorMatrix`, one-input `feComponentTransfer` with its direct `feFuncR`/`feFuncG`/`feFuncB`/`feFuncA` children, and one-input - `feMorphology` and `feConvolveMatrix`, plus zero-input `feTurbulence` and - two-input - `feDisplacementMap`; graph inputs resolve from + `feMorphology`, `feConvolveMatrix`, and `feDiffuseLighting` with one direct + `feDistantLight`, `fePointLight`, or `feSpotLight` child, plus zero-input + `feTurbulence` and two-input `feDisplacementMap`; graph inputs resolve from `SourceGraphic`/`SourceAlpha`/prior and named results, with both filter coordinate systems and color spaces, hard regions, nesting, admitted transforms, ``, and the established effect order; @@ -77,14 +77,14 @@ from the dated addenda below: the full `preserveAspectRatio` grammar; and one exact-time `` on a top-level ``. `crates/n0_cli/README.md` is the statement of record. -- **The corpus** is 741 Chromium-baked primitive cells plus 10 sampled frames. +- **The corpus** is 812 Chromium-baked primitive cells plus 10 sampled frames. All byte-exact except seven curved cells carrying a declared, geometrically confined tolerance (the native-oval/conic boundary) and four gradient cells carrying a declared one-code-value ramp-quantization tolerance (one pixel against Chromium's Skia; 18 knife-edge pixels between this engine's own macOS and Linux Skia builds; 336 ramp pixels under an isolated layer's restore; 576 after a masked ramp becomes luminance alpha). The named refusal - register has 146 rows. + register has 152 rows. - **Not claimed:** no conformance score exists or may be computed — FLIP is unratified. The FLIP record and identity-changing review are prepared, but only the owner act on gridaco/nothing#49 may authorize them and the first @@ -3658,3 +3658,110 @@ primitive corpus moves from 700 to 741 cells; the ten exact-time sampled frames are unchanged. Exactly nine checklist rows tick: the element and eight attributes named above. This records no conformance score and takes no FLIP action. + +## Rung: `feDiffuseLighting` and the light-source family (2026-08-27) + +The verdict is CLOSE/SPLIT. ``, ``, +``, and `` close for their complete static +Chromium behavior. Eight element-specific attribute rows close with them: +`azimuth`, `diffuseConstant`, `elevation`, `limitingConeAngle`, `pointsAtX`, +`pointsAtY`, `pointsAtZ`, and `surfaceScale`. The shared `x`, `y`, `z`, +`specularExponent`, `kernelUnitLength`, `lighting-color`, `in`, `result`, +primitive-region, color-space, filter-resource, and dynamics rows remain open +for their wider applicability or independently named value/cascade remainder. +`` remains unsupported; no CSS property row closes. + +Chromium 149.0.7827.55 establishes diffuse illumination from one input image's +alpha field. Missing `in` follows the established first/previous graph rule, +and SourceGraphic and SourceAlpha are identical because source RGB does not +enter the operation. The result is opaque throughout its primitive subregion, +including opaque black where the diffuse coefficient is zero; a primitive +without a recognized direct light child instead contributes transparent +black. Non-light children are skipped, nested lights do not participate, and +the first recognized direct `feDistantLight`, `fePointLight`, or `feSpotLight` +child wins. + +`surfaceScale` and `diffuseConstant` carry one signed SVG number with initial +one. For this animated-number family an exactly empty attribute becomes zero, +while whitespace-only and malformed text use the initial; leading plus, +exponent, and the measured trailing-comma prefix are accepted. +`surfaceScale` remains signed. A negative diffuse constant clamps to zero. +The three light-source coordinates and the three spot targets carry the same +one-number grammar with initial zero. Distant azimuth and elevation are signed +and periodic. Spot exponent defaults to one and clamps to the inclusive +1–128 range; its shared attribute row stays open because the same name also +applies to specular lighting. A missing or zero cone angle, or one outside the +inclusive -90–90 range, selects the backend's 90-degree behavior. Within that +range a negative angle is pixel-identical to its positive magnitude. A spot +whose position equals its target retains Chromium's native degenerate result. + +User-space point coordinates pass through directly. Under object-box primitive +units, x and y map against the target box's independent axes and z maps against +the normalized diagonal, `sqrt((width² + height²) / 2)`. Spot positions and +targets use that same three-dimensional map. Exact controls cover non-square +boxes, negative coordinates, non-uniform `viewBox` mapping, axis transforms, +reflection, exact quarter turns, ``, stroke geometry, gradient alpha, and +target opacity, clip, and mask. A finite authored object-box coordinate whose +mapping overflows produces Chromium's transparent operation result rather than +an unfiltered fallback; that boundary is committed exact. + +The direct `lighting-color` subset has initial white, is not inherited by +default, admits the established sRGB color forms and `currentColor`, treats an +invalid or reset spelling as the initial, and ignores authored color alpha +while retaining its RGB channels. Missing filter interpolation equals +linearRGB; explicit sRGB is visibly distinct. The operation adapts the light +channels into that selected space before illumination. Explicit inheritance, +CSS-authored `lighting-color`, custom-property substitution, and wider color +functions are all honored by Chromium and now refuse by four focused stable +names. Those independently listed cascade, custom-property, and color-family +gaps—plus the still-open specular applicability—keep the `lighting-color` +presentation-attribute row open. The CSS property twin is unavailable in the +pinned Servo-mode cascade, and no matcher is added around it. + +Current Chromium ignores every sampled `kernelUnitLength` spelling on diffuse +lighting: positive one- and two-axis numbers, fractions, zero, negative, +malformed text, units, percentages, CSS math, custom properties, and CSS-wide +keywords all leave a discriminating surface unchanged. The same drop reproduced +on sampled specular-lighting controls. Two diffuse cells commit a valid and an +invalid drop, but `kernelUnitLength` remains open until the specular primitive +itself is admitted. This follows the browser-drop precedent established by +[gridaco/nothing#77](https://github.com/gridaco/nothing/pull/77). + +The numeric crux was measured instead of inferred. Source decimals around the +binary32 midpoint, adjacent finite extrema, subnormals, underflow, parser +overflow fallback, and huge signed angles all reproduce Chromium through the +shared ordered SVG-number evaluator. At this 64×64 amplification, the midpoint +witness and both adjacent controls happen to be pixel-identical, so no new +numeric patrol was invented from a non-discriminating raster. This is a +negative probe verdict, not a proof that no larger raster can expose another +alias (measured, not celled). + +Two silent backend classes remain and are now named. General target rotation +changed 551 pixels at maximum channel delta 15, a shear changed 543 at delta +12, and a sampled affine map changed 624 at delta 12. Translation, arbitrary +sampled axis maps, reflection, and exact quarter turns are exact. Separately, +using diffuse lighting as the foreground of `feComposite` `in` or `atop` +against a source-derived second input changed 69 pixels at maximum delta 180. +The other composite operators, arithmetic composition, blend, merge, +generated-background composition, lighting in the second input, and adjacent +one-input spatial operations are exact. Two focused refusal fixtures guard +those boundaries in strict and best-effort admission (measured, not celled). + +Six twice-deterministic scratch matrices exercised 236 sources across grammar, +light selection, operation semantics, color, units, graph composition, +transforms, extremes, and `kernelUnitLength`. Every candidate rendered through +the actual command path. After the named patrols, 217 candidates are +pixel-exact and admission-identical; the remaining 19 reach one of the new or +already-established stable names. Seventy-one cells entered only through +`just add`; all are Chromium-baked and exact without a tolerance. + +Gate sensitivity was proved by temporarily halving the resolved diffuse +coefficient in the painter. `just gate` rejected 61 of the new cells, with up +to all 4,096 pixels changed and maximum channel delta 128. Restoring the +coefficient returned the complete 812-cell gate to green. + +Six focused rows join the refusal register, moving it from 146 to 152. The +primitive corpus moves from 741 to 812 cells; the ten exact-time sampled frames +are unchanged. Exactly twelve checklist rows tick: the four elements and eight +attributes named above. This records no conformance score and takes no FLIP +action. diff --git a/docs/wg/consolidation/web-checklist.md b/docs/wg/consolidation/web-checklist.md index 2fd1843f..07e9edba 100644 --- a/docs/wg/consolidation/web-checklist.md +++ b/docs/wg/consolidation/web-checklist.md @@ -654,9 +654,9 @@ excluded. > separate unresolved operation grammar. Authored declarations are therefore > quarantined by name rather than matched by a second cascade. The other four > filter-effect properties are Gecko-only at this Stylo pin and also remain -> open. The direct `feFlood` attribute route now carries an admitted subset, -> but it does not create a CSS computed-value route and does not change these -> property rows. +> open. The direct `feFlood` and `feDiffuseLighting` attribute routes now carry +> admitted subsets, but neither creates a CSS computed-value route or changes +> these property rows. ### Compositing and blending @@ -1468,9 +1468,9 @@ for attributes the platform ships ahead of the SVG 2 indexes. > up to 2,814 pixels and maximum channel delta 250; restoration returns the > gate to green. The shared graph, region, interpolation, filter-resource, and > dynamics rows remain open. -- [ ] `` +- [x] `` - [x] `` -- [ ] `` +- [x] `` - [x] `` - [x] `` - [x] `` @@ -1520,9 +1520,24 @@ for attributes the platform ships ahead of the SVG 2 indexes. > zero radius and later color-space conversion retain their prior paths. The > complete 609-cell gate is exact on ARM and hosted x86 without tolerance. - [ ] `` -- [ ] `` +- [x] `` - [ ] `` -- [ ] `` +- [x] `` + +> **2026-08-27 close/split:** `feDiffuseLighting` reads one input alpha field +> and closes with all three direct light kinds. The first recognized direct +> light child wins; non-light children are skipped, nested lights do not +> participate, and no light produces transparent black. Exact cells cover +> distant, point, and spot illumination; opaque output alpha; signed surface +> height; object-box x/y/normalized-diagonal-z mapping; both filter color +> spaces; graph inputs; hard regions; ``, `viewBox`, stroke and gradient +> alpha; target effects; safe transforms; and neighboring filter operations. +> General affine mappings and one narrow `feComposite` foreground placement +> refuse by stable precision names. Seventy-one exact cells move the complete +> gate to 812. Halving the diffuse coefficient makes sixty-one of them fail, +> up to all 4,096 pixels and maximum channel delta 128; restoration returns +> the gate to green. `feSpecularLighting` remains open behind the advanced +> transactional primitive witness. - [ ] `` - [x] `` @@ -1808,6 +1823,16 @@ for attributes the platform ships ahead of the SVG 2 indexes. - [ ] `image-rendering` - [ ] `letter-spacing` - [ ] `lighting-color` + +> **2026-08-27 split:** direct `lighting-color` on admitted diffuse lighting +> carries initial white, the admitted sRGB color subset, `currentColor`, reset +> and invalid fallback, non-inheritance, and Chromium's rule that light-color +> alpha is ignored. Missing filter interpolation is linearRGB and explicit +> sRGB remains distinct. Explicit inheritance, CSS ingress, `var()`, and wider +> color functions refuse by four stable names under their independently +> listed rows. The presentation-attribute row also applies to the still-open +> specular primitive, so it does not tick; its CSS property twin is absent at +> the pinned cascade and stays separately open. - [ ] `marker-end` - [ ] `marker-mid` - [ ] `marker-start` @@ -1926,7 +1951,7 @@ for attributes the platform ships ahead of the SVG 2 indexes. - [ ] `aria-valuenow` - [ ] `aria-valuetext` - [ ] `autofocus` -- [ ] `azimuth` +- [x] `azimuth` - [x] `baseFrequency` > **2026-08-26 close:** `baseFrequency` applies only to `feTurbulence` and @@ -1955,7 +1980,7 @@ for attributes the platform ships ahead of the SVG 2 indexes. - [ ] `crossorigin` - [ ] `data-*` - [ ] `decoding` -- [ ] `diffuseConstant` +- [x] `diffuseConstant` - [x] `divisor` - [ ] `download` - [ ] `dx` @@ -1967,7 +1992,7 @@ for attributes the platform ships ahead of the SVG 2 indexes. > invalid spelling select `duplicate`. The attribute's other listed > applicability is blur, where current Chromium drops all spellings; one > committed drop cell records that browser behavior. -- [ ] `elevation` +- [x] `elevation` - [x] `exponent` - [ ] `fetchpriority` - [x] `filterUnits` @@ -2006,12 +2031,13 @@ for attributes the platform ships ahead of the SVG 2 indexes. > Missing, malformed, non-finite, or wrong-count matrices produce the measured > transparent result. Kernels at the measured native strategy boundaries—28, > 29, 64, 65, and 256 coefficients—are exact; 257 coefficients produce the -> celled Chromium drop. `kernelUnitLength` stays open: Chromium ignores every -> sampled valid and invalid spelling on convolution, while the attribute also -> applies to the still-open lighting primitives. +> celled Chromium drop. Current Chromium also ignores every sampled valid and +> invalid spelling on diffuse lighting, with valid and invalid drop cells, and +> sampled specular controls reproduce that result. `kernelUnitLength` stays +> open until the specular primitive itself is admitted. - [ ] `lang` - [ ] `lengthAdjust` -- [ ] `limitingConeAngle` +- [x] `limitingConeAngle` - [ ] `markerHeight` - [ ] `markerUnits` - [ ] `markerWidth` @@ -2136,9 +2162,9 @@ for attributes the platform ships ahead of the SVG 2 indexes. - [ ] `ping` - [ ] `playbackorder` - [ ] `points` -- [ ] `pointsAtX` -- [ ] `pointsAtY` -- [ ] `pointsAtZ` +- [x] `pointsAtX` +- [x] `pointsAtY` +- [x] `pointsAtZ` - [x] `preserveAlpha` > **2026-08-27 close:** the complete case-sensitive `false | true` grammar is @@ -2186,7 +2212,22 @@ for attributes the platform ships ahead of the SVG 2 indexes. > invalid, wrong-case, whitespace-padded, and CSS-wide spellings select the > initial `noStitch`; stitched fractional primitive regions are Chromium-baked. - [ ] `style` -- [ ] `surfaceScale` +- [x] `surfaceScale` + +> **2026-08-27 close/split:** the eight diffuse/light-only attributes tick at +> their complete signed SVG-number behavior. `surfaceScale` and +> `diffuseConstant` have initial one; an exactly empty attribute becomes zero, +> while whitespace-only or malformed text takes the initial. Surface height +> keeps its sign and a negative diffuse constant clamps to zero. Azimuth and +> elevation are signed and periodic. Spot targets default independently to +> zero. `limitingConeAngle` uses the measured 90-degree behavior when missing, +> zero, or outside ±90; a negative in-range angle equals its positive +> magnitude. Leading plus, exponent, trailing-comma prefix, finite extremes, +> underflow, and overflow fallback were measured across the family. The wider +> invalid-spelling matrix is measured, not all separately celled. Shared +> `x`/`y`/`z` remain open for their other element applicability, and +> `specularExponent` remains open for `feSpecularLighting` even though the spot +> light's initial one and inclusive 1–128 clamp are carried. - [ ] `systemLanguage` - [ ] `tabindex` - [x] `tableValues` diff --git a/fixtures/web-first/README.md b/fixtures/web-first/README.md index 8651abaf..61abdf2f 100644 --- a/fixtures/web-first/README.md +++ b/fixtures/web-first/README.md @@ -226,6 +226,11 @@ is exactly what the engine renders pixel-for-pixel. | `svg-filter-convolve-{source-alpha,source-alpha-preserve,color-default,color-auto,color-linear,color-srgb,primitive-units,region-crop,input-previous,result-reuse,generated-input,blur-before,morphology-after}.svg` | Alpha, color, graph, and operation evidence: convolved versus preserved SourceAlpha, default linearRGB and explicit `auto`/sRGB/linearRGB, object-box units, hard crops, previous and named result routing, generated input, and ordering around blur and morphology. All thirteen are byte-exact. | | `svg-filter-convolve-{source-path,source-stroke,source-group,use,viewbox,axis-fractional,quarter-turn,target-opacity,target-clip,target-mask}.svg` | Source and composition evidence: direct path, stroke, and group images; `` and non-uniform `viewBox`; safe fractional axis mapping and exact quarter turn; and filter ordering with target opacity, geometric clip, and mask. The binary-mask control is byte-identical to explicit filter-then-mask nesting, differs from the reversed order by 75 pixels at maximum channel delta 99, and differs from no mask by 444 pixels at maximum delta 204. All ten are byte-exact. | | *(measured, not celled — convolution split)* | Four twice-deterministic Chromium 149 matrices probed grammar, operation semantics, numeric and native-strategy boundaries, source classes, transforms, graph routing, and effect order. Every candidate also rendered through both actual CLI admissions; process success was never treated as pixel proof. After the three patrols below, every admitted candidate is exact and admission-identical. Current Chromium ignores every sampled valid and invalid `kernelUnitLength` spelling. The amplified coefficient `1.000000059604644775390625000000000000000000000001` selects the upper adjacent binary32 value; the shared ordered source-number route is exact. The default divisor uses ordered binary32 summation. General target rotation and shear differ by 462px/Δ15 and 632px/Δ13; source-dependent linear/radial gradient fills and a gradient stroke differ by 1,425px/Δ7, 1,658px/Δ7, and 609px/Δ7. A valid divisor of `1e-45` has a non-finite reciprocal in the resolved arithmetic domain and refuses by its own narrow name. Axis maps, fractional translation/scale, reflection, exact quarter turns, generated input, accepted kernels through 256, ordered sum overflow, and large finite bias are exact. Removing kernel reversal made eleven cells fail: the dedicated witness changed 230px/Δ202, and failures reached 2,814px with maximum Δ250. Restoration returned the complete 741-cell gate to green. The corpus is now 741 cells plus 10 sampled frames, the filter estate has 380 cells, and the named register has 146 rows. | +| `svg-filter-diffuse-{distant,distant-angle-default,distant-angle-large,distant-azimuth-negative,distant-elevation-negative,point,point-x-negative,point-y-negative,point-z-negative,spot,spot-target-x,spot-target-y,spot-target-z,spot-exponent-default,spot-exponent-lower-clamp,spot-exponent-upper-clamp,spot-cone-default,spot-cone-active,spot-cone-negative,spot-cone-outside,spot-degenerate,missing-light,child-order,nested-light,nonlight-child}.svg` | Light selection and the complete element-specific light grammar: all three light kinds, signed/large distant angles, independent signed point and spot coordinates, spot exponent clamping, cone behavior, the degenerate spot, first-direct-child selection, skipped non-light children, ignored nesting, and transparent output without a light. All twenty-five are byte-exact. | +| `svg-filter-diffuse-{constant-default,constant-empty-zero,constant-zero,constant-negative-clamp,constant-number-plus,constant-number-exponent,surface-default,surface-empty-zero,surface-zero,surface-negative,surface-number-plus,surface-number-exponent,surface-max,object-box-overflow}.svg` | Diffuse scalar and extreme arithmetic evidence: initial versus exact-empty zero, explicit zero, signed surface height, non-negative diffuse coefficient, leading-plus/exponent grammar, maximum finite height, and the transparent result when a finite object-box point overflows during mapping. All fourteen are byte-exact. | +| `svg-filter-diffuse-{light-color-default,light-color-rgb,light-color-alpha-ignored,light-color-currentcolor,light-color-srgb-function,light-color-invalid,light-color-transparent,color-linear,color-srgb,input-default,input-source-alpha,input-source-graphic,output-alpha,region-percent,point-primitive-units,spot-primitive-units,viewbox}.svg` | Color, input, output, region, and three-dimensional unit evidence: initial/reset/invalid color, sRGB spellings, `currentColor`, ignored color alpha, distinct filter color spaces, first-input fallback, alpha-only lighting, opaque result alpha, hard percentage crops, axis/normalized-diagonal object-box mapping for point and spot lights, and non-uniform `viewBox`. All seventeen are byte-exact. | +| `svg-filter-diffuse-{use,stroke,gradient-alpha,target-opacity,target-clip,target-mask,transform-axis,transform-reflection,transform-quarter-turn,blur-after,blur-before,convolve-before,composite-out,kernel-unit-length-drop,kernel-unit-length-invalid-drop}.svg` | Source, effect-order, safe-mapping, graph, and browser-drop evidence: ``, stroke and paint-server alpha, outer opacity/clip/mask, axis maps/reflection/quarter turns, both blur orders, convolution input, an exact diffuse/composite placement, and valid/invalid `kernelUnitLength` spellings that current Chromium ignores. All fifteen are byte-exact. | +| *(measured, not celled — diffuse-lighting split)* | Six twice-deterministic Chromium 149 matrices contain 236 sources. Every candidate also rendered through both actual CLI admissions; 217 are exact and admission-identical, and the other nineteen reach a new or older stable refusal, with zero silent mismatches. SourceGraphic and SourceAlpha are identical because only alpha is lit; the raw result is opaque across its primitive region, while zero diffuse constant is opaque black and no light is transparent. Object-box z uses `sqrt((w²+h²)/2)`, not either axis. Current Chromium ignores all fifteen sampled diffuse `kernelUnitLength` spellings and all three sampled specular controls. General rotation differs by 551px/Δ15, shear by 543px/Δ12, and a sampled affine map by 624px/Δ12; axis maps, reflection, and exact quarter turns are exact. Diffuse output as the foreground of composite `in`/`atop` against a source-derived second input differs by 69px/Δ180; the other composite/blend/merge/generated-background and one-input operation placements are exact. Midpoint-adjacent source-number controls are pixel-identical at this raster, so no numeric refusal was invented. CSS lighting color, explicit inheritance, `var()`, and wider color syntax remain four guarded value/cascade gaps. Halving the painter's diffuse coefficient made sixty-one new cells fail, up to all 4,096 pixels and Δ128; restoration returned the complete 812-cell gate to green. The corpus is now 812 cells plus 10 sampled frames, the filter estate has 451 cells, and the named register has 152 rows. | | `svg-gradient-linear.svg` · `svg-gradient-linear-userspace.svg` · `svg-gradient-linear-bbox-offset.svg` | The gradient rung's base cells: the default objectBoundingBox ramp, the byte-identical userSpaceOnUse equivalent (the canary for the box-inverse fold), and a bbox-relative ramp on offset geometry. | | `svg-gradient-transform.svg` · `svg-gradient-css-transform.svg` | `gradientTransform` and an author `transform` declaration are one computed value — the attribute cell and the non-quarter CSS rotation cell (the discriminating measurement: the value applies about the raw origin of gradient space, both spellings). | | `svg-gradient-spread-reflect.svg` · `svg-gradient-spread-repeat.svg` · `svg-gradient-hard-stop.svg` · `svg-gradient-stop-nonmonotonic.svg` | The ramp grammar: both non-pad spread methods with their measured seams, equal-offset hard stops rendering crisp, and non-monotonic offsets clamping to the running maximum (never sorted). | diff --git a/fixtures/web-first/STATUS.md b/fixtures/web-first/STATUS.md index 7cab58df..949ff529 100644 --- a/fixtures/web-first/STATUS.md +++ b/fixtures/web-first/STATUS.md @@ -19,7 +19,7 @@ Not a conformance claim: no score is computed or implied (FLIP is unratified), and the corpus enumerates constructs, not the SVG surface. -## Chromium-baked cells (741) +## Chromium-baked cells (812) Each renders byte-exact against its committed Chromium oracle (seven curved cells and four gradient ramps carry a declared, bounded @@ -258,6 +258,77 @@ to its fixture source. No new image is committed for this view. svg-filter-convolve-target-y svg-filter-convolve-use svg-filter-convolve-viewbox +svg-filter-diffuse-blur-after +svg-filter-diffuse-blur-before +svg-filter-diffuse-child-order +svg-filter-diffuse-color-linear +svg-filter-diffuse-color-srgb +svg-filter-diffuse-composite-out +svg-filter-diffuse-constant-default +svg-filter-diffuse-constant-empty-zero +svg-filter-diffuse-constant-negative-clamp +svg-filter-diffuse-constant-number-exponent +svg-filter-diffuse-constant-number-plus +svg-filter-diffuse-constant-zero +svg-filter-diffuse-convolve-before +svg-filter-diffuse-distant +svg-filter-diffuse-distant-angle-default +svg-filter-diffuse-distant-angle-large +svg-filter-diffuse-distant-azimuth-negative +svg-filter-diffuse-distant-elevation-negative +svg-filter-diffuse-gradient-alpha +svg-filter-diffuse-input-default +svg-filter-diffuse-input-source-alpha +svg-filter-diffuse-input-source-graphic +svg-filter-diffuse-kernel-unit-length-drop +svg-filter-diffuse-kernel-unit-length-invalid-drop +svg-filter-diffuse-light-color-alpha-ignored +svg-filter-diffuse-light-color-currentcolor +svg-filter-diffuse-light-color-default +svg-filter-diffuse-light-color-invalid +svg-filter-diffuse-light-color-rgb +svg-filter-diffuse-light-color-srgb-function +svg-filter-diffuse-light-color-transparent +svg-filter-diffuse-missing-light +svg-filter-diffuse-nested-light +svg-filter-diffuse-nonlight-child +svg-filter-diffuse-object-box-overflow +svg-filter-diffuse-output-alpha +svg-filter-diffuse-point +svg-filter-diffuse-point-primitive-units +svg-filter-diffuse-point-x-negative +svg-filter-diffuse-point-y-negative +svg-filter-diffuse-point-z-negative +svg-filter-diffuse-region-percent +svg-filter-diffuse-spot +svg-filter-diffuse-spot-cone-active +svg-filter-diffuse-spot-cone-default +svg-filter-diffuse-spot-cone-negative +svg-filter-diffuse-spot-cone-outside +svg-filter-diffuse-spot-degenerate +svg-filter-diffuse-spot-exponent-default +svg-filter-diffuse-spot-exponent-lower-clamp +svg-filter-diffuse-spot-exponent-upper-clamp +svg-filter-diffuse-spot-primitive-units +svg-filter-diffuse-spot-target-x +svg-filter-diffuse-spot-target-y +svg-filter-diffuse-spot-target-z +svg-filter-diffuse-stroke +svg-filter-diffuse-surface-default +svg-filter-diffuse-surface-empty-zero +svg-filter-diffuse-surface-max +svg-filter-diffuse-surface-negative +svg-filter-diffuse-surface-number-exponent +svg-filter-diffuse-surface-number-plus +svg-filter-diffuse-surface-zero +svg-filter-diffuse-target-clip +svg-filter-diffuse-target-mask +svg-filter-diffuse-target-opacity +svg-filter-diffuse-transform-axis +svg-filter-diffuse-transform-quarter-turn +svg-filter-diffuse-transform-reflection +svg-filter-diffuse-use +svg-filter-diffuse-viewbox svg-filter-displacement-color-linear svg-filter-displacement-color-srgb svg-filter-displacement-default @@ -770,7 +841,7 @@ to its fixture source. No new image is committed for this view. svg-visibility-rule-beats-attribute svg-visibility-unhide -## The refusal register (146) +## The refusal register (152) What the slice refuses, by name, in the compiler's own words — **both refuse** is a document-level contract; **declared** renders @@ -809,6 +880,8 @@ its row into the cells above. | `svg-filter-convolve-transform-precision` | declared | skipped svg/g[1]: unsupported SVG filter: feConvolveMatrix's target mapping crosses the pinned-backend convolution-filter transform precision boundary | | `svg-filter-css-functions` | declared | skipped svg/rect[2]: unsupported SVG filter: filter presentation attribute uses CSS filter functions, which are a separate unresolved operation grammar | | `svg-filter-css-property` | declared | skipped svg/rect[2]: unsupported computed style: style attribute on declares filter, which this cascade does not represent | +| `svg-filter-diffuse-composition-precision` | declared | skipped svg/g[1]: unsupported SVG filter: feDiffuseLighting as the foreground of feComposite in/atop against a source-derived second input crosses the pinned-backend lighting-composition precision boundary | +| `svg-filter-diffuse-transform-precision` | declared | skipped svg/g[1]: unsupported SVG filter: feDiffuseLighting's target mapping crosses the pinned-backend lighting-filter transform precision boundary | | `svg-filter-displacement-clip-precision` | declared | skipped svg/path[1]: unsupported SVG filter: feDisplacementMap crosses the pinned-backend filtered clip-path precision boundary | | `svg-filter-displacement-transform-precision` | declared | skipped svg/rect[2]: unsupported SVG filter: feDisplacementMap's target mapping crosses the pinned-backend displacement-filter transform precision boundary | | `svg-filter-drop-shadow-color-precision` | declared | skipped svg/rect[2]: unsupported SVG filter: feDropShadow with an interior-channel flood color in linearRGB crosses the pinned-backend native-shadow color-conversion precision boundary | @@ -823,6 +896,10 @@ its row into the cells above. | `svg-filter-flood-opacity-calc` | declared | skipped svg/rect[2]: unsupported SVG filter: feFlood flood-opacity is a CSS function this build cannot evaluate without a computation context | | `svg-filter-flood-var` | declared | skipped svg/rect[2]: unsupported SVG filter: feFlood flood-color resolves through var(), whose substitution is not represented at this Stylo pin | | `svg-filter-href` | declared | skipped svg/rect[2]: unsupported SVG filter: href inheritance is not yet resolved | +| `svg-filter-lighting-color-css` | declared | skipped svg/rect[1]: unsupported SVG filter: CSS lighting-color on is not represented by the pinned cascade; its direct presentation attribute is a separate ingress | +| `svg-filter-lighting-color-inherit` | declared | skipped svg/rect[1]: unsupported SVG filter: feDiffuseLighting lighting-color uses inherit, which needs the unavailable cascaded lighting-color longhand | +| `svg-filter-lighting-color-syntax` | declared | skipped svg/rect[1]: unsupported SVG filter: feDiffuseLighting lighting-color is outside the admitted color slice: color space Lab is not yet gated against Chromium | +| `svg-filter-lighting-color-var` | declared | skipped svg/rect[1]: unsupported SVG filter: feDiffuseLighting lighting-color resolves through var(), whose substitution is not represented at this Stylo pin | | `svg-filter-list` | declared | skipped svg/rect[2]: unsupported SVG filter: filter presentation attribute uses multiple filter operations | | `svg-filter-list-quoted` | declared | skipped svg/rect[2]: unsupported SVG filter: filter presentation attribute uses multiple filter operations | | `svg-filter-morphology-filled-ellipse-precision` | declared | skipped svg/circle[1]: unsupported SVG filter: feMorphology's active source image crosses the retained filled-ellipse coverage boundary | @@ -831,7 +908,7 @@ its row into the cells above. | `svg-filter-offset-blur-precision` | declared | skipped svg/rect[2]: unsupported SVG filter: a filter graph combines feOffset with Gaussian blur, which crosses the pinned-backend composed-operation precision boundary | | `svg-filter-offset-fractional-precision` | declared | skipped svg/rect[2]: unsupported SVG filter: feOffset uses a fractional displacement, which crosses the pinned-backend rasterization boundary | | `svg-filter-offset-transform-precision` | declared | skipped svg/g[1]/rect[1]: unsupported SVG filter: feOffset's target mapping produces a fractional device-space displacement at the pinned-backend rasterization boundary | -| `svg-filter-primitive` | declared | skipped svg/rect[2]: unsupported SVG filter: filter graph contains unsupported primitive | +| `svg-filter-primitive` | declared | skipped svg/rect[2]: unsupported SVG filter: filter graph contains unsupported primitive | | `svg-filter-primitive-empty-region` | declared | skipped svg/rect[2]: unsupported SVG filter: a non-positive filter primitive region is not yet represented as a transparent graph result | | `svg-filter-region-calc` | declared | skipped svg/rect[2]: unsupported SVG filter: filter region x uses calc(), whose computed length is not represented at this Stylo pin | | `svg-filter-region-range` | declared | skipped svg/rect[2]: unsupported SVG filter: filter region width crosses the unimplemented Web used-length range | diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-blur-after.png b/fixtures/web-first/chromium/svg-filter-diffuse-blur-after.png new file mode 100644 index 0000000000000000000000000000000000000000..0a8770ea7e32d96e45159b686919dd618fc7b303 GIT binary patch literal 2249 zcmV;)2sZbLP)000PnNkl9TfcOADK!*SR z=ih&<`FX{wiUJcm`pt(V>V)=3+U(`WP6DL=*DK??ZYVf*OuzX^LS2&Gfqqo_HoUCq zk2U@Cg zwdb8Hz~gj`=dcv%@t@qRL!Loo&_Kfm_iFG}N}MQAq~|gfZc{INl3VSNmjLsmgxT~S zkMWM}W%-A%QQ_1Awirw~otXu2wWYUb-(-S3Ll?^n_jrg$3i7TFjC|x-uFxTzh;Me} zYy{S9hrg5`pY4CG3bq6ilZt*grbCyyPA5b%T2)ZSHTrCa#B`|&Gfv#=FuAvPOt*T0 z7=Dh>p-uZ^icw&JW9^cJ@+{ciUFHm<0zBSiaTPvnIWJkxyE#Q;GRe!3?a+dhG48!B z45+aFz>@0)W;k`?Qz;EflDUT1lnUGHQ6$p4tl^Vj3I$c7-l55)cjPb7A$4_@Ob#Qg%sy1O=T12E)z05g{NJetFhVWh%#?>$gO6Pa|2WkfCC*!Mu zlrdY>GmLhhTh!a13HoCm*? ze{ks088T7bw*r>2QFb@s+p5h>fH;=-RIRnT~4FzgQ?{<~j!WaiIB`u;L{i^osMw+Pi^eKb} zK}XK^IMJs%u-O5%0m>R&@fQ97Q-HzLAt5e-ccfg!eF&jkIcoi7_r?}Q?obCW(t$=I zkPEkH&VaW@H%dX97nf!f$Y1AJHgKW-!$}GLs38`A%!xIZsT-KwnP6u=&ttTga|LXz z*`_E(7oVoIhsvKT{aoT8hT>(k!aP{r*VTqAOUyHgAoME@=^4=D+(@x*Dfib0OD{S2 zK=jSN+w3D0fc%I*P350zx2jR~J1f}U8=!}frV`12r9MLL2*ztOCwY_tl&fS7n!onl z&s~H9PzDcdD(oA%=M_SbuPugVo^}R@FvdzikhKYs+b1Zu^>Zu!E-F$lkiM_+vE-XW z{JD)kcipaq18bxIsqwEX?7xI{?T`m_9p{RJz*EALGPROCyETZ!-J_nLk)ABtqzoPv z9WUHKA1obK{dFB)pZs&<0imk+z|1^>MhDMgm$n%m;37pQN(qJTZi9?|BwYg!mcPRl zevGeBF#|cTYyYwe>ju(0TmJcB-D&PSismLm127uLN;x#$H4^0{lZof1EPvc7jnl}Z z;908$o(%mOf{voe@>d#s zzHq@|gM-V)lk1Hzbdv9iq9O2G+8TT}S>6SBbomuLE8kRKfagSkoFj5yDK|E9572bD zCyHQ7$O>|1;3>YVfu9vT@LKa-zplJ)Lh{#bm2r!y_&_d0AA=$b{DjD(fqx(W!tz_* z#WEq(AYvkJYT$?ORvbJpp#c*G3T@&Cp=in)hR6dH;S*%pwSq?@j|P4N&m!^9Hu<>h zzdi&-Gpu13TMPVI-!xcW_8*SsuRe2fGM*~lh z{yl5RzFTMyFXvw~?R8gl&`-3IP=*H+upJZOAyHf;KGr!}+JfAFZo9v>$~vd4;cWqH z_*wx|qMSU)7RdP+G`mAzw!?-BIcB=h2(p-`P`nb`qM!G(Z>R~+A#t!CgOjaXp{>?(?Le{WI0qXbmytTwIHAKg}C@(uR z!FAbq*rwO5GS;Pm0)SA7JYf-QSgJq{L?|h1$s2r%SKZCE{>+tQ(wZrgqpe%1HB@@X zSFJwL2Ntk&MnH~JQ{Z7$k^U~6nz{6A?aWx|KVMz%eQ?|+Z%%p9mT=PDRSnuQ-y6GR zaM>x#w8izu0B)#O!{?7u40)2Fogs8>92(}GOi#qOO-7$@bTdsiZ^p}SHA3N=b|MJz zhSD8S{?IXzRzqS?vKf)5T-)i_-{Rb8+wrl3*w%sEgW|TdX;IX1d;Bg(k0CI`76>1H z?WnO9_5LV!`1>0`s2u*@5rhvvb}I4yNOt^QzTNTr{{a91|No_(inss(00v1!K~w_( X5yZY=|CNVk00000NkvXXu0mjfmsV0h literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-blur-before.png b/fixtures/web-first/chromium/svg-filter-diffuse-blur-before.png new file mode 100644 index 0000000000000000000000000000000000000000..6077b1d7f90bf2139b988ced7182ebe18d449fce GIT binary patch literal 2426 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 literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-color-linear.png b/fixtures/web-first/chromium/svg-filter-diffuse-color-linear.png new file mode 100644 index 0000000000000000000000000000000000000000..44eff44397dcc0ce212f703b764748b5fc9d4597 GIT binary patch literal 1060 zcmV+<1l#+GP)000BoNkl4Y5Chpk_#dk!EEN;*&&B^x#uHh)+KG64XOI22oJ-kOjR& zP!AP`QW8l~jZ!pHoD8)&mu|arx9#q>^^1kd&)>GY+wP9ReIDcoyC2^7e&6r!_q{1O zf4?2%GX%(UbOBnU3(y)}fY#^&v_==8HF+<9O!a|n4`nT&)&h}rng_XNGaT~C?{*loFtTy5_W<^Tc!J<#ajThvKS8e9x7SP%#KLdR<%^O;yncTXkV{JKEXOAj zpv0v;>#>-uf=GuxGH#0K6OtW$Vjn9CYGHga-Mk9!DxevfjEM_Cz zNnNY#?2@02faW@z)Ij3}D4Jk|@?vuVMYufNf+v~)@dihcLCSQzUZoR^(9vW+-E4=0 zF{f{0+9zo)<`z{*Famt!eeG2z8cNn^=EbCEZiNv)7b8HO1S3!+xYSkCdaz=CnRzn4 zx=wQs?i7o&9=wrD5-CO8nv{dr1IL4b2Xo1BPfJmCX@-|(R6r;kgQpnB zGd8O>8X5*ZZjEnWY0P;2E(=9tG%L^{u_t+M+1Y|#U(0;=V7CB@G{RaEPXJy3>eF+5 zd(%8rE$T%X6;NJmDm0N{PWVHsy$C}Ox9@)TuGl|4q8WgXpD_G;{JfCuH#U-3Sr5Pb z^4~xAt{$dHu@f=dr6w-w9CmJv&mOglpNJ8lzKb4@xwpnY?z90ZV3tZ{7r}k+#h($ e21!IgR09BNGO%)=*z;ci0000000BzNklajn>;~cy|ZDnaVngE5Sy`jwRjV-T7HUiA5JGyWCCLmTq zMhk5OVl2mPtOT z4Wy*iq(9ZuP@$uo-q`RnYb3@3f#5?dX@U{Vb$V|oZgoc7LB{H!_wTGCgajHt1JWk= zKL!pqcAEdJXfu}J=<5|hV=)3`NH79? zb(N(7IzIMxb;-^*dl&(-B^aThMtk;9Q>B4g_cM2&TLUz&_+dgUXMz!+hA6`=+QTr= z3v2X&j_RC&#>{}s2}U^CZQ9djBnjfXE%@N2EoXmJfcyzYApl(6+8PW@f_wkX3m56^ z-BAIGBp5+M5kp7K@Hu*d%*cyh**l}eMyi`EIJB*9F(1bv^UTA<=s3-p&8I?Ns1)k&WMi5Is>zo zAgtk%?IU|P!`t9F5YtZ)7hM_sk!qjoZQ?x+CqRA|U3)yAYL5-&e)FV*Ihm8$MQ%Sc zJ^%MirE8n9s$5tRfVY~QE=sQ&Zk%od0>KNA%|(K$1}yl)U3pw2v}(YT@ogo8i-cAU zSTYKb+C?I&1}quB4@m7I5mf`0Yzv-rE)rKYV96#xA{U9S8n9&h1SXM-L{|-1a(u&s zE}B~jjZEe^8W4xjssT%m>4PqE`eHx=L{tq}2=z~Y3Zn{88dZSOr~;Hm6`(XlFW@%- p00960v!H~F00006Nkl0009%NklAX6836kB7wzkm%r+GvQ>K0*0)G@Faj4IP}zO6Z-1?4-5wqzK)8bu!qMTfD%^dRkrY=EzzC47gI{1GWMu;E$zO6ibx#d`k3ef6c1cv3gf%M036?l_wUx^A(>|g{o z6jj;egXf#=%h2Zmx*d$ba=c>=T0y;on^=}9i#f+KRDga5|3#7ZOhdnYX|jD8Dp0EG znLK>~U6WP044*a~ADYo7hF5@NX-CMiYL!3Xd2;2HV=XFBsp*G@C|`kkt!NtBwF~2J zictX}#2!!4+=UEXQ)&hH;_Qi}n|f5>XnJ6Dm`y~erAQXDFhX7Wv&>kM zPKsdT!V7TzObVWc%O#jPS}B5?CfqvVi_7N@xnG45pp_z7%E6o0>{aKT=U*@aR8rJX ztBrbf>R2Kf_x4RAK5B$h)SMb_PEP=j-~|Y$$mP_41usA{Mee5tEVjE9p%i(U8nD<3 zkV%oJsR4_v0D%;Fof@#TyW#nrBCk^emUaTZrl^Cd0ZY5Z{-vn1sR4_FJxr0&kU+2L zY-+&b@YoMiBvyAy*-aAV8ZyfHr+E@EZUC|Nr$hBPjp? f00v1!K~w_(ZsdqePe6>?00000NkvXXu0mjfJU^@+ literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-constant-default.png b/fixtures/web-first/chromium/svg-filter-diffuse-constant-default.png new file mode 100644 index 0000000000000000000000000000000000000000..a1468a5150b89cddd0dfedf4d62a90b30a631a08 GIT binary patch literal 897 zcmV-{1AhF8P)0009vNklFHq>e%+SZC9RwzAq5z(ucf>1<6q$jU}3hF@=Pbz|*#G9yik}5*! zNjwPZK@V!BSgEFst!>hp#F&pw(qtVBgkk%#*_~u&2<(p#9_$S4pZET=Z)Vpub#)Y4 z83(jDwgB1K0%T(gkc}-sHnsrSw7dY9!L_|1f57LOSxkRl$wISPPZh(f**zgY`9T91 zWnjk^Z)8mkc#T9d^DC~t`W(OeVlkI5LjxGy+(I^05px50r!9y z1JE#=0ndOi1JJOU0TCe705nWyKm-Uj01bl~5D$nq0F6~MAQ_Ni02)hX&=sc<^%Bc&uK4L<7*M1+$L={eFP#0Te|cdw{RYjO}4lIDKcv@ec(6VLu|EY;e8G-3kVIB3O}$^M#KF$C;rvkAI#>D;ZT?x1F%#6v^Yqe)$yxdm^12!)^sMQ{Pas>o8;fPx?Him4*2T?0zZ)k;7WS?wB7Y6{?8MGRd7O3n8J zysLwypuiNC2lQV(uDHj9xKusv_pD0j16hJW@q-%b9!A5#WH;t^uV^ z`bZU#O(t-Fp=&@nKsUH@Lix5KmxZ6X!8I6$GdV40~u@}E0`GyO&A*Q*aYPQ PMHoC?{an^LB{Ts57^yG- literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-constant-negative-clamp.png b/fixtures/web-first/chromium/svg-filter-diffuse-constant-negative-clamp.png new file mode 100644 index 0000000000000000000000000000000000000000..4c2d310f5d589cc39a4aebc07c151be4cf1e1df6 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGJMa8DPnKsUH@Lix5KmxZ6X!8I6$GdV40~u@}E0`GyO&A*Q*aYPQ PMHoC?{an^LB{Ts57^yG- literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-constant-number-exponent.png b/fixtures/web-first/chromium/svg-filter-diffuse-constant-number-exponent.png new file mode 100644 index 0000000000000000000000000000000000000000..6a2a5362cb398dbacc9ea3e971b98ecd762feea5 GIT binary patch literal 814 zcmV+}1JV46P)0008xNklqIh-JdB1n6e%1vs47ZuK44 zvBp6f%u=#y!X$&Y9S&Uh6w(6T3Jg4Z64I_?5eZBqdOnUneG5{WlNRvQ2O*usnPXcU zJ)5kWj49|9uIw2lno6Z22w>#zAuOb4Em|6adyN7T5Qr z2moI`d*FjhX_lY<3NNODF{>0XxSlr{iO2!W`DEAcI-NMpgu`I(@AT0ZEX#_Lc>o{= zL>ivkfmy@XA14_UjGa-BG^BC`qy~VcWf*V)vID@uN83j-oRaR68Z!hmEzeE?XRh5=atEdgL@6o#?@T>)Sz!Tfc5|Y$KNN5@ry@8{=wxH2;+GI zdUCdrbx3J;_B$-bJ-0KuN;8MD04SYMgDK6uuAW7Bb97^#mrqAak1q>=*%#$si+~@0 zqs91O&#!YzIRkdbg1D00$l@20008xNklqIh-JdB1n6e%1vs47ZuK44 zvBp6f%u=#y!X$&Y9S&Uh6w(6T3Jg4Z64I_?5eZBqdOnUneG5{WlNRvQ2O*usnPXcU zJ)5kWj49|9uIw2lno6Z22w>#zAuOb4Em|6adyN7T5Qr z2moI`d*FjhX_lY<3NNODF{>0XxSlr{iO2!W`DEAcI-NMpgu`I(@AT0ZEX#_Lc>o{= zL>ivkfmy@XA14_UjGa-BG^BC`qy~VcWf*V)vID@uN83j-oRaR68Z!hmEzeE?XRh5=atEdgL@6o#?@T>)Sz!Tfc5|Y$KNN5@ry@8{=wxH2;+GI zdUCdrbx3J;_B$-bJ-0KuN;8MD04SYMgDK6uuAW7Bb97^#mrqAak1q>=*%#$si+~@0 zqs91O&#!YzIRkdbg1D00$l@2nKsUH@Lix5KmxZ6X!8I6$GdV40~u@}E0`GyO&A*Q*aYPQ PMHoC?{an^LB{Ts57^yG- literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-convolve-before.png b/fixtures/web-first/chromium/svg-filter-diffuse-convolve-before.png new file mode 100644 index 0000000000000000000000000000000000000000..f85c1360b485050f17a3b2987bdd5572739406da GIT binary patch literal 834 zcmV-I1HJr-P)0008_NklbFqz?m+~_yI1kxOTU3gsS3V8 zZA(lwHA#(m+a%j;lGVQ~EHa&ao86gdV1Itv$#dj3U2LhuTQ{1GRm!{NvW8W5@&2)eBkT3r+j?J3bq$ zcLvCB7UxpsdVi;-RvPN|@7<;OX+(>ug`j&{y}_xYNyG-|_%kP_;Ne3-hB_cxOe?U{ zRApsUZuAi|pyQ$YS2x=0+r6_3)0wFVa*yC))Cj=sr<;fhas?p4)utMagrtz?an6qP zfyl?A44H0r1{7f+3t*aHjQJx8`1H0iq6;+HLaY;v;U&=I3UEj;h92n8Tb*weB^i|# za!&hhAI*iJ4)IAzQMJczia-zm3C?9=hfJNK@g)E}H1iC`g~3C4gCNmhovzUDm8 zgbHv@FoxSe6Dq(z!5Dg=p$Jauuum5>dL2r&-4`prtXtv&1SS~6_S1E60T6&xJe(I4 z0D~)c-#ctc5FjwYd$B#fz*l6owhI5RRvnd(5k~hvxOv*PFZ`WE#5dWKJ zE}O7zk5`~jRjQ5t;Tiwe!ESMQ_Js>bC&Q_@lo2!vInS;EZlQDe85l$B@_@gKV3}_` zJ3o3PY^#WJ(T#^+^aoc5rvw2)Tts0W9l}&Xpo@^p?nh=jbDUjdbU($ZJ6Qlv7g3u> zhddh<;v%|B52l;Dd|c#e)(?w?Z2$lO M07*qoM6N<$f>T6!(f|Me literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-distant-angle-default.png b/fixtures/web-first/chromium/svg-filter-diffuse-distant-angle-default.png new file mode 100644 index 0000000000000000000000000000000000000000..b53a8e2b5eb6fc572cf128e2abc2cf81f690c8b1 GIT binary patch literal 827 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 literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-distant.png b/fixtures/web-first/chromium/svg-filter-diffuse-distant.png new file mode 100644 index 0000000000000000000000000000000000000000..a1468a5150b89cddd0dfedf4d62a90b30a631a08 GIT binary patch literal 897 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 PMHoC?{an^LB{Ts57^yG- literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-missing-light.png b/fixtures/web-first/chromium/svg-filter-diffuse-missing-light.png new file mode 100644 index 0000000000000000000000000000000000000000..e2fc51d998211adee20d11ed48deb3c4951d0d96 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGJMI8PVHkcv5P&O354C@?S>3UdG0 z-1t{o>aoB!w&>q?K5n+OQx6bc!Fh!xi^;TcmV@sCHR8E%85tP<|2O!_84R?E4P+BD Z!_)f=m(QKiW(SHec)I$ztaD0e0sx(_Ggtrs literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-nested-light.png b/fixtures/web-first/chromium/svg-filter-diffuse-nested-light.png new file mode 100644 index 0000000000000000000000000000000000000000..e2fc51d998211adee20d11ed48deb3c4951d0d96 GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGJMI8PVHkcv5P&O354C@?S>3UdG0 z-1t{o>aoB!w&>q?K5n+OQx6bc!Fh!xi^;TcmV@sCHR8E%85tP<|2O!_84R?E4P+BD Z!_)f=m(QKiW(SHec)I$ztaD0e0sx(_Ggtrs literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-nonlight-child.png b/fixtures/web-first/chromium/svg-filter-diffuse-nonlight-child.png new file mode 100644 index 0000000000000000000000000000000000000000..a1468a5150b89cddd0dfedf4d62a90b30a631a08 GIT binary patch literal 897 zcmV-{1AhF8P)0009vNklFHq>e%+SZC9RwzAq5z(ucf>1<6q$jU}3hF@=Pbz|*#G9yik}5*! zNjwPZK@V!BSgEFst!>hp#F&pw(qtVBgkk%#*_~u&2<(p#9_$S4pZET=Z)Vpub#)Y4 z83(jDwgB1K0%T(gkc}-sHnsrSw7dY9!L_|1f57LOSxkRl$wISPPZh(f**zgY`9T91 zWnjk^Z)8mkc#T9d^DC~t`W(OeVlkI5LjxGy+(I^05px50r!9y z1JE#=0ndOi1JJOU0TCe705nWyKm-Uj01bl~5D$nq0F6~MAQ_Ni02)hX&=sc<^%Bc&uK4L<7*M1+$L={eFP#0Te|cdw{RYjO}4lIDKcv@ec(6VLu|EY;e8G-3kVIB3O}$^M#KF$C;rvkAI#>D;ZT?x1F%#6v^Yqe)$yxdm^12!)^sMQ{Pas>o8;fPx?Him4*2T?0zZ)k;7WS?wB7Y6{?8MGRd7O3n8J zysLwypuiNC2lQV(uDHj9xKusv_pD0j16hJW@q-%b9!A5#WH;t^uV^ z`bZU#O(t-Fp=&@3UdG0 z-1t{o>aoB!w&>q?K5n+OQx6bc!Fh!xi^;TcmV@sCHR8E%85tP<|2O!_84R?E4P+BD Z!_)f=m(QKiW(SHec)I$ztaD0e0sx(_Ggtrs literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-output-alpha.png b/fixtures/web-first/chromium/svg-filter-diffuse-output-alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..fb45e94d392f84e95521302f162e8d55b1991ac8 GIT binary patch literal 1071 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 JPDHLkV1man`;Pzs literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-point-z-negative.png b/fixtures/web-first/chromium/svg-filter-diffuse-point-z-negative.png new file mode 100644 index 0000000000000000000000000000000000000000..4c2d310f5d589cc39a4aebc07c151be4cf1e1df6 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGJMa8DPnKsUH@Lix5KmxZ6X!8I6$GdV40~u@}E0`GyO&A*Q*aYPQ PMHoC?{an^LB{Ts57^yG- literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-point.png b/fixtures/web-first/chromium/svg-filter-diffuse-point.png new file mode 100644 index 0000000000000000000000000000000000000000..8284570d381a917b752901237ee84cd67ea1ea36 GIT binary patch literal 3303 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 literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-region-percent.png b/fixtures/web-first/chromium/svg-filter-diffuse-region-percent.png new file mode 100644 index 0000000000000000000000000000000000000000..d796168f8ec1f38565960770a68e2e9a026f5ab5 GIT binary patch literal 527 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 literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-spot-cone-negative.png b/fixtures/web-first/chromium/svg-filter-diffuse-spot-cone-negative.png new file mode 100644 index 0000000000000000000000000000000000000000..60765580b1f1fa7655d070208a9f82590e80a77f GIT binary patch literal 3505 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 literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-spot-degenerate.png b/fixtures/web-first/chromium/svg-filter-diffuse-spot-degenerate.png new file mode 100644 index 0000000000000000000000000000000000000000..4c2d310f5d589cc39a4aebc07c151be4cf1e1df6 GIT binary patch literal 162 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGJMa8DPnKsUH@Lix5KmxZ6X!8I6$GdV40~u@}E0`GyO&A*Q*aYPQ PMHoC?{an^LB{Ts57^yG- literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-spot-exponent-default.png b/fixtures/web-first/chromium/svg-filter-diffuse-spot-exponent-default.png new file mode 100644 index 0000000000000000000000000000000000000000..e4bc1718c61980e2bb6423988ed6ac8b0bd5a55f GIT binary patch literal 3487 zcmV;Q4Pf$#P)000eCNkl+K`i^rBdVxGgkL({v* z8oLfm?cCqkx!)dl>~Az%$I8dRTi#a8?>=wC@R{p|me1=3i z{){DK$M($YV^gp0oqToAa{s~At7rGO6Uw#>0s+56reO!v9xxcg z*n->=znKU(g`S`nJ~X1#ykw50G0;;#Rsz>uxah{qmRYQsRgvdl909#$!O&vvfKM>odKbZ3}009utAje`xV_7cO?VA#yM*8zupev0y|uVrF|L;xGw5O#>D5 zI7USye4Yn*3_-kfZr8H8oj%)`U`LgEikr_xjLCmDLip#$_RpS!RKKP!J$26IXUx~h zNA_ZHtIW$`?asVGB_8aljSP46cGYZvGKoqK80-WAD54@so_le}xc~S=H*cW(C)cy#V_i$@L-a#-bOMBPbfnur%qVF_RJ)ib zhA{Xzkaq#%HQ)X8D*2+X-n&^DJ6vp{f!!U9RGx4*<8(2@cFp;V$Xay81si86^fP#@ zGNJRg#W#)QC}XHUz3tjH{`?Euk396(T_9`&d5B~p6QyB0s3t&tC3TcGL^5;Q>cRL1 zRy2tmu*vI`S5muT2BnhpsdE0FT!|1nH6o9oi>*w>Q8*>&gZ6^xl!(n(lt?*(W^6g;FQsRY8GDF zIYA`J6*0X4_c=bB#I`x4O$?OOM~di+F9E*!iIp`_;ct6A`(6m>=eHku_;0&G)j;iysD3$F zmeAToJ!hUU^wjeQ=*uW+Zd}>#5J%8?k%K^o;#d^{OsE8D1tyEe)0V-RkueCX6iz_j!Z2)*=7(4r1N|k?!q22e;Q6uJA0jB_z z2vIbmAHMw293 z=e1#06^ne>m5N&8uHX;}mAs&+*n~2xg|j+7cE)@U=9hojv3*bVJQyko(0u2FB~~+! zK5YYl`iLWqR)EOOi5kQfCFP_1AifF$!z4VCz~BspaL&7jSI*~P`1<{ueK1H8hh&fv zSiP`&{!jsDu+-B&#DTT5=T(Y4TOU9r7#nFE?Ml!lR;K0M)3M z@T--%C3Ear+P}6O3=Zj;oX$hcBW6^qY*&t`I(3y1^pqt?U!l*-$u}t)1wT;hu0SFd zsvpMFk$_ta1Xlq}Uw4iCKz9k9i3M&s7`w;THz`Ma$0UIk*A;mXIY5$d#SgbWxFxxB zh;?1ZQG0;YKX;&=Zo2ukal*A`QFkj>z}z&PkE-w2E(lE<>cS_MPHP27VZmIrB;m6^ z``tD{f5W9qx!48$ASO(hz?}YiS4T$o+O@wyZ&6XCuMGX4vn%NaP)+=dpHY_xl&YAx zB2SKrVbWHS=cywS0_&Fa`d$DF*(ZD}6Bz2N(@jZu({5S#S5NMwbx#W?hk^%k1DPpI z&`K5x-xmTmnQBU8BPPY$lcCv}z`JA9I+0dLrIK>_$OQVkYUpn5H(Km&`TXnb>}>Bo zU?=uOD#USxMG^u6O9gS%Pp*9B#rCIX_sXrVJa+*kSVJhMfy`-?o(|D_8ac!)C!%6|x7SVXv_e7S z&rCF0b~0&#eqsPP{m9aTG0~|g2dJC|6$9F4Ar1hkKeU}Z+E0CP&NGTopA-GW*%A|= z;%A>k*eROn>uRHJlukag_0UNx`bhFZ!1y#8=6gPXdA5P_6{ray7CMM%b^Yw)uE(|u zfzMvNICg%ZoDfrObVcUBofd2JP&==`h*k9SN4CXh5UirOG8NAh;{lQ}CS7W5G4jad zEBCx0=)Zr}DvY&R9hG==O0^y!^x*Dg^9z_0m$Hhcnz>U^us!lBU!E>t6*mkWvip;l zDg&yXl$g*HzVSxOe{}9(`%rJa%GjvF7crE5`tJxBwhCl+36hlF-O=W6`t+7V^xzR4 zZq-Eil^fJk)e->?x?(Uu6pyEL>w{b6qu;*rT|B#x2=o@-xuT_g;PeLjTs?k8Rfr+uFSAXJgGP6FV_K@yI2M;oWa!un$e3CLIbHZR1n<;fW@#1$psM7BcP`T4vLd{r<1rw;A5_;9f5adqm|>qo_bvK3sYoF7Qc#$(&F(uJD+Cs zv=TbHpj-WJfRB2h9%vd^|X0`oR%M3IYZVX;uvd6;+Q}Eu@*y7h~Xvl~B{Qo;Hm-J0m|- zL|~c|5wBQ<`3fUu!y{YW zGx4Ye_fb{Ez_HLHK|wr;H-t})6%1*QKlT{tsgDeGbk*C~r2MVwA(dFyr%hB)!o@ng zA`YoOaS)*kD-A2@nlv9sFGJ-4N~2>(nu9$xle2z|xI)%LF^CGolX?t2otU~{euxDj z7(SL~C8R_xNB0J+OZP%fLaniJdL-5<`mr@j5C^ROWN0Q5{mj%9RSOA8#EuK zfa`k}Qn|)V2qO8mn N002ovPDHLkV1h!LmMs7P literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-spot-exponent-lower-clamp.png b/fixtures/web-first/chromium/svg-filter-diffuse-spot-exponent-lower-clamp.png new file mode 100644 index 0000000000000000000000000000000000000000..e4bc1718c61980e2bb6423988ed6ac8b0bd5a55f GIT binary patch literal 3487 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 N002ovPDHLkV1h!LmMs7P literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-spot-exponent-upper-clamp.png b/fixtures/web-first/chromium/svg-filter-diffuse-spot-exponent-upper-clamp.png new file mode 100644 index 0000000000000000000000000000000000000000..c9140e615e5d7c3748680872094b5421edc048e8 GIT binary patch literal 1437 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 JPDHLkV1gFL-XQ=0 literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-surface-default.png b/fixtures/web-first/chromium/svg-filter-diffuse-surface-default.png new file mode 100644 index 0000000000000000000000000000000000000000..bab649bfd79575e1ab7a43a2c876952b295802a9 GIT binary patch literal 928 zcmV;R17G}!P)000A3Nkl2Z_CB_H!jquV>;3x3|d3g}xlP1Qb8UYg$L=un) zD2A3&dcW+Y>k*CFth3whv^xXI{$4u+{O6qCaCSjhcybG!W_;+B;|1W27l1cj0N!{3 zc;f}&&8ZI{*nHL{`fiRyM8S8EmrBh=7SDA1kqaCaGvL`1aMRUjbz{!~^Q$OVF;@5aS2 zM(FcS3Bn*+ECYZ57^8-c4vPwM2RQg^=cQa(S^r+vX(Lz$00A(@x~^vmoj3R|7>&e3 z!+oLMbd_2L%K#vN4;4xt`nHtJtqJ2jDBfKR|$2%Na#& zz@=or(j0)h06?y!K2N6LGJQCCc5*agzu5dl2GYnXPXXZif4iDp+RR@b49!l(L1_E+ z<^b@lU8<>de*LqxUzuM_i+-HAJ2=!AY`Wf@4+3P1is0w-x}{pzUVcoca`L_L-s!8+ zR<@Xb&~i}HBrEbEqj^zv-c@@ z2{Ly(K672+Zu#^GW#ZCBD_g}kD~COj zn3x&p2|GADLICz%l*!94KBTI0V|KcK?1JQIFG&=(T?DU3U$11>c1vT!;Rh43f~jF)=^zyFCGHHsB!(P94#2F798C>GEbdw+UF39XAY!?PK^Hll8i-g1aJ!2r zrUoL`RdczED5eG?c01kcBD$%8h+P1ex`=veAYxlPce;prY9P{NKXeiN8S7~>mHcvq zI>b)829Kr_5EPEQ z5X5G3OmG`p^!GO(H(T1N2MDj=yuy;jWZF2(!FPcg@!YqJ3=IGOdv;mI11(|$S;WjB Xvx4!(8J;V%fFcZ@u6{1-oD!M<`tvcH literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-surface-max.png b/fixtures/web-first/chromium/svg-filter-diffuse-surface-max.png new file mode 100644 index 0000000000000000000000000000000000000000..c34a74a709295bcce63e1df70b4ec75c745ac552 GIT binary patch literal 392 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLH@YFxq;$IEGZrc{A%RFOwoq8)u@@ z^8)q9e&-(g%!+Z+Q)ltAznApuk5S-5xm$9!TlUCp-(qZ;>&LNxlhH)6L5<}?3&X6p ztX}VXe}A6)<>B^84>&$dU&&*?@M8Y_^}m15GH&gbdT@kMSwZ6JwgyMmc$sPGF3To# zIIEpi8bTyvy|?q1*mw4$FhPrTkCa)Px=;8MJGC3}=RWTfpHnBLl<# k|HZODqk-Yc1`0@KhIH|qY^h7VQ9uy}Pgg&ebxsLQ0D0S`6951J literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-surface-negative.png b/fixtures/web-first/chromium/svg-filter-diffuse-surface-negative.png new file mode 100644 index 0000000000000000000000000000000000000000..7ec61f0205af3d07cfb91cb64735165a2aea70c8 GIT binary patch literal 906 zcmV;519kj~P)0009&Nkl7^Nq+Qdd?bdBp$NuPW3`GaS4HWT4!3)Jp@lw3-YxouX7~boZcp-`x4%}qw zWa4ylD4SjD)^zRKG>NZ9M~o+@%}H|(g*=pUpb0%s^Zw3xn^t;sZx;13BI0p3Ic zyom&O6AADp65vhG3rK|5ihIpF_upD5EUuj!x_xCNnF#bDl1_f|x)k2*fpS$}`BJq^ z6a>;0c(_os2Vu0_rHcOi-H)}cT0SFB97!TtNLQdzYr%6iMUtc@ugWvWRTwO-X*(4i z(c&op0k8)*=7&)j2xxpbd7_{k=*Hs5O1(i@NuB}_0DEwGCXd2F6w&Fi^k60)Bn+Mc zhXEMO$|y8o37VbE^vNQGVWU__{_zwDH2_Wmh5;`SdH|dR3j+@lM1U~h1=s|@ z33V9o0?Y#7gf0vi0j2?PLKOy#0OJ5Sp$G#;fPDa*_zeR_fJ*?J_zHu2mfQm1lWY`04GX9ym_(kt=xdC@oKF?IMQ80d;@UEh3TAbSTOs1CQd%mExZx+x2TNv!Y zeR1(XH^2W~(8;(3&W@}0;LV1H*aEYMCB(8U`1oJ0?sj;VTR;&1RMCTHTZke3DS1$h z?>CHGN?!e1Ynh$ik-~(SOBKycWp}h@ToOeAecG;dej-MIeHEP=P1hQRVORsI{NjD5 z#bbjJU|dD8?2HZdX|)!to14XhMyng&iCI<=bPcd!Niji5#8x(|$R~IKW>w^?YrujR zU{ghYy9O+tH?|m5k>9QXi>E-?RYcJ>VDS_PyNW2f1}voC2g0i&x~>5WNg$*uqV5{7 zkOV@iBI>RIOPjBbP(>}nJU^Y2V_o|}c73~^OG*8z{B*gD0@FqSs_5?3QFt@dJ#@p& zrDck)0ZSVJsG^f2iv6yrOMKq0!vl4R=&uI6i3E5P3GgNo;7ugJo1Xvx0RR6osuh6% g000I_L_t&o08P!PovsTvg#Z8m07*qoM6N<$f^CeA!vFvP literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-surface-number-exponent.png b/fixtures/web-first/chromium/svg-filter-diffuse-surface-number-exponent.png new file mode 100644 index 0000000000000000000000000000000000000000..ba28994ac29f233ddcaeae1639c5f57e3bc63752 GIT binary patch literal 897 zcmV-{1AhF8P)0009vNklF|9LL|AnRVCI)J-!BR7y}NAt@**tc!<;Zg$XH*PwIVk~&4V2fJb^pxl?DTRf#_>0^J8ymOu`r*5JlOZ}edhhXv%lG0<@LyERLw}J z%JBt6;|qw!7Z8mvAR1plG*vI4xV+YUAaJg`DH_ZCTF#>VCb_M}Q(9|dO>MBEi|Dqv z`)FM}rG|qtV!&cNH}+-q#itdch$_MD1Of_PjO7}_il$fgPatY*-6f0!J_+**!042}XM0OW6dt(-_}h#BM-bnQYL ziP>ayYkX=0dB;(JX#lKL7zS8?c>t_b76w>=LjZPdqJl8M0(=5sg*ptd0Ji{Gp$h{b zz%>9?sKNjUa1Ow(-FOcJAizHWR=kD*5D*doE1tq&7Z4TzD?4F`)CVSJQjgy(xX-l< z2n>J~tx){@BS{9|X1CmD+6BZ0;6G2^{=M+Mo%QZB?GH4<13;LXPm}65$F~QMxlgtW ztff>yxI{dbt(4TS>Mtgy_z@2_pkTJGA?r= z&`JoYq6aUd=3t<&`9w!u`3nI7{#EpKdh`2S+8p1w((Yv`B*3|f$SwQczwF)_>Iw$D zeN+n1=2=D7uHkG?Bk~9=z^#frbqye}0G}%I+BJYU7958v^4c|kI0~??B8sj7#8H5C z6;X5zAa3_8c2z{zHGsGYFsdTzt^veNfKe4ucMTv)iI-&@jb$H>%`YYBzXfu_Yu5l$ zLV#3}EMXSAr|23$u>Ye!!T18A@dZTV3y8)S5KYw!{00C3|NjHRj_&{f00v1!K~w_( XTwA@rUFBrW00000NkvXXu0mjfgNKiH literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-surface-number-plus.png b/fixtures/web-first/chromium/svg-filter-diffuse-surface-number-plus.png new file mode 100644 index 0000000000000000000000000000000000000000..ba28994ac29f233ddcaeae1639c5f57e3bc63752 GIT binary patch literal 897 zcmV-{1AhF8P)0009vNklF|9LL|AnRVCI)J-!BR7y}NAt@**tc!<;Zg$XH*PwIVk~&4V2fJb^pxl?DTRf#_>0^J8ymOu`r*5JlOZ}edhhXv%lG0<@LyERLw}J z%JBt6;|qw!7Z8mvAR1plG*vI4xV+YUAaJg`DH_ZCTF#>VCb_M}Q(9|dO>MBEi|Dqv z`)FM}rG|qtV!&cNH}+-q#itdch$_MD1Of_PjO7}_il$fgPatY*-6f0!J_+**!042}XM0OW6dt(-_}h#BM-bnQYL ziP>ayYkX=0dB;(JX#lKL7zS8?c>t_b76w>=LjZPdqJl8M0(=5sg*ptd0Ji{Gp$h{b zz%>9?sKNjUa1Ow(-FOcJAizHWR=kD*5D*doE1tq&7Z4TzD?4F`)CVSJQjgy(xX-l< z2n>J~tx){@BS{9|X1CmD+6BZ0;6G2^{=M+Mo%QZB?GH4<13;LXPm}65$F~QMxlgtW ztff>yxI{dbt(4TS>Mtgy_z@2_pkTJGA?r= z&`JoYq6aUd=3t<&`9w!u`3nI7{#EpKdh`2S+8p1w((Yv`B*3|f$SwQczwF)_>Iw$D zeN+n1=2=D7uHkG?Bk~9=z^#frbqye}0G}%I+BJYU7958v^4c|kI0~??B8sj7#8H5C z6;X5zAa3_8c2z{zHGsGYFsdTzt^veNfKe4ucMTv)iI-&@jb$H>%`YYBzXfu_Yu5l$ zLV#3}EMXSAr|23$u>Ye!!T18A@dZTV3y8)S5KYw!{00C3|NjHRj_&{f00v1!K~w_( XTwA@rUFBrW00000NkvXXu0mjfgNKiH literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-surface-zero.png b/fixtures/web-first/chromium/svg-filter-diffuse-surface-zero.png new file mode 100644 index 0000000000000000000000000000000000000000..f26440c7a629af756ab89175af903681b44c0cfe GIT binary patch literal 168 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLGJMSWg$nkcv5P&NFf{C@>r_5EPEQ z5X5G3OmG`p^!GO(H(T1N2MDj=yuy;jWZF2(!FPcg@!YqJ3=IGOdv;mI11(|$S;WjB Xvx4!(8J;V%fFcZ@u6{1-oD!M<`tvcH literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-target-clip.png b/fixtures/web-first/chromium/svg-filter-diffuse-target-clip.png new file mode 100644 index 0000000000000000000000000000000000000000..d796168f8ec1f38565960770a68e2e9a026f5ab5 GIT binary patch literal 527 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1SD0tpLH@YFdp%AaSW-L^Jdmrze5fpt>=4~ zSxqEbBzQUv^-A9V{-Lw4wex*q4XgYC(N4o3&LUEZy!N`RQRz&z>`^=Y^YMnu zcM2!}QQsuUm8NYUQP(T3;1qU1`=i&)^^;AaR2DddJ=ha#z2cqk;jgC;yn4PMev|Bq zs+aY?bM?b=n_5Y~0Y+Hj%BN>+}g9)I;*G+b|O57g4U#1-H<@td84 zs_X2$6qTSYo((QtW^)gCEXg>{>%VNp?fG}@_B>o~a%;NAB;E3)nTrwy4kyj{{o=fV v-vJXidcs-=4~ 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 Eg88CqLI3~& literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-transform-quarter-turn.png b/fixtures/web-first/chromium/svg-filter-diffuse-transform-quarter-turn.png new file mode 100644 index 0000000000000000000000000000000000000000..f0882387556eb575d5c0ae8947dfec33f6fcfb57 GIT binary patch literal 992 zcmV<610Vc}P)000A(NklzG6c7rw&~%{-ZD)Lyq(Tw;+D`Kzd0(0)^D?jfzxU?-ozDM6&n}dK z#f$(fa)wT9!+@)xltRzcjwNLWy6N3O^-2bKD;(;$jpG=K3 zH;v&nS6%IWAVEH!Sf{%C+dqfu~EBNpK*M9x_g@qKAP1{EM=P^SbL1!; zh5I*VL_LY2L#M&wz>lGcaO1;wqYih#P^1D0(>vn1`lzql?1lphpW~m~lb@qw5c^Uw zZ8d`B9D60&zuMq{O>Z$2 zDlZ-=1Tn&Kpy~C{n=j)|Z(xZ`Txrl&uS*9p1RsKmd$Y%(M&r11My|M0Q>@QLx^N+0 zAKTbsf~gr6uXIc3BU`f!Me&p%s6=+FboRSWH+4;K(JIAFb^53shsS)^Tl)L{mhtj* zOx?~L#DdankQVV=z>$O9Vd^m3d{ZrMAA6_GoTZh{vkE`{bin8b$Go&quqID&c6Yv7 z9{&=ec-b$6nrAt1zkTH8CyU)3P%xrRt28y6GpQIa`Un!5fiNg})*s+*Jne5aj=Q|9 zR!JY;lDT88F2U#lUo#M9t~|>D(D206J?v&VE?X--zC9-|9W~R>50#89XS4GxL?RZ5 zh17~{`N>_m3Wm3z@TA;MuV1N#nKsUH@Lix5KmxZ6X!8I6$GdV40~u@}E0`GyO&A*Q*aYPQ PMHoC?{an^LB{Ts57^yG- literal 0 HcmV?d00001 diff --git a/fixtures/web-first/chromium/svg-filter-diffuse-use.png b/fixtures/web-first/chromium/svg-filter-diffuse-use.png new file mode 100644 index 0000000000000000000000000000000000000000..fb45e94d392f84e95521302f162e8d55b1991ac8 GIT binary patch literal 1071 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 D diff --git a/fixtures/web-first/svg-filter-diffuse-blur-before.svg b/fixtures/web-first/svg-filter-diffuse-blur-before.svg new file mode 100644 index 00000000..a7537991 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-blur-before.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-child-order.svg b/fixtures/web-first/svg-filter-diffuse-child-order.svg new file mode 100644 index 00000000..b01882ac --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-child-order.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-color-linear.svg b/fixtures/web-first/svg-filter-diffuse-color-linear.svg new file mode 100644 index 00000000..d6e6fe23 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-color-linear.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-color-srgb.svg b/fixtures/web-first/svg-filter-diffuse-color-srgb.svg new file mode 100644 index 00000000..692bc8f8 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-color-srgb.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-composite-out.svg b/fixtures/web-first/svg-filter-diffuse-composite-out.svg new file mode 100644 index 00000000..14802829 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-composite-out.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-constant-default.svg b/fixtures/web-first/svg-filter-diffuse-constant-default.svg new file mode 100644 index 00000000..dcb6e4a0 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-constant-default.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-constant-empty-zero.svg b/fixtures/web-first/svg-filter-diffuse-constant-empty-zero.svg new file mode 100644 index 00000000..4bc566f5 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-constant-empty-zero.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-constant-negative-clamp.svg b/fixtures/web-first/svg-filter-diffuse-constant-negative-clamp.svg new file mode 100644 index 00000000..01a6a811 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-constant-negative-clamp.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-constant-number-exponent.svg b/fixtures/web-first/svg-filter-diffuse-constant-number-exponent.svg new file mode 100644 index 00000000..5d8c5763 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-constant-number-exponent.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-constant-number-plus.svg b/fixtures/web-first/svg-filter-diffuse-constant-number-plus.svg new file mode 100644 index 00000000..84ca3532 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-constant-number-plus.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-constant-zero.svg b/fixtures/web-first/svg-filter-diffuse-constant-zero.svg new file mode 100644 index 00000000..4d3eabd7 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-constant-zero.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-convolve-before.svg b/fixtures/web-first/svg-filter-diffuse-convolve-before.svg new file mode 100644 index 00000000..95ec275a --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-convolve-before.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-distant-angle-default.svg b/fixtures/web-first/svg-filter-diffuse-distant-angle-default.svg new file mode 100644 index 00000000..04c96dad --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-distant-angle-default.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-distant-angle-large.svg b/fixtures/web-first/svg-filter-diffuse-distant-angle-large.svg new file mode 100644 index 00000000..388edd18 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-distant-angle-large.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-distant-azimuth-negative.svg b/fixtures/web-first/svg-filter-diffuse-distant-azimuth-negative.svg new file mode 100644 index 00000000..2ea7be25 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-distant-azimuth-negative.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-distant-elevation-negative.svg b/fixtures/web-first/svg-filter-diffuse-distant-elevation-negative.svg new file mode 100644 index 00000000..257564d9 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-distant-elevation-negative.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-distant.svg b/fixtures/web-first/svg-filter-diffuse-distant.svg new file mode 100644 index 00000000..d0f80931 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-distant.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-gradient-alpha.svg b/fixtures/web-first/svg-filter-diffuse-gradient-alpha.svg new file mode 100644 index 00000000..3d59f9ab --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-gradient-alpha.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-input-default.svg b/fixtures/web-first/svg-filter-diffuse-input-default.svg new file mode 100644 index 00000000..183cf08f --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-input-default.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-input-source-alpha.svg b/fixtures/web-first/svg-filter-diffuse-input-source-alpha.svg new file mode 100644 index 00000000..692bc8f8 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-input-source-alpha.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-input-source-graphic.svg b/fixtures/web-first/svg-filter-diffuse-input-source-graphic.svg new file mode 100644 index 00000000..b433b1b9 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-input-source-graphic.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-kernel-unit-length-drop.svg b/fixtures/web-first/svg-filter-diffuse-kernel-unit-length-drop.svg new file mode 100644 index 00000000..40a05b9c --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-kernel-unit-length-drop.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/fixtures/web-first/svg-filter-diffuse-kernel-unit-length-invalid-drop.svg b/fixtures/web-first/svg-filter-diffuse-kernel-unit-length-invalid-drop.svg new file mode 100644 index 00000000..f81cb57f --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-kernel-unit-length-invalid-drop.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/fixtures/web-first/svg-filter-diffuse-light-color-alpha-ignored.svg b/fixtures/web-first/svg-filter-diffuse-light-color-alpha-ignored.svg new file mode 100644 index 00000000..2b703ff3 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-light-color-alpha-ignored.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-light-color-currentcolor.svg b/fixtures/web-first/svg-filter-diffuse-light-color-currentcolor.svg new file mode 100644 index 00000000..557706ef --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-light-color-currentcolor.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-light-color-default.svg b/fixtures/web-first/svg-filter-diffuse-light-color-default.svg new file mode 100644 index 00000000..bd3fe35f --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-light-color-default.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-light-color-invalid.svg b/fixtures/web-first/svg-filter-diffuse-light-color-invalid.svg new file mode 100644 index 00000000..0396337c --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-light-color-invalid.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-light-color-rgb.svg b/fixtures/web-first/svg-filter-diffuse-light-color-rgb.svg new file mode 100644 index 00000000..aee937a8 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-light-color-rgb.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-light-color-srgb-function.svg b/fixtures/web-first/svg-filter-diffuse-light-color-srgb-function.svg new file mode 100644 index 00000000..4de2c5d4 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-light-color-srgb-function.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-light-color-transparent.svg b/fixtures/web-first/svg-filter-diffuse-light-color-transparent.svg new file mode 100644 index 00000000..5328db07 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-light-color-transparent.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-missing-light.svg b/fixtures/web-first/svg-filter-diffuse-missing-light.svg new file mode 100644 index 00000000..b0b0a424 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-missing-light.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-nested-light.svg b/fixtures/web-first/svg-filter-diffuse-nested-light.svg new file mode 100644 index 00000000..db69c763 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-nested-light.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-nonlight-child.svg b/fixtures/web-first/svg-filter-diffuse-nonlight-child.svg new file mode 100644 index 00000000..d10e27b7 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-nonlight-child.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-object-box-overflow.svg b/fixtures/web-first/svg-filter-diffuse-object-box-overflow.svg new file mode 100644 index 00000000..0111013d --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-object-box-overflow.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-output-alpha.svg b/fixtures/web-first/svg-filter-diffuse-output-alpha.svg new file mode 100644 index 00000000..692bc8f8 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-output-alpha.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-point-primitive-units.svg b/fixtures/web-first/svg-filter-diffuse-point-primitive-units.svg new file mode 100644 index 00000000..e51ae144 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-point-primitive-units.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-point-x-negative.svg b/fixtures/web-first/svg-filter-diffuse-point-x-negative.svg new file mode 100644 index 00000000..40095860 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-point-x-negative.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-point-y-negative.svg b/fixtures/web-first/svg-filter-diffuse-point-y-negative.svg new file mode 100644 index 00000000..c95e50f8 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-point-y-negative.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-point-z-negative.svg b/fixtures/web-first/svg-filter-diffuse-point-z-negative.svg new file mode 100644 index 00000000..b0ae7af2 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-point-z-negative.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-point.svg b/fixtures/web-first/svg-filter-diffuse-point.svg new file mode 100644 index 00000000..e48af808 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-point.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-region-percent.svg b/fixtures/web-first/svg-filter-diffuse-region-percent.svg new file mode 100644 index 00000000..ae9321c0 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-region-percent.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-cone-active.svg b/fixtures/web-first/svg-filter-diffuse-spot-cone-active.svg new file mode 100644 index 00000000..11a9024c --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-cone-active.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-cone-default.svg b/fixtures/web-first/svg-filter-diffuse-spot-cone-default.svg new file mode 100644 index 00000000..4804b325 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-cone-default.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-cone-negative.svg b/fixtures/web-first/svg-filter-diffuse-spot-cone-negative.svg new file mode 100644 index 00000000..0813019b --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-cone-negative.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-cone-outside.svg b/fixtures/web-first/svg-filter-diffuse-spot-cone-outside.svg new file mode 100644 index 00000000..ff4a1b27 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-cone-outside.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-degenerate.svg b/fixtures/web-first/svg-filter-diffuse-spot-degenerate.svg new file mode 100644 index 00000000..6c36a431 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-degenerate.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-exponent-default.svg b/fixtures/web-first/svg-filter-diffuse-spot-exponent-default.svg new file mode 100644 index 00000000..8a96826d --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-exponent-default.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-exponent-lower-clamp.svg b/fixtures/web-first/svg-filter-diffuse-spot-exponent-lower-clamp.svg new file mode 100644 index 00000000..600a6602 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-exponent-lower-clamp.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-exponent-upper-clamp.svg b/fixtures/web-first/svg-filter-diffuse-spot-exponent-upper-clamp.svg new file mode 100644 index 00000000..31e9c6e3 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-exponent-upper-clamp.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-primitive-units.svg b/fixtures/web-first/svg-filter-diffuse-spot-primitive-units.svg new file mode 100644 index 00000000..b0c25b21 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-primitive-units.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-target-x.svg b/fixtures/web-first/svg-filter-diffuse-spot-target-x.svg new file mode 100644 index 00000000..2bba47df --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-target-x.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-target-y.svg b/fixtures/web-first/svg-filter-diffuse-spot-target-y.svg new file mode 100644 index 00000000..6ad720de --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-target-y.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot-target-z.svg b/fixtures/web-first/svg-filter-diffuse-spot-target-z.svg new file mode 100644 index 00000000..ee1c0e9a --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot-target-z.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-spot.svg b/fixtures/web-first/svg-filter-diffuse-spot.svg new file mode 100644 index 00000000..a2cbb514 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-spot.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-stroke.svg b/fixtures/web-first/svg-filter-diffuse-stroke.svg new file mode 100644 index 00000000..d4b7641f --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-stroke.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-surface-default.svg b/fixtures/web-first/svg-filter-diffuse-surface-default.svg new file mode 100644 index 00000000..0e6fa0f4 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-surface-default.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-surface-empty-zero.svg b/fixtures/web-first/svg-filter-diffuse-surface-empty-zero.svg new file mode 100644 index 00000000..0a358716 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-surface-empty-zero.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-surface-max.svg b/fixtures/web-first/svg-filter-diffuse-surface-max.svg new file mode 100644 index 00000000..a6ffe90d --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-surface-max.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-surface-negative.svg b/fixtures/web-first/svg-filter-diffuse-surface-negative.svg new file mode 100644 index 00000000..4f46d4b4 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-surface-negative.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-surface-number-exponent.svg b/fixtures/web-first/svg-filter-diffuse-surface-number-exponent.svg new file mode 100644 index 00000000..f80746e0 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-surface-number-exponent.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-surface-number-plus.svg b/fixtures/web-first/svg-filter-diffuse-surface-number-plus.svg new file mode 100644 index 00000000..ddcc837c --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-surface-number-plus.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-surface-zero.svg b/fixtures/web-first/svg-filter-diffuse-surface-zero.svg new file mode 100644 index 00000000..65fef0a0 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-surface-zero.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-target-clip.svg b/fixtures/web-first/svg-filter-diffuse-target-clip.svg new file mode 100644 index 00000000..15711b34 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-target-clip.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-target-mask.svg b/fixtures/web-first/svg-filter-diffuse-target-mask.svg new file mode 100644 index 00000000..92c9d47f --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-target-mask.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-target-opacity.svg b/fixtures/web-first/svg-filter-diffuse-target-opacity.svg new file mode 100644 index 00000000..c9cf127b --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-target-opacity.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-transform-axis.svg b/fixtures/web-first/svg-filter-diffuse-transform-axis.svg new file mode 100644 index 00000000..24b22e0d --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-transform-axis.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-transform-quarter-turn.svg b/fixtures/web-first/svg-filter-diffuse-transform-quarter-turn.svg new file mode 100644 index 00000000..5c06cac5 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-transform-quarter-turn.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-transform-reflection.svg b/fixtures/web-first/svg-filter-diffuse-transform-reflection.svg new file mode 100644 index 00000000..e77fbe2e --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-transform-reflection.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-use.svg b/fixtures/web-first/svg-filter-diffuse-use.svg new file mode 100644 index 00000000..2abfdb1f --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-use.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/svg-filter-diffuse-viewbox.svg b/fixtures/web-first/svg-filter-diffuse-viewbox.svg new file mode 100644 index 00000000..2db1af59 --- /dev/null +++ b/fixtures/web-first/svg-filter-diffuse-viewbox.svg @@ -0,0 +1 @@ + diff --git a/fixtures/web-first/unsupported/README.md b/fixtures/web-first/unsupported/README.md index 064180a4..d7097470 100644 --- a/fixtures/web-first/unsupported/README.md +++ b/fixtures/web-first/unsupported/README.md @@ -72,10 +72,16 @@ The scannable, generated view of this register (beside the baked cells) is | `svg-filter-css-functions.svg` · `svg-filter-list.svg` · `svg-filter-list-quoted.svg` | The direct presentation reader carries one same-document URL only. Filter functions and a list of multiple operations are valid members of the wider property grammar and refuse by the stable filter name instead of being mistaken for that single URL. Quoted and unquoted URL tokens take the same branch. | | `svg-filter-external.svg` · `svg-filter-root.svg` | External resource resolution and the root host CSS-layer route stay outside this self-contained SVG-local frame. An external reference skips its target; an active root filter refuses in both admissions because there is no smaller honest hole. | | `svg-filter-href.svg` | Refuse `` inheritance before graph construction. Dropping the template edge could change primitive order, inherited attributes, inputs, and every output pixel. | -| `svg-filter-primitive.svg` | Any unrepresented `fe*` child invalidates graph construction transactionally. The witness has advanced to `feDiffuseLighting` after a supported flood prefix; it skips the whole affected target, so that prefix can never escape as a plausible filtered result. | +| `svg-filter-primitive.svg` | Any unrepresented `fe*` child invalidates graph construction transactionally. The witness has advanced to `feSpecularLighting` after a supported flood prefix; it skips the whole affected target, so that prefix can never escape as a plausible filtered result. | | `svg-filter-convolve-transform-precision.svg` | Refuse `feConvolveMatrix` under a target mapping outside axis maps and exact quarter turns. Fractional translation/scale, reflection, and exact quarter turns are exact. A sampled 17-degree rotation differs by 462 pixels at maximum channel delta 15 and a shear by 632 at delta 13; arbitrarily small sampled rotation/shear values reproduce the class (measured, not celled). | | `svg-filter-convolve-paint-server-precision.svg` | Refuse source-dependent `feConvolveMatrix` when the isolated source uses a paint-server fill or stroke. Sampled linear and radial fills differ by 1,425 and 1,658 pixels at maximum channel delta 7; a gradient stroke differs by 609 at delta 7. Generated-only filter inputs remain exact (measured, not celled). | | `svg-filter-convolve-arithmetic-range.svg` | Refuse a nonzero `divisor` whose reciprocal overflows finite `f32`. Chromium executes the valid number and the sampled output equals a nearby finite-gain control, while the resolved contract admits only finite gain. This is a narrow arithmetic-range patrol, not a second source parser (measured, not celled). | +| `svg-filter-diffuse-transform-precision.svg` | Refuse `feDiffuseLighting` under a target mapping outside axis maps and exact quarter turns. Translation, arbitrary sampled axis scales, reflection, and exact quarter turns are exact. A sampled 17-degree rotation differs by 551 pixels at maximum channel delta 15, a shear by 543 at delta 12, and a general affine map by 624 at delta 12 (measured, not celled). | +| `svg-filter-diffuse-composition-precision.svg` | Refuse diffuse lighting as the foreground of `feComposite` `in` or `atop` when the second input is source-derived. The sampled `in` witness differs by 69 pixels at maximum delta 180. `over`, `out`, `xor`, `lighter`, arithmetic, blend, merge, generated-background composition, lighting in the second input, and neighboring one-input spatial operations are exact (measured, not celled). | +| `svg-filter-lighting-color-css.svg` | Refuse CSS-authored `lighting-color` at its real ingress. Chromium lets the inline declaration beat the direct presentation attribute; the pinned Servo-mode cascade has no lighting-color longhand, so the target is skipped and declared instead of painting either color. Stylesheet ingress is likewise declared at the sheet. The direct attribute remains a separate admitted subset. | +| `svg-filter-lighting-color-inherit.svg` | Refuse explicit `inherit` on `lighting-color`. Chromium takes the ancestor filter's computed light color while the property is otherwise non-inherited. Reconstructing that edge needs the unavailable cascaded longhand; reset keywords retain the initial white and remain admitted. | +| `svg-filter-lighting-color-var.svg` | Refuse custom-property substitution in direct `lighting-color`. Chromium substitutes the green control exactly; the direct reader cannot prove which declaration supplies the value, so even a benign substitution over-refuses under the independent `var()` row. | +| `svg-filter-lighting-color-syntax.svg` | Refuse wider color syntax outside the admitted sRGB subset. Chromium honors the sampled Lab and HSL colors, and a Lab control differing by only six channel levels proves the conversion is byte-sensitive. The wider color-function rows carry this gap; it does not become an invented lighting-only parser. | | `svg-filter-turbulence-transform-precision.svg` | Refuse `feTurbulence` under a general rotation or shear. Axis maps, fractional translation, reflection, and exact quarter turns are exact; a sampled 17-degree rotation differs by 3,173 pixels at maximum channel delta 7 and a shear by 3,110 at delta 6 (measured, not celled). | | `svg-filter-displacement-transform-precision.svg` | Refuse `feDisplacementMap` under a general rotation or shear. Axis maps, fractional translation, reflection, and exact quarter turns are exact; a sampled 17-degree rotation differs by 280 pixels at maximum channel delta 13 and a shear by 360 at delta 18 (measured, not celled). | | `svg-filter-displacement-clip-precision.svg` | Refuse `feDisplacementMap` across a geometric `clip-path`. The sampled path clip differs by 35 pixels at maximum channel delta 2 (measured, not celled); opacity without the clip is exact and celled. | diff --git a/fixtures/web-first/unsupported/svg-filter-diffuse-composition-precision.svg b/fixtures/web-first/unsupported/svg-filter-diffuse-composition-precision.svg new file mode 100644 index 00000000..9f9c1eb0 --- /dev/null +++ b/fixtures/web-first/unsupported/svg-filter-diffuse-composition-precision.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + diff --git a/fixtures/web-first/unsupported/svg-filter-diffuse-transform-precision.svg b/fixtures/web-first/unsupported/svg-filter-diffuse-transform-precision.svg new file mode 100644 index 00000000..d25ee73f --- /dev/null +++ b/fixtures/web-first/unsupported/svg-filter-diffuse-transform-precision.svg @@ -0,0 +1,11 @@ + + + + + + + + + + diff --git a/fixtures/web-first/unsupported/svg-filter-lighting-color-css.svg b/fixtures/web-first/unsupported/svg-filter-lighting-color-css.svg new file mode 100644 index 00000000..67bfa336 --- /dev/null +++ b/fixtures/web-first/unsupported/svg-filter-lighting-color-css.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/fixtures/web-first/unsupported/svg-filter-lighting-color-inherit.svg b/fixtures/web-first/unsupported/svg-filter-lighting-color-inherit.svg new file mode 100644 index 00000000..86b7f8e8 --- /dev/null +++ b/fixtures/web-first/unsupported/svg-filter-lighting-color-inherit.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/fixtures/web-first/unsupported/svg-filter-lighting-color-syntax.svg b/fixtures/web-first/unsupported/svg-filter-lighting-color-syntax.svg new file mode 100644 index 00000000..6ed91422 --- /dev/null +++ b/fixtures/web-first/unsupported/svg-filter-lighting-color-syntax.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/fixtures/web-first/unsupported/svg-filter-lighting-color-var.svg b/fixtures/web-first/unsupported/svg-filter-lighting-color-var.svg new file mode 100644 index 00000000..09cbe979 --- /dev/null +++ b/fixtures/web-first/unsupported/svg-filter-lighting-color-var.svg @@ -0,0 +1,9 @@ + + + + + + + + diff --git a/fixtures/web-first/unsupported/svg-filter-primitive.svg b/fixtures/web-first/unsupported/svg-filter-primitive.svg index 8852b56e..217ad752 100644 --- a/fixtures/web-first/unsupported/svg-filter-primitive.svg +++ b/fixtures/web-first/unsupported/svg-filter-primitive.svg @@ -2,9 +2,9 @@ - + - + From d6e158b2b0cd4e2ac42c4378ef8059a00a5a0281 Mon Sep 17 00:00:00 2001 From: Universe Date: Thu, 27 Aug 2026 08:26:42 +0900 Subject: [PATCH 2/2] ci: give seam architecture its cold-build budget --- .github/workflows/consolidation-gates.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/consolidation-gates.yml b/.github/workflows/consolidation-gates.yml index 120f65a1..3f42414e 100644 --- a/.github/workflows/consolidation-gates.yml +++ b/.github/workflows/consolidation-gates.yml @@ -87,7 +87,7 @@ jobs: needs: scope if: needs.scope.outputs.engine == 'true' runs-on: ubuntu-24.04 - timeout-minutes: 30 + timeout-minutes: 45 steps: - name: Checkout head revision uses: actions/checkout@v4