nx_paint_blend.nx
buildroot/runtime/nx_paint_blend.nx
about
nx_paint_blend.nx -- alpha-compositing rect fill into a Framebuffer
using the standard "source over" Porter-Duff operator. Phase 4
fourth primitive of NISHI_BROWSER_ROADMAP. Pair to nx_paint_solid_rect
(which OVERWRITES pixels regardless of source alpha); this primitive
MIXES per pixel.
Formulas (Porter-Duff "A over B", premultiplied math executed with
straight-alpha 8-bit source + destination):
out.a = src.a + dst.a * (255 - src.a) / 255
out.r = (src.r * src.a + dst.r * (255 - src.a) * dst.a / 255) / out.a (compositing)
Simplified for the common case where destination is opaque
(dst.a = 255), reducing to:
out.r = (src.r * src.a + dst.r * (255 - src.a)) / 255
out.g = (src.g * src.a + dst.g * (255 - src.a)) / 255
out.b = (src.b * src.a + dst.b * (255 - src.a)) / 255
out.a = 255
We use the simplified form because the framebuffer's destination
is always opaque (no transparency on the final screen surface).
When src.a == 0 the pixel is unchanged (early-out).
When src.a == 255 the result is equivalent to nx_paint_solid_rect
(full overwrite, faster path).
What it does NOT handle yet (Phase 4b queued):
- non-opaque destination (would need premultiplied-alpha buffer)
- non-source-over operators (multiply, screen, overlay, etc.)
- per-pixel-alpha source (currently solid color only)
- SIMD acceleration
Per cardinal feedback-honest-perf-verdict-no-aspirational-claims:
gap list is EXACT.
genealogy_id: porter_duff_compositing_1984 + w3c_css_compositing_module_1
lineage_id: nishi_browser_paint_blend_v1
dependencies 3 imports · 1 importers
imports: nx_syscalls.nxnx_css_color_decode.nxnx_paint_solid_rect.nx
imported by: nx_paint_blend_test.nx
structs
| none |
consts
| none |
functions
| 46 | func _blend_pixel(fb_pixels: *u8, off: i64, called by 1: nx_paint_blend_rect |
| 76 | func nx_paint_blend_rect(fb: *Framebuffer, |