Skip to content

Add NamedImage API support#806

Merged
Kyle-Ye merged 19 commits intomainfrom
feature/named_image
Mar 1, 2026
Merged

Add NamedImage API support#806
Kyle-Ye merged 19 commits intomainfrom
feature/named_image

Conversation

@Kyle-Ye
Copy link
Collaborator

@Kyle-Ye Kyle-Ye commented Mar 1, 2026

No description provided.

Kyle-Ye added 19 commits March 2, 2026 03:25
- Use _CUIThemeVectorGlyphWeight enum for Font.Weight.glyphWeight
- Add Image.HashableScale.glyphSize mapping (small→1, medium→2, large→3)
- Fix namedVectorGlyph call to pass glyphSize from imageScale instead of glyphWeight
- Pass Locale directly to namedVectorGlyph locale parameter (NSLocale bridging)
- Force unwrap CUIDeviceIdiom(rawValue:) instead of fallback to .universal
- Remove explicit get blocks from computed subscripts
- Move #if OPENSWIFTUI_LINK_COREUI guards to cover individual subscripts
- Add platform unimplemented warning for BitmapKey subscript on non-CoreUI
- Use guard let in decode(_:) for cleaner control flow
- Add fillVariant(_:name:) for fill symbol variant lookup
- Add mayContainSymbol(_:) for checking if catalog contains a symbol
- Add findShapeAndFillVariantName(_:base:body:) for shape+fill variant resolution
- Add findName(_:base:body:) for full variant name resolution
- Add SystemAssetManager struct with systemAssetManager/privateSystemAssetManager statics
- SystemAssetManager: proper struct with catalog, fillMapping, nameAliases,
  symbols fields; init(internalUse:) loads from CoreGlyphs bundles
- catalog getter: returns SystemAssetManager.catalog for system locations
- fillVariant: uses fillMapping dict for system, name+".fill" for bundle
- mayContainSymbol: uses symbols array for system, true for bundle
- Add aliasedName() using nameAliases dictionary
- findShapeAndFillVariantName: calls aliasedName() before lookups
- findName: handles .slash variant, normalizes .background semantics
- Add _SimulatorSystemRootDirectory() wrapper for GSSystemRootDirectory
- Add GraphicsServices_Private SPI module
Move SystemAssetManager and its static instances outside of
#if OPENSWIFTUI_LINK_COREUI, keeping only the CUICatalog field
and init logic conditional.
@Kyle-Ye Kyle-Ye merged commit 1aaa7bf into main Mar 1, 2026
3 of 8 checks passed
@Kyle-Ye Kyle-Ye deleted the feature/named_image branch March 1, 2026 20:04
@augmentcode
Copy link

augmentcode bot commented Mar 1, 2026

🤖 Augment PR Summary

Summary: This PR adds initial support for SwiftUI-style named images (asset catalog images and SF Symbols), including a CoreUI-backed resolution path when enabled.

Changes:

  • Implemented a large NamedImage implementation with cache keys, bitmap decoding, and (WIP) vector symbol lookup/resolution.
  • Added Image initializers for bundle images, system symbols, and variable-value symbols, plus internal system symbol SPI.
  • Introduced SFSymbols shims using dlopen/dlsym to access private SFSymbols metadata without hard-linking.
  • Added Image.Location behavior for system/private-system/bundle catalogs and symbol variant name resolution utilities.
  • Extended image scale support (_watch_toolbar_medium) and added Image.HashableScale for cache keys and glyph sizing.
  • Added Protobuf encoders for Image.Location, NamedImage.Key, and NamedImage.BitmapKey, plus an encoder helper for “attached values”.
  • Added a GraphicsServices shim for _SimulatorSystemRootDirectory() and a CoreText shim for accessibility-bold weight mapping.
  • Added tests covering SFSymbols shim access and basic NamedImage key/cache behaviors.

Technical Notes: Many of the CoreUI/vector symbol pieces are guarded behind OPENSWIFTUI_LINK_COREUI and marked WIP/TBA, indicating the implementation is still in-progress.

🤖 Was this summary useful? React with 👍 or 👎

Copy link

@augmentcode augmentcode bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 4 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

) -> NamedImage.VectorInfo? {
let environment = context.environment
let variants = environment.symbolVariants
let result: NamedImage.VectorInfo? = location.findName(variants, base: name) { candidateName in
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

location.findName(variants, base: name) { candidateName in … } ignores candidateName and always calls vectorInfo(name: name, …), so symbol variant/alias name lookup won’t actually affect the asset lookup here.

Severity: high

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

}
let gamut = key.displayGamut.cuiDisplayGamut
let idiom = CUIDeviceIdiom(rawValue: environment.cuiAssetIdiom) ?? .universal
let idiom = CUIDeviceIdiom(rawValue: environment.cuiAssetIdiom)!
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change force-unwraps CUIDeviceIdiom(rawValue: environment.cuiAssetIdiom)!; if cuiAssetIdiom ever contains an unexpected value, this will crash (previously it safely fell back to .universal).

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

}
#if OPENSWIFTUI_LINK_COREUI
let fullPath = _SimulatorSystemRootDirectory() + bundlePath
let bundle = Bundle(path: fullPath)!
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bundle(path: fullPath)! and try! CUICatalog(...) will crash at runtime if the CoreGlyphs bundle/catalog isn’t present or can’t be opened (e.g. unusual simulator roots or stripped environments) when OPENSWIFTUI_LINK_COREUI is enabled.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

)
let environment = EnvironmentValues()
let resolved = provider.resolveError(in: environment)
#expect(resolved.image.scale == 0)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveError(in:) currently constructs a GraphicsImage with scale: 1.0, but this test asserts resolved.image.scale == 0, which looks inconsistent and likely to fail.

Severity: medium

Fix This in Augment

🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant