@@ -265,17 +265,161 @@ package struct _ShapeStyle_RenderedShape {
265265 styles : ShapeStyle . Pack ,
266266 layers : inout ShapeStyle . RenderedLayers
267267 ) {
268- // TODO: RBSymbolAnimator/RBSymbolUpdate
269- // We use a plain implementation for now
270- _openSwiftUIUnimplementedWarning ( )
271- let style = styles [ name , 0 ]
272- layers . beginLayer (
273- id : . styled ( name , 0 ) ,
274- style : style ,
275- shape : & self
268+ #if canImport( Darwin )
269+ func level ( for style : ORBSymbolStyle ) -> Int ? {
270+ switch style {
271+ case . primary : 0
272+ case . secondary : 1
273+ case . tertiary : 2
274+ case . quaternary : 3
275+ case . quinary : 4
276+ default : nil
277+ }
278+ }
279+
280+ let slice = styles [ name ]
281+ var flags : ORBSymbolUpdateFlags
282+ switch orientation {
283+ case . up : flags = [ ]
284+ case . upMirrored : flags = [ . flipX ]
285+ case . down : flags = [ . flipX , . flipY ]
286+ case . downMirrored : flags = [ . flipY ]
287+ case . left : flags = [ . swapAxes ]
288+ case . leftMirrored : flags = [ . swapAxes , . flipX ]
289+ case . right : flags = [ . swapAxes , . flipX , . flipY ]
290+ case . rightMirrored : flags = [ . swapAxes , . flipY ]
291+ }
292+ flags . insert ( . mergeLayers )
293+ if ! glyph . preservesVectorRepresentation {
294+ flags . insert ( . applyVerticalOffset )
295+ }
296+ var position = frame . origin
297+ var size = frame . size
298+ let update = glyph . animator . beginUpdate (
299+ with : . unspecified ,
300+ position : & position ,
301+ size : & size ,
302+ flags : flags
276303 )
277- render ( style : style )
278- layers . endLayer ( shape : & self )
304+ defer { glyph . animator . end ( update ) }
305+ let nextTime = update . nextTime
306+ var imageScale = 1.0
307+ var imageOpacity : Float = 1.0
308+ if ! glyph . preservesVectorRepresentation ,
309+ ! slice . isEmpty ,
310+ let image = update . templateImage ( scale : & imageScale , opacity : & imageOpacity ) {
311+ shape = . image ( GraphicsImage (
312+ contents : . cgImage ( image ) ,
313+ scale : imageScale ,
314+ unrotatedPixelSize : CGSize ( width : image . width , height : image . height ) ,
315+ orientation : orientation ,
316+ isTemplate : true
317+ ) )
318+ let style = slice [ 0 ] . applyingOpacity ( imageOpacity )
319+ layers . beginLayer ( id : . styled ( name , 0 ) , style : style , shape : & self )
320+ render ( style : style )
321+ layers . endLayer ( shape : & self )
322+ return
323+ }
324+
325+ let groupCount = update . groupCount
326+ // Style-mask bit 12 disables the single-layer path. Its meaning is not known.
327+ let isSingleLayer = update . styleMask & ( 1 << 12 ) == 0
328+ && groupCount == 1 && update . groupSize ( group : 0 ) == 1
329+ if ! isSingleLayer , slice . allColors {
330+ let list = ORBDisplayList ( )
331+ update . draw ( in : list . state ) { symbolStyle , colorName in
332+ let color : Color . Resolved ?
333+ if let level = level ( for : symbolStyle ) , ! slice . isEmpty {
334+ color = slice [ min ( level , slice . count - 1 ) ] . color
335+ } else if symbolStyle == . namedColor {
336+ color = colorName . flatMap { styles [ $0 ] }
337+ } else {
338+ color = nil
339+ }
340+ guard let color else { return . null }
341+ return ORBColor ( red : color . red , green : color . green , blue : color . blue , alpha : color . opacity )
342+ }
343+ layers . beginLayer ( id : . unstyled , style : nil , shape : & self )
344+ item = makeDrawingItem (
345+ from : list . moveContents ( ) ,
346+ offset : CGSize ( item . frame . origin ) ,
347+ flags : [ ]
348+ )
349+ if nextTime . isFinite {
350+ layerNeedes . insert ( . drawingGroup )
351+ }
352+ layers . endLayer ( shape : & self )
353+ return
354+ }
355+
356+ var drawingList : ORBDisplayList ?
357+ for group in 0 ..< groupCount {
358+ for index in 0 ..< update . groupSize ( group : group ) {
359+ let layer = ORBSymbolUpdateLayer ( update : update , group : group , index : index )
360+ let opacity = layer . drawingOpacity
361+ guard opacity > 0 else { continue }
362+ let style : ShapeStyle . Pack . Style
363+ let id : ShapeStyle . LayerID
364+ if let level = level ( for : layer . style ) , ! slice . isEmpty {
365+ style = slice [ min ( level , slice . count - 1 ) ] . applyingOpacity ( opacity )
366+ id = . styled ( name , UInt16 ( level ) )
367+ } else if layer . style == . namedColor , let colorName = layer . colorName {
368+ let color : Color . Resolved
369+ if let resolved = styles [ colorName ] {
370+ color = resolved
371+ } else if let proposed = layer . defaultColor {
372+ color = Color . Resolved ( failableCGColor : proposed ) ?? . clear
373+ } else {
374+ continue
375+ }
376+ style = ShapeStyle . Pack . Style ( . color ( color ) ) . applyingOpacity ( opacity )
377+ id = . named ( colorName )
378+ } else {
379+ continue
380+ }
381+ layers . beginLayer ( id : id , style : style , shape : & self )
382+ var transform = CGAffineTransform ( )
383+ let path = glyph . preservesVectorRepresentation
384+ ? ORBPath . null
385+ : layer . path ( transform : & transform , flags : [ . includeClips ] )
386+ if ! path . isNull {
387+ // Layer paths belong to the update; the shape takes an owned copy.
388+ shape = . path (
389+ Path ( box : Path . PathBox ( takingPath : path . copy ( transform : & transform ) ) ) ,
390+ FillStyle ( )
391+ )
392+ } else {
393+ let list : ORBDisplayList
394+ if let drawingList {
395+ list = drawingList
396+ } else {
397+ list = ORBDisplayList ( )
398+ drawingList = list
399+ }
400+ layer . draw (
401+ in : list . state ,
402+ color : . white ,
403+ opacity : 1 ,
404+ blendMode : . init ( rawValue : 0 ) ,
405+ flags : [ . includeClips ]
406+ )
407+ shape = . alphaMask ( makeDrawingItem (
408+ from : list . moveContents ( ) ,
409+ offset : . zero ,
410+ flags : [ . alphaOnly ]
411+ ) )
412+ if nextTime . isFinite {
413+ layerNeedes . insert ( . drawingGroup )
414+ }
415+ }
416+ render ( style : style )
417+ layers . endLayer ( shape : & self )
418+ }
419+ }
420+ #else
421+ _openSwiftUIPlatformUnimplementedFailure ( )
422+ #endif
279423 }
280424
281425 private mutating func renderUnstyledImage (
0 commit comments