@@ -153,15 +153,24 @@ enum AssetUtil {
153153 let type = rendition. getUInt ( forKey: " type " ) ?? 0
154154
155155 let isVector = type == 9
156- let ( width, height, unslicedImage) = resolveImageDimensions ( rendition, isVector)
156+ var ( width, height, unslicedImage) = resolveImageDimensions ( rendition, isVector)
157157 let assetType = determineAssetType ( key)
158158 let imageId = UUID ( ) . uuidString
159159
160160 let fileExtension = ( renditionTypeName as NSString ) . pathExtension. lowercased ( )
161161
162- // Skip files without an extension or SVGs
163- if !fileExtension. isEmpty && fileExtension != " svg " , let unslicedImage = unslicedImage {
164- images [ imageId] = ( cgImage: unslicedImage, format: fileExtension)
162+ if unslicedImage == nil && className == " _CUIThemeMultisizeImageSetRendition " {
163+ if let result = findImageForMultisizeSet ( rendition, key, assetKeys, structuredThemeStore) {
164+ unslicedImage = result. image
165+ width = result. width
166+ height = result. height
167+ }
168+ }
169+
170+ // Skip SVGs, but save images even if they don't have an extension (default to png)
171+ if fileExtension != " svg " , let unslicedImage = unslicedImage {
172+ let format = fileExtension. isEmpty ? " png " : fileExtension
173+ images [ imageId] = ( cgImage: unslicedImage, format: format)
165174 }
166175
167176 let idiomValue = key. getUInt ( forKey: " themeIdiom " )
@@ -276,6 +285,60 @@ enum AssetUtil {
276285 }
277286 return true
278287 }
288+
289+ private static func findImageForMultisizeSet(
290+ _ rendition: NSObject ,
291+ _ key: NSObject ,
292+ _ assetKeys: [ NSObject ] ,
293+ _ structuredThemeStore: NSObject
294+ ) -> ( image: CGImage , width: Int , height: Int ) ? {
295+ // Get the sizeIndexes to find the actual image
296+ guard rendition. responds ( to: Selector ( ( " sizeIndexes " ) ) ) ,
297+ let sizeIndexesResult = rendition. perform ( Selector ( ( " sizeIndexes " ) ) ) ,
298+ let sizeIndexesArray = sizeIndexesResult. takeUnretainedValue ( ) as? NSArray ,
299+ sizeIndexesArray. count > 0 else {
300+ return nil
301+ }
302+
303+ // Get the first size index
304+ let sizeIndexObj = sizeIndexesArray. object ( at: 0 ) as! NSObject
305+
306+ // Get the idiom and subtype from the size index
307+ let idiom = sizeIndexObj. getUInt ( forKey: " idiom " ) ?? 0
308+ let subtype = sizeIndexObj. getUInt ( forKey: " subtype " ) ?? 0
309+ let keyElement = key. getUInt ( forKey: " themeElement " ) ?? 0
310+
311+ // Look for a rendition with matching idiom and subtype in the asset keys
312+ for otherKey in assetKeys {
313+ let otherKeyIdiom = otherKey. getUInt ( forKey: " themeIdiom " ) ?? 0
314+ let otherKeySubtype = otherKey. getUInt ( forKey: " themeSubtype " ) ?? 0
315+ let otherKeyElement = otherKey. getUInt ( forKey: " themeElement " ) ?? 0
316+
317+ // Find a key with matching element, idiom, and subtype
318+ guard otherKeyElement == keyElement,
319+ otherKeyIdiom == idiom,
320+ otherKeySubtype == subtype else {
321+ continue
322+ }
323+
324+ let otherKeyList = unsafeBitCast (
325+ otherKey. perform ( Selector ( ( " keyList " ) ) ) ,
326+ to: UnsafeMutableRawPointer . self
327+ )
328+
329+ guard let imageRendition = createRendition ( from: structuredThemeStore, otherKeyList) ,
330+ let className = imageRendition. perform ( Selector ( ( " className " ) ) ) ? . takeUnretainedValue ( ) as? String ,
331+ className != " _CUIThemeMultisizeImageSetRendition " ,
332+ let result = imageRendition. perform ( Selector ( ( " unslicedImage " ) ) ) else {
333+ continue
334+ }
335+
336+ let image = result. takeUnretainedValue ( ) as! CGImage
337+ return ( image, image. width, image. height)
338+ }
339+
340+ return nil
341+ }
279342
280343 private static func determineAssetType( _ key: NSObject ) -> AssetType {
281344 let themeElement = key. getUInt ( forKey: " themeElement " ) ?? 0
0 commit comments