Merge commit '7621e2f8dec938cf48181c8b10afc9b01f444e68' into beta

This commit is contained in:
Ilya Laktyushin
2025-12-06 02:17:48 +04:00
commit 8344b97e03
28070 changed files with 7995182 additions and 0 deletions
@@ -0,0 +1,19 @@
//
// AnimationSubview.swift
// lottie-swift-iOS
//
// Created by Brandon Withrow on 2/5/19.
//
#if os(macOS)
import AppKit
/// A view that can be added to a keypath of an AnimationView
public final class AnimationSubview: NSView {
var viewLayer: CALayer? {
layer
}
}
#endif
@@ -0,0 +1,102 @@
//
// AnimationViewBase.swift
// lottie-swift-iOS
//
// Created by Brandon Withrow on 2/6/19.
//
#if os(macOS)
import AppKit
public enum LottieContentMode: Int {
case scaleToFill
case scaleAspectFit
case scaleAspectFill
case redraw
case center
case top
case bottom
case left
case right
case topLeft
case topRight
case bottomLeft
case bottomRight
}
/// The base view for `AnimationView` on macOs.
///
/// Enables the `AnimationView` implementation to be shared across platforms.
public class AnimationViewBase: NSView {
// MARK: Public
public override var wantsUpdateLayer: Bool {
true
}
public override var isFlipped: Bool {
true
}
public var contentMode: LottieContentMode = .scaleAspectFit {
didSet {
setNeedsLayout()
}
}
public override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
animationMovedToWindow()
}
public override func layout() {
super.layout()
CATransaction.begin()
CATransaction.setDisableActions(true)
layoutAnimation()
CATransaction.commit()
}
// MARK: Internal
var screenScale: CGFloat {
NSApp.mainWindow?.backingScaleFactor ?? 1
}
var viewLayer: CALayer? {
layer
}
func layoutAnimation() {
// Implemented by subclasses.
}
func animationMovedToWindow() {
// Implemented by subclasses.
}
func commonInit() {
wantsLayer = true
}
func setNeedsLayout() {
needsLayout = true
}
func layoutIfNeeded() {
// Implemented by subclasses.
}
@objc
func animationWillMoveToBackground() {
// Implemented by subclasses.
}
@objc
func animationWillEnterForeground() {
// Implemented by subclasses.
}
}
#endif
@@ -0,0 +1,80 @@
//
// LottieBundleImageProvider.swift
// lottie-swift
//
// Created by Brandon Withrow on 1/25/19.
//
#if os(macOS)
import AppKit
/// Provides an image for a lottie animation from a provided Bundle.
public class BundleImageProvider: AnimationImageProvider {
// MARK: Lifecycle
/// Initializes an image provider with a bundle and an optional subpath.
///
/// Provides images for an animation from a bundle. Additionally the provider can
/// search a specific subpath for the images.
///
/// - Parameter bundle: The bundle containing images for the provider.
/// - Parameter searchPath: The subpath is a path within the bundle to search for image assets.
///
public init(bundle: Bundle, searchPath: String?) {
self.bundle = bundle
self.searchPath = searchPath
}
// MARK: Public
public func imageForAsset(asset: ImageAsset) -> CGImage? {
if
let data = Data(imageAsset: asset),
let image = NSImage(data: data)
{
return image.CGImage
}
let imagePath: String?
/// Try to find the image in the bundle.
if let searchPath = searchPath {
/// Search in the provided search path for the image
var directoryPath = URL(fileURLWithPath: searchPath)
directoryPath.appendPathComponent(asset.directory)
if let path = bundle.path(forResource: asset.name, ofType: nil, inDirectory: directoryPath.path) {
/// First search for the image in the asset provided sub directory.
imagePath = path
} else if let path = bundle.path(forResource: asset.name, ofType: nil, inDirectory: searchPath) {
/// Try finding the image in the search path.
imagePath = path
} else {
imagePath = bundle.path(forResource: asset.name, ofType: nil)
}
} else {
if let path = bundle.path(forResource: asset.name, ofType: nil, inDirectory: asset.directory) {
/// First search for the image in the asset provided sub directory.
imagePath = path
} else {
/// First search for the image in bundle.
imagePath = bundle.path(forResource: asset.name, ofType: nil)
}
}
guard let foundPath = imagePath, let image = NSImage(contentsOfFile: foundPath) else {
/// No image found.
LottieLogger.shared.assertionFailure("Could not find image \"\(asset.name)\" in bundle")
return nil
}
return image.CGImage
}
// MARK: Internal
let bundle: Bundle
let searchPath: String?
}
#endif
@@ -0,0 +1,69 @@
//
// FilepathImageProvider.swift
// lottie-swift
//
// Created by Brandon Withrow on 2/1/19.
//
#if os(macOS)
import AppKit
/// An `AnimationImageProvider` that provides images by name from a specific filepath.
public class FilepathImageProvider: AnimationImageProvider {
// MARK: Lifecycle
/// Initializes an image provider with a specific filepath.
///
/// - Parameter filepath: The absolute filepath containing the images.
///
public init(filepath: String) {
self.filepath = URL(fileURLWithPath: filepath)
}
public init(filepath: URL) {
self.filepath = filepath
}
// MARK: Public
public func imageForAsset(asset: ImageAsset) -> CGImage? {
if
asset.name.hasPrefix("data:"),
let url = URL(string: asset.name),
let data = try? Data(contentsOf: url),
let image = NSImage(data: data)
{
return image.CGImage
}
let directPath = filepath.appendingPathComponent(asset.name).path
if FileManager.default.fileExists(atPath: directPath) {
return NSImage(contentsOfFile: directPath)?.CGImage
}
let pathWithDirectory = filepath.appendingPathComponent(asset.directory).appendingPathComponent(asset.name).path
if FileManager.default.fileExists(atPath: pathWithDirectory) {
return NSImage(contentsOfFile: pathWithDirectory)?.CGImage
}
LottieLogger.shared.assertionFailure("Could not find image \"\(asset.name)\" in bundle")
return nil
}
// MARK: Internal
let filepath: URL
}
extension NSImage {
@nonobjc
var CGImage: CGImage? {
guard let imageData = tiffRepresentation else { return nil }
guard let sourceData = CGImageSourceCreateWithData(imageData as CFData, nil) else { return nil }
return CGImageSourceCreateImageAtIndex(sourceData, 0, nil)
}
}
#endif