NetNewsWire/Shared/Extensions/RSImage-Extensions.swift
2024-03-24 18:49:39 -07:00

80 lines
1.6 KiB
Swift

//
// RSImage-Extensions.swift
// RSCore
//
// Created by Maurice Parker on 4/11/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
#if os(macOS)
import AppKit
#else
import UIKit
#endif
import Core
extension RSImage {
private static let scaledMaxPixelSize: Int = {
let maxIconSize = 48
#if os(iOS)
let maxScreenScale = 3
#elseif os(macOS)
let maxScreenScale = 2
#endif
return maxIconSize * maxScreenScale
}()
static func scaledForIcon(_ data: Data) async -> RSImage? {
await IconScalerQueue.shared.scaledForIcon(data)
}
static func scaledForIcon(_ data: Data) -> RSImage? {
guard var cgImage = RSImage.scaleImage(data, maxPixelSize: Self.scaledMaxPixelSize) else {
return nil
}
#if os(iOS)
return RSImage(cgImage: cgImage)
#else
let size = NSSize(width: cgImage.width, height: cgImage.height)
return RSImage(cgImage: cgImage, size: size)
#endif
}
}
// MARK: - IconScalerQueue
private final class IconScalerQueue: @unchecked Sendable {
static let shared = IconScalerQueue()
private let queue: DispatchQueue = {
let q = DispatchQueue(label: "IconScaler", attributes: .initiallyInactive)
q.setTarget(queue: DispatchQueue.global(qos: .default))
q.activate()
return q
}()
private func scaledForIcon(_ data: Data, _ imageResultBlock: @escaping ImageResultBlock) {
queue.async {
let image = RSImage.scaledForIcon(data)
imageResultBlock(image)
}
}
func scaledForIcon(_ data: Data) async -> RSImage? {
await withCheckedContinuation { continuation in
self.scaledForIcon(data) { image in
continuation.resume(returning: image)
}
}
}
}