mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-22 14:20:20 +00:00
Emoji status and reaction improvements
This commit is contained in:
@@ -54,17 +54,27 @@ public final class AnimationCacheItem {
|
||||
case frames(Int)
|
||||
}
|
||||
|
||||
public struct AdvanceResult {
|
||||
public let frame: AnimationCacheItemFrame
|
||||
public let didLoop: Bool
|
||||
|
||||
public init(frame: AnimationCacheItemFrame, didLoop: Bool) {
|
||||
self.frame = frame
|
||||
self.didLoop = didLoop
|
||||
}
|
||||
}
|
||||
|
||||
public let numFrames: Int
|
||||
private let advanceImpl: (Advance, AnimationCacheItemFrame.RequestedFormat) -> AnimationCacheItemFrame?
|
||||
private let advanceImpl: (Advance, AnimationCacheItemFrame.RequestedFormat) -> AdvanceResult?
|
||||
private let resetImpl: () -> Void
|
||||
|
||||
public init(numFrames: Int, advanceImpl: @escaping (Advance, AnimationCacheItemFrame.RequestedFormat) -> AnimationCacheItemFrame?, resetImpl: @escaping () -> Void) {
|
||||
public init(numFrames: Int, advanceImpl: @escaping (Advance, AnimationCacheItemFrame.RequestedFormat) -> AdvanceResult?, resetImpl: @escaping () -> Void) {
|
||||
self.numFrames = numFrames
|
||||
self.advanceImpl = advanceImpl
|
||||
self.resetImpl = resetImpl
|
||||
}
|
||||
|
||||
public func advance(advance: Advance, requestedFormat: AnimationCacheItemFrame.RequestedFormat) -> AnimationCacheItemFrame? {
|
||||
public func advance(advance: Advance, requestedFormat: AnimationCacheItemFrame.RequestedFormat) -> AdvanceResult? {
|
||||
return self.advanceImpl(advance, requestedFormat)
|
||||
}
|
||||
|
||||
@@ -669,12 +679,14 @@ private final class AnimationCacheItemAccessor {
|
||||
self.currentDctData = dctData
|
||||
}
|
||||
|
||||
private func loadNextFrame() {
|
||||
private func loadNextFrame() -> Bool {
|
||||
var didLoop = false
|
||||
let index: Int
|
||||
if let currentFrame = self.currentFrame {
|
||||
if currentFrame.index + 1 >= self.durationMapping.count {
|
||||
index = 0
|
||||
self.compressedDataReader = nil
|
||||
didLoop = true
|
||||
} else {
|
||||
index = currentFrame.index + 1
|
||||
}
|
||||
@@ -689,7 +701,7 @@ private final class AnimationCacheItemAccessor {
|
||||
|
||||
guard let compressedDataReader = self.compressedDataReader else {
|
||||
self.currentFrame = nil
|
||||
return
|
||||
return didLoop
|
||||
}
|
||||
|
||||
do {
|
||||
@@ -779,17 +791,22 @@ private final class AnimationCacheItemAccessor {
|
||||
self.currentFrame = nil
|
||||
self.compressedDataReader = nil
|
||||
}
|
||||
|
||||
return didLoop
|
||||
}
|
||||
|
||||
func reset() {
|
||||
self.currentFrame = nil
|
||||
}
|
||||
|
||||
func advance(advance: AnimationCacheItem.Advance, requestedFormat: AnimationCacheItemFrame.RequestedFormat) -> AnimationCacheItemFrame? {
|
||||
func advance(advance: AnimationCacheItem.Advance, requestedFormat: AnimationCacheItemFrame.RequestedFormat) -> AnimationCacheItem.AdvanceResult? {
|
||||
var didLoop = false
|
||||
switch advance {
|
||||
case let .frames(count):
|
||||
for _ in 0 ..< count {
|
||||
self.loadNextFrame()
|
||||
if self.loadNextFrame() {
|
||||
didLoop = true
|
||||
}
|
||||
}
|
||||
case let .duration(duration):
|
||||
var durationOverflow = duration
|
||||
@@ -798,12 +815,16 @@ private final class AnimationCacheItemAccessor {
|
||||
currentFrame.remainingDuration -= durationOverflow
|
||||
if currentFrame.remainingDuration <= 0.0 {
|
||||
durationOverflow = -currentFrame.remainingDuration
|
||||
self.loadNextFrame()
|
||||
if self.loadNextFrame() {
|
||||
didLoop = true
|
||||
}
|
||||
} else {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
self.loadNextFrame()
|
||||
if self.loadNextFrame() {
|
||||
didLoop = true
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -818,36 +839,42 @@ private final class AnimationCacheItemAccessor {
|
||||
let currentSurface = ImageARGB(width: currentFrame.yuva.yPlane.width, height: currentFrame.yuva.yPlane.height, rowAlignment: 32)
|
||||
currentFrame.yuva.toARGB(target: currentSurface)
|
||||
|
||||
return AnimationCacheItemFrame(format: .rgba(data: currentSurface.argbPlane.data, width: currentSurface.argbPlane.width, height: currentSurface.argbPlane.height, bytesPerRow: currentSurface.argbPlane.bytesPerRow), duration: currentFrame.duration)
|
||||
return AnimationCacheItem.AdvanceResult(
|
||||
frame: AnimationCacheItemFrame(format: .rgba(data: currentSurface.argbPlane.data, width: currentSurface.argbPlane.width, height: currentSurface.argbPlane.height, bytesPerRow: currentSurface.argbPlane.bytesPerRow), duration: currentFrame.duration),
|
||||
didLoop: didLoop
|
||||
)
|
||||
case .yuva:
|
||||
return AnimationCacheItemFrame(
|
||||
format: .yuva(
|
||||
y: AnimationCacheItemFrame.Plane(
|
||||
data: currentFrame.yuva.yPlane.data,
|
||||
width: currentFrame.yuva.yPlane.width,
|
||||
height: currentFrame.yuva.yPlane.height,
|
||||
bytesPerRow: currentFrame.yuva.yPlane.bytesPerRow
|
||||
return AnimationCacheItem.AdvanceResult(
|
||||
frame: AnimationCacheItemFrame(
|
||||
format: .yuva(
|
||||
y: AnimationCacheItemFrame.Plane(
|
||||
data: currentFrame.yuva.yPlane.data,
|
||||
width: currentFrame.yuva.yPlane.width,
|
||||
height: currentFrame.yuva.yPlane.height,
|
||||
bytesPerRow: currentFrame.yuva.yPlane.bytesPerRow
|
||||
),
|
||||
u: AnimationCacheItemFrame.Plane(
|
||||
data: currentFrame.yuva.uPlane.data,
|
||||
width: currentFrame.yuva.uPlane.width,
|
||||
height: currentFrame.yuva.uPlane.height,
|
||||
bytesPerRow: currentFrame.yuva.uPlane.bytesPerRow
|
||||
),
|
||||
v: AnimationCacheItemFrame.Plane(
|
||||
data: currentFrame.yuva.vPlane.data,
|
||||
width: currentFrame.yuva.vPlane.width,
|
||||
height: currentFrame.yuva.vPlane.height,
|
||||
bytesPerRow: currentFrame.yuva.vPlane.bytesPerRow
|
||||
),
|
||||
a: AnimationCacheItemFrame.Plane(
|
||||
data: currentFrame.yuva.aPlane.data,
|
||||
width: currentFrame.yuva.aPlane.width,
|
||||
height: currentFrame.yuva.aPlane.height,
|
||||
bytesPerRow: currentFrame.yuva.aPlane.bytesPerRow
|
||||
)
|
||||
),
|
||||
u: AnimationCacheItemFrame.Plane(
|
||||
data: currentFrame.yuva.uPlane.data,
|
||||
width: currentFrame.yuva.uPlane.width,
|
||||
height: currentFrame.yuva.uPlane.height,
|
||||
bytesPerRow: currentFrame.yuva.uPlane.bytesPerRow
|
||||
),
|
||||
v: AnimationCacheItemFrame.Plane(
|
||||
data: currentFrame.yuva.vPlane.data,
|
||||
width: currentFrame.yuva.vPlane.width,
|
||||
height: currentFrame.yuva.vPlane.height,
|
||||
bytesPerRow: currentFrame.yuva.vPlane.bytesPerRow
|
||||
),
|
||||
a: AnimationCacheItemFrame.Plane(
|
||||
data: currentFrame.yuva.aPlane.data,
|
||||
width: currentFrame.yuva.aPlane.width,
|
||||
height: currentFrame.yuva.aPlane.height,
|
||||
bytesPerRow: currentFrame.yuva.aPlane.bytesPerRow
|
||||
)
|
||||
duration: currentFrame.duration
|
||||
),
|
||||
duration: currentFrame.duration
|
||||
didLoop: didLoop
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1235,7 +1262,7 @@ private func adaptItemFromHigherResolution(currentQueue: Queue, itemPath: String
|
||||
guard let frame = higherResolutionItem.advance(advance: .frames(1), requestedFormat: .yuva(rowAlignment: yuva.yPlane.rowAlignment)) else {
|
||||
return nil
|
||||
}
|
||||
switch frame.format {
|
||||
switch frame.frame.format {
|
||||
case .rgba:
|
||||
return nil
|
||||
case let .yuva(y, u, v, a):
|
||||
@@ -1245,7 +1272,7 @@ private func adaptItemFromHigherResolution(currentQueue: Queue, itemPath: String
|
||||
yuva.aPlane.copyScaled(fromPlane: a)
|
||||
}
|
||||
|
||||
return frame.duration
|
||||
return frame.frame.duration
|
||||
}, proposedWidth: width, proposedHeight: height, insertKeyframe: true)
|
||||
}
|
||||
|
||||
@@ -1282,7 +1309,7 @@ private func generateFirstFrameFromItem(currentQueue: Queue, itemPath: String, a
|
||||
guard let frame = animationItem.advance(advance: .frames(1), requestedFormat: .yuva(rowAlignment: 1)) else {
|
||||
return false
|
||||
}
|
||||
switch frame.format {
|
||||
switch frame.frame.format {
|
||||
case .rgba:
|
||||
return false
|
||||
case let .yuva(y, u, v, a):
|
||||
@@ -1297,7 +1324,7 @@ private func generateFirstFrameFromItem(currentQueue: Queue, itemPath: String, a
|
||||
yuva.vPlane.copyScaled(fromPlane: v)
|
||||
yuva.aPlane.copyScaled(fromPlane: a)
|
||||
|
||||
return frame.duration
|
||||
return frame.frame.duration
|
||||
}, proposedWidth: y.width, proposedHeight: y.height, insertKeyframe: true)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user