Rename AlignEntry::BeginTurtle/EndTurtle to BeginClip/EndClip — these
entries control GPU clip rect stacking, not turtle lifecycle.
Add push_clip_rect/pop_clip_rect to Cx2d: lightweight API for manual
clip rect control without creating a full turtle. The existing
clip_and_shift_align_list pass intersects nested clip rects and writes
draw_clip into draw call instances.
Co-authored-by: ant <ant@offline.click>
Add Texture::set_data_u32(cx, width, height, data) that replaces pixel
data and dimensions in one call. Unlike put_back_vec_u32, this also
updates width/height, making it safe for image sources that change
resolution (animated images, lazy-loaded placeholders).
Co-authored-by: ant <ant@offline.click>
dispatch_studio_msg pushed to screenshot_requests but never
triggered a redraw. The GL readback that captures the screenshot
only runs during the render path, so the request was never
serviced in windowed backends (Wayland, X11, macOS).
Co-authored-by: ant <ant@offline.click>
The Contents.json only had a single universal+platform entry, which is
only recognized by iOS 16+. Add classic per-idiom entries (iphone, ipad,
ios-marketing) so actool compiles both sets into Assets.car. iOS 15
falls back to the idiom-based entries.
Co-authored-by: ant <ant@offline.click>
Move font family registration out of on_custom_apply (script apply time)
and into ensure_fonts_loaded (draw time). This avoids redundant work when
the same FontFamily is applied to hundreds of widgets during a frame.
ensure_fonts_loaded now has a fast path that checks is_font_family_complete()
and returns immediately when all expected members are already registered.
The slow path calls load_all_script_resources() to progress pending loads
before falling back to update_font_definitions().
Other changes:
- FontFamilyDefinition gains expected_member_count to distinguish partial
from complete registrations.
- set_font_family_definition skips cache eviction when the definition or
cached family is already equivalent.
- load_font_family now clones the definition instead of removing it,
allowing re-loads after cache eviction without losing the definition.
- Loader::font_family_definitions and Layouter::loader are now pub(crate)
to support the completeness query from Fonts.
---
Review observations (not yet addressed):
1. STALE FAMILY ON RE-APPLY (medium risk): If a FontFamily is re-applied
with different members but the same object index (same family_id), the
fast path in ensure_fonts_loaded will see the old definition as
"complete" and never call update_font_definitions with the new members.
Fix: compare current member handles against stored definition, or set a
dirty flag in on_custom_apply that forces one refresh.
2. UNNECESSARY LAYOUT CACHE FLUSH (medium risk): Layouter::set_font_family_definition
unconditionally clears cached_params and cached_results even when
Loader::set_font_family_definition short-circuits as unchanged. During
partial-load states ensure_fonts_loaded may call update repeatedly with
identical partial definitions, flushing the text layout cache each time.
Fix: propagate a changed bool from Loader and only clear when true.
3. COMPLETENESS IGNORES CACHE-ONLY STATE (low risk): is_font_family_complete
only checks font_family_definitions, not font_family_cache. If a family
was already loaded into cache and its definition consumed, completeness
returns false. The new early-return in set_font_family_definition for
cache-match mitigates this in practice but the invariant is fragile.
Fix: also check font_family_cache in is_font_family_complete, or ensure
definitions are always retained (which this diff partly does by switching
from remove to get+clone in load_font_family).
Co-authored-by: ant <ant@offline.click>