code wiki / _hdl_build / nx_srcset_lib.nx
nx_srcset_lib.nx
buildroot/runtime/_hdl_build/nx_srcset_lib.nx
about
nx_srcset_lib.nx -- BR14: CHOOSE THE ONE IMAGE URL A RENDER SHOULD FETCH FOR THIS ELEMENT AT THIS
VIEWPORT. The compare board's browser rung BR14 (symbol bi_srcset) and the named debt row
`images-lazy`: "Lazy-load / srcset / data-src images are not fetched ... so media-heavy pages render
most figures blank even though the decoders are byte-exact." The decoders were never the problem --
br_extract only ever looked at the `src` attribute, so a lazy-loaded <img> handed the renderer a
`data:` placeholder (or nothing at all) and the real URL sat unread in srcset / data-src.
WHAT THIS IS NOT: nx_img_harvest / nx_media_harvest COLLECT every image URL on a page (scraping --
they want ALL srcset candidates). This SELECTS exactly one, for one element, at one viewport. Same
attribute, opposite question, so it is a second ruler for a second job, not a duplicate of the first.
nx_cms_image's img_srcset_widths GENERATES a srcset ladder for publishing -- the inverse direction.
NO ALLOCATION. The selection needs no candidate list: "smallest candidate that still covers the
target, else the largest available" is two running extrema, computable in ONE pass over the
attribute bytes. Scratch is PASSED IN (BI_SCRATCH_SLOTS) so nothing here allocates per <img>.
NO NEW BYTES. Every URL this returns is a byte range INTO THE CALLER'S OWN BUFFER (off,len), which
is exactly the contract br_extract/page.bsrc_off already speaks. A srcset candidate is a contiguous
substring of the attribute value, so selection is a pair of integers -- no copy, no arena, no cap.
INTEGER ONLY. A pixel-density descriptor is written as a decimal ("1.5x"), so every density here is
PERMIL (1x = 1000, 1.5x = 1500, 2x = 2000). Permil is the estate's standing fixed-point unit and
three fractional digits covers every density any shipping site writes.
DELIBERATE DIVERGENCES FROM THE HTML SPEC LETTER, each named so the next reader does not have to
rediscover which are bugs and which are choices:
* descriptor suffix accepted in EITHER case (`2X` as well as `2x`). The spec's parser is
lowercase-only. There is no other meaning for `2X`, and the divergence can only ever ADD a
picture, never remove one -- it fails in the direction of rendering more, not less.
* `sizes` is evaluated only in the two forms decidable WITHOUT a media-query engine (a bare
`<n>px` and a bare `<n>vw`). Anything carrying a media condition or a list REFUSES BY NAME
(BI_SIZES_UNPARSED) and falls back to HTML's own default source size of 100vw, so a caller can
report that it did not honour the author's sizes instead of silently pretending it did.
* fractional digits past permil resolution are TRUNCATED toward zero, never rounded, so a
density can only ever select a LARGER candidate than the exact value would -- again the
direction that renders more.
dependencies 2 imports · 3 importers
imports: nx_syscalls.nxnx_dom_query.nx
imported by: nx_browser_render.nxnx_browser_render_gif_t139.nxnx_srcset_lib_gate.nx
structs
| none |
consts
| 42 | const BI_TAB: i64 = 9 |
| 43 | const BI_LF: i64 = 10 |
| 44 | const BI_FF: i64 = 12 |
| 45 | const BI_CR: i64 = 13 |
| 46 | const BI_SPACE: i64 = 32 |
| 47 | const BI_COMMA: i64 = 44 |
| 48 | const BI_DOT: i64 = 46 |
| 49 | const BI_ZERO: i64 = 48 |
| 50 | const BI_NINE: i64 = 57 |
| 51 | const BI_UC_A: i64 = 65 |
| 52 | const BI_UC_Z: i64 = 90 |
| 53 | const BI_LC_P: i64 = 112 |
| 54 | const BI_LC_V: i64 = 118 |
| 55 | const BI_LC_W: i64 = 119 |
| 56 | const BI_LC_X: i64 = 120 |
| 57 | const BI_CASE_DELTA: i64 = 32 |
| 60 | const BI_PERMIL_DIGITS: i64 = 3 |
| 61 | const BI_PERMIL_ONE: i64 = 1000 |
| 62 | const BI_B10: i64 = 10 |
| 68 | const BI_SAFE_DIGITS: i64 = 18 |
| 69 | const BI_NUM_MAX_DIGITS: i64 = BI_SAFE_DIGITS - BI_PERMIL_DIGITS |
| 72 | const BI_VW_PER_VIEWPORT: i64 = 100 |
| 79 | const BI_SCRATCH_SLOTS: i64 = 4 |
| 80 | const BI_SC_NUM: i64 = 0 |
| 81 | const BI_SC_AOFF: i64 = 1 |
| 82 | const BI_SC_ALEN: i64 = 2 |
| 83 | const BI_SC_SIZECODE: i64 = 3 |
| 86 | const BI_NO_CANDIDATES: i64 = 0 |
| 87 | const BI_PICK_W: i64 = 1 // chosen by width descriptor against the derived target |
| 88 | const BI_PICK_X: i64 = 2 // chosen by pixel-density descriptor against the device ratio |
| 89 | const BI_MIXED_DESCRIPTORS: i64 = 0 - 2 // w and x in one list: invalid HTML, the WHOLE attribute is ignored |
| 90 | const BI_BAD_TARGET: i64 = 0 - 3 // caller passed a non-positive size or density -- refuse, never guess |
| 93 | const BI_DESC_DROP: i64 = 0 |
| 94 | const BI_DESC_W: i64 = 1 |
| 95 | const BI_DESC_X: i64 = 2 |
| 99 | const BI_SRC_NONE: i64 = 0 // this element carries no usable source at all |
| 100 | const BI_SRC_SRCSET: i64 = 1 |
| 101 | const BI_SRC_SRC: i64 = 2 // the plain eager path -- byte-for-byte what br_extract chose before |
| 102 | const BI_SRC_DATA_SRCSET: i64 = 3 |
| 103 | const BI_SRC_DATA_ATTR: i64 = 4 |
| 104 | const BI_SRC_PLACEHOLDER: i64 = 5 // ONLY a data: src existed; returned unchanged, exactly as before |
| 107 | const BI_SIZES_DEFAULT: i64 = 0 // no sizes attribute -- HTML's own default source size is 100vw |
| 108 | const BI_SIZES_PX: i64 = 1 |
| 109 | const BI_SIZES_VW: i64 = 2 |
| 110 | const BI_SIZES_UNPARSED: i64 = 3 // a media condition or list this lib does not evaluate -> 100vw |
functions
| 112 | func bi_lc(c: i64) -> i64 { if c >= BI_UC_A { if c <= BI_UC_Z { return c + BI_CASE_DELTA } } return c } |
| 117 | func bi_is_ws(c: i64) -> i64 |
| 126 | func bi_is_digit(c: i64) -> i64 { if c >= BI_ZERO { if c <= BI_NINE { return 1 } } return 0 } called by 1: bi_num_permil |
| 128 | func bi_has_dot(buf: *u8, a: i64, b: i64) -> i64 called by 1: bi_desc |
| 142 | func bi_num_permil(buf: *u8, a: i64, b: i64, out: *i64) -> i64 |
| 193 | func bi_desc(buf: *u8, a: i64, b: i64, out: *i64) -> i64 |
| 230 | func bi_srcset(buf: *u8, off: i64, len: i64, size_px: i64, dpr_permil: i64, sc: *i64, out_off: *i64, out_len: *i64) -> i64 |
| 373 | func bi_sizes_px(buf: *u8, off: i64, len: i64, vw_px: i64, sc: *i64) -> i64 |
| 413 | func bi_is_placeholder(buf: *u8, off: i64, len: i64) -> i64 |
| 432 | func bi_img_lazy(buf: *u8, tag_off: i64, tag_len: i64, sc: *i64) -> i64 |
| 464 | func bi_img_source(buf: *u8, tag_off: i64, tag_len: i64, vw_px: i64, dpr_permil: i64, sc: *i64, out_off: *i64, out_len: *i64) -> i64 |