diff --git a/.isu/issues.json b/.isu/issues.json index 18e7324..c410dd4 100644 --- a/.isu/issues.json +++ b/.isu/issues.json @@ -1,5 +1,5 @@ { - "next_id": 415, + "next_id": 416, "issues": [ { "id": 1, @@ -5091,6 +5091,19 @@ "author": "piefev", "state": "open", "created_at": "2026-07-18T12:53:38Z" + }, + { + "id": 415, + "repo": "we", + "title": "Opera parity remains blocked after glyph mask coverage ramp", + "body": "Parent: isu issue 281.\n\nThis pass steepened Metal glyph-mask coverage with a smoothstep ramp so supersampled glyph masks keep crisper subpixel edges. The focused Opera scenario improved, but still cannot remove its xfail.\n\nRepro:\n cargo run -p we-e2e -- --scenario crates/e2e/scenarios/real-web/opera.com.we --out-dir crates/e2e/artifacts\n\nCurrent result after this pass:\n- desktop L96: 89.29% match (131604/1228500 px differ, tol=4, max_diff=0.1000%)\n- mobile L111: 82.70% match (56941/329160 px differ, tol=4, max_diff=0.1000%)\n- DOM and interactivity assertions pass; console captures only expected offline third-party fetch misses.\n\nArtifacts:\n- crates/e2e/artifacts/real-web/opera.com/desktop.png\n- crates/e2e/artifacts/real-web/opera.com/desktop.png.diff.png\n- crates/e2e/artifacts/real-web/opera.com/mobile.png\n- crates/e2e/artifacts/real-web/opera.com/mobile.png.diff.png\n\nRemaining visible blockers are still first-viewport WebP/image parity plus residual glyph antialiasing and small cookie-panel edge/text fidelity gaps. Keep crates/e2e/scenarios/real-web/opera.com.we xfailed until both Chromium screenshot assertions pass within the committed threshold.", + "labels": [ + "real-web" + ], + "assigned": [], + "author": "piefev", + "state": "open", + "created_at": "2026-07-18T13:23:09Z" } ] } diff --git a/crates/platform/src/metal.rs b/crates/platform/src/metal.rs index 389f19d..b64aaf4 100644 --- a/crates/platform/src/metal.rs +++ b/crates/platform/src/metal.rs @@ -479,7 +479,10 @@ fragment float4 fragment_main( float coverage = clamp(0.5 - d / aa, 0.0, 1.0); c = float4(in.color.rgb, in.color.a * coverage); } else if (in.use_texture > 1.5) { - float coverage = tex.sample(samp, in.tex_coord).r; + // Glyph masks are supersampled coverage fields. Steepening the + // middle of the ramp keeps subpixel edges crisp without changing + // fully transparent or fully covered pixels. + float coverage = smoothstep(0.3, 0.7, tex.sample(samp, in.tex_coord).r); c = float4(in.color.rgb, in.color.a * coverage); } else { float4 tex_color = tex.sample(samp, in.tex_coord); @@ -1948,7 +1951,8 @@ mod tests { #[test] fn shader_treats_mask_texture_as_alpha_coverage() { - assert!(SHADER_SOURCE.contains("float coverage = tex.sample(samp, in.tex_coord).r;")); + assert!(SHADER_SOURCE + .contains("float coverage = smoothstep(0.3, 0.7, tex.sample(samp, in.tex_coord).r);")); assert!(SHADER_SOURCE.contains("c = float4(in.color.rgb, in.color.a * coverage);")); }