Repository navigation
feat(scene): overlays load their own images and fonts - #62
Conversation
Quest-Claim: a97c81d77de75a2c
An overlay names images and fonts as data: URLs or files under the scene file's directory. The source reads and checks each before the overlay opens, and the overlay's document fetches from those bytes alone, so its first frame has them and it never touches the network. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… Blitz draws them Images decode in check and go into the document's cache before its first resolve, so a background an animation brings in later draws at once, and a corrupt one fails the overlay. Fonts decompress and register in check. url() is allowed only in background, background-image, and @font-face src. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 45 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 4b7b203
No actionable findings in the reviewed changes.
Overall direction: The validated asset snapshot carried with the overlay keeps source preparation and compositor rendering consistent. Decoding images before the render-thread handoff and preloading Blitz’s image cache addresses first-frame and later-animation asset availability without render-thread file I/O.
Verification limits: GitHub-only static review of the loader, source/compositor handoff, regression tests, and the pinned Blitz resource-handling code. I did not run quest context, quest check, tests, or GPU/platform validation. The author reports passing local checks; the latest GitHub Check run was still in progress when inspected.
A restart lays the overlay out again through #62's open, so its preloaded images and served fonts survive it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Finishes
quest/m1/overlay-assets.md(from moq-dev/studio#34).Problem
An overlay could not show a logo or set text in a brand face:
checkrefused<img>,@font-face, and everyurl(), and its Blitz document had no net provider. A relative<img src>also panicked inside Blitz's parser duringcheck, because the document's default base URL (adata:URL) cannot resolve one.Approach
overlay::check(html, dir)now returns aContent: the HTML plus every asset it names, read and checked on the source's task, off the render thread. URLs resolve against the scene file's directory as afile:base, exactly as the document will resolve them.data:URLs decode per the Fetch standard (percent-decoding, forgiving base64).file:URLs must canonicalize under the canonical scene directory, which refuses.., absolute paths, and symlinks out of it.wuff, as Blitz does) and register with fontique the way Blitz will register them.<img>(withsrcandalt) and top-level@font-face(font-family,src,font-weight,font-style,font-display) are now allowed.url()is found by walking each declaration's CSS tokens. It is allowed only inbackground,background-image, and@font-facesrc, the places Blitz draws or loads it, socontent: url()or aurl()in a custom property is refused by name.local(),image-set(), andsrc()are refused, as are descriptors Blitz ignores, such asunicode-range, and@font-faceinside@media(Blitz reads only top-level ones).openputs every decoded image in the document's image cache before the first resolve, using Blitz's publicload_resource. Blitz checks that cache before any fetch, so an<img>, a background, or a background an animation brings in later draws with no fetch. ANetProvider(Assets) serves fonts from memory, and they land in the open's resolve. The first frame on program therefore has every asset. If the document ever fetches a URLcheckdid not read, its paint fails, naming the URL.Picture::Overlaycarries theContent, so the HTML and assets the compositor opens always match.wofffeature is on, so it does not skip asrcthat names a.woff/.woff2file or format. It receives the already decompressed bytes either way.Measured on this Mac (release build), with a full-frame 1920x1080 PNG: the overlay thread's open and first resolve take 0.3 ms. Before images were preloaded, Blitz decoded the PNG on that thread, which took 24 ms, and the compositor's next paint waits on that thread. The 23 ms decode now runs in
checkon the source's task, where an image source already decodes its picture. A TTF costs 0.4 ms incheckand 0.17 ms at open.Impact
<img src>,url()in CSS, and@font-face. These load fromdata:URLs or from files under the scene file's directory. Anything else fails the source, naming the URL.overlayandPictureare crate-private. The scene file format is unchanged. Existing overlays behave the same.base64andpercent-encoding, both already in the lockfile, andwuff, which Blitz'swofffeature also brings in, along withbrotli-decompressor.Choices made without asking
local()in@font-faceis refused, not skipped. Blitz ignores it, and the machine's fonts are deliberately left out, so asrc: local(X), url(y)list must droplocal(X).url()in asrclist is read and must load, including fallbacks Blitz would never fetch. This fails loud rather than letting a broken fallback through.url()in a custom property is refused, even when avar()would only carry it intobackground. Tracking where eachvar()lands would be needed to allow it; writingurl()inbackgrounddirectly covers the same use.browser::MAX_SIDE, the largest an overlay can be), which bounds what Blitz's decode can allocate.wofffeature) because brand kits usually ship web fonts as WOFF2.<img>takes nowidth/heightattributes. CSS sizes it, consistent with the existing attribute rule.srcorhrefis not a URL (such ashttp://[).checkcontains this withcatch_unwindand reports it as an error. The overlay thread never sees such HTML.Alternatives
checkreports errors when the source starts.Follow-ups
<body>background color across the canvas but not a background image, sobody { background: url(logo.png) }on an empty body draws nothing. This is upstream (DioxusLabs/blitz). Until then, an overlay can put the image on a sized element.src/href(see above). An upstream fix would letcheckdropcatch_unwind.Validation
just ci(viaquest gate) passed on4b7b203: lints, and 240 tests.cargo nextest run -p moq-scene --lib --run-ignored only -E 'test(/overlay/)'passed 4/4, including the newan_overlay_draws_its_image_on_its_first_frame.<img>fromdata:, a background from a file, a background a@keyframesbrings in at its end, and a TTF face via@font-face. They also cover refusals (other schemes,.., an absolute path, a symlink out, a missing file, a directory, a wrong type, an oversized image, a truncated PNG, a WOFF2 that does not decompress, bad base64,url()incontentor a custom property,local(),image-set(),unicode-range, and nested@font-face) anddata:decoding. With the image preload disabled, the open test fails.Review
Codex (
quest review), gpt-6.1-sol, medium effort. Last round: round 2 on head4b7b203595c88fb90f9a8eb7086bcc8b3ea473a4, 0 findings.Round 1 (head
97c4128), all fixed in4b7b203:checkand preloaded into Blitz's image cache, so no image is ever fetched.check.content: url(logo.png)passed but Blitz never draws image content. Fixed:url()is allowed only inbackground,background-image, and@font-facesrc.(Written by Claude Opus 5.5)