Fix tint colors

This commit is contained in:
Isaac 2023-11-27 18:35:41 +04:00
parent 36a8f411dc
commit 92043f0241
4 changed files with 70 additions and 14 deletions

View File

@ -1158,7 +1158,33 @@ private func addAttachment(attachment: UIImage, line: TextNodeLine, ascent: CGFl
}
open class TextNode: ASDisplayNode {
public struct RenderContentTypes: OptionSet {
public var rawValue: Int
public init(rawValue: Int) {
self.rawValue = rawValue
}
public static let text = RenderContentTypes(rawValue: 1 << 0)
public static let emoji = RenderContentTypes(rawValue: 1 << 1)
public static let all: RenderContentTypes = [.text, .emoji]
}
private final class DrawingParameters: NSObject {
let cachedLayout: TextNodeLayout?
let renderContentTypes: RenderContentTypes
init(cachedLayout: TextNodeLayout?, renderContentTypes: RenderContentTypes) {
self.cachedLayout = cachedLayout
self.renderContentTypes = renderContentTypes
super.init()
}
}
public internal(set) var cachedLayout: TextNodeLayout?
public var renderContentTypes: RenderContentTypes = .all
override public init() {
super.init()
@ -2169,7 +2195,7 @@ open class TextNode: ASDisplayNode {
}
override public func drawParameters(forAsyncLayer layer: _ASDisplayLayer) -> NSObjectProtocol? {
return self.cachedLayout
return DrawingParameters(cachedLayout: self.cachedLayout, renderContentTypes: self.renderContentTypes)
}
@objc override public class func draw(_ bounds: CGRect, withParameters parameters: Any?, isCancelled: () -> Bool, isRasterizing: Bool) {
@ -2192,8 +2218,13 @@ open class TextNode: ASDisplayNode {
var blendMode: CGBlendMode = .normal
var renderContentTypes: RenderContentTypes = .all
if let parameters = parameters as? DrawingParameters {
renderContentTypes = parameters.renderContentTypes
}
var clearRects: [CGRect] = []
if let layout = parameters as? TextNodeLayout {
if let layout = (parameters as? DrawingParameters)?.cachedLayout {
if !isRasterizing || layout.backgroundColor != nil {
context.setBlendMode(.copy)
blendMode = .copy
@ -2409,6 +2440,18 @@ open class TextNode: ASDisplayNode {
continue
}
if renderContentTypes != .all {
if let font = attributes["NSFont"] as? UIFont, font.fontName.contains("ColorEmoji") {
if !renderContentTypes.contains(.emoji) {
continue
}
} else {
if !renderContentTypes.contains(.text) {
continue
}
}
}
var fixDoubleEmoji = false
if glyphCount == 2, let font = attributes["NSFont"] as? UIFont, font.fontName.contains("ColorEmoji"), let string = layout.attributedString {
let range = CTRunGetStringRange(run)

View File

@ -662,6 +662,7 @@ public final class AvatarListContentNode: ASDisplayNode {
if value {
replicatorLayer.instanceAlphaOffset = -1.0
replicatorLayer.animate(from: 0.0 as NSNumber, to: -1.0 as NSNumber, keyPath: "instanceAlphaOffset", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.3)
} else {
replicatorLayer.instanceAlphaOffset = 0.0
replicatorLayer.animate(from: -1.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "instanceAlphaOffset", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.3)

View File

@ -418,7 +418,7 @@ public final class EmojiStatusComponent: Component {
if transition.animation.isImmediate {
iconView.tintColor = iconTintColor
} else {
transition.setTintColor(layer: iconView.layer, color: iconTintColor)
transition.setTintColor(view: iconView, color: iconTintColor)
}
} else {
iconView.tintColor = nil

View File

@ -4,17 +4,24 @@ import AsyncDisplayKit
import Display
private final class MultiScaleTextStateNode: ASDisplayNode {
let textNode: ImmediateTextNode
let tintTextNode: ImmediateTextNode
let noTintTextNode: ImmediateTextNode
var currentLayout: MultiScaleTextLayout?
override init() {
self.textNode = ImmediateTextNode()
self.textNode.displaysAsynchronously = false
self.tintTextNode = ImmediateTextNode()
self.tintTextNode.displaysAsynchronously = false
self.tintTextNode.renderContentTypes = TextNode.RenderContentTypes.all.subtracting(TextNode.RenderContentTypes.emoji)
self.noTintTextNode = ImmediateTextNode()
self.noTintTextNode.displaysAsynchronously = false
self.noTintTextNode.renderContentTypes = .emoji
super.init()
self.addSubnode(self.textNode)
self.addSubnode(self.tintTextNode)
self.addSubnode(self.noTintTextNode)
}
}
@ -60,12 +67,12 @@ public final class MultiScaleTextNode: ASDisplayNode {
}
public func stateNode(forKey key: AnyHashable) -> ASDisplayNode? {
return self.stateNodes[key]?.textNode
return self.stateNodes[key]?.tintTextNode
}
public func updateTintColor(color: UIColor, transition: ContainedViewLayoutTransition) {
for (_, node) in self.stateNodes {
transition.updateTintColor(layer: node.textNode.layer, color: color)
transition.updateTintColor(layer: node.tintTextNode.layer, color: color)
}
}
@ -77,10 +84,13 @@ public final class MultiScaleTextNode: ASDisplayNode {
var mainLayout: MultiScaleTextLayout?
for (key, state) in states {
if let node = self.stateNodes[key] {
node.textNode.attributedText = NSAttributedString(string: text, font: state.attributes.font, textColor: state.attributes.color)
node.textNode.isAccessibilityElement = true
node.textNode.accessibilityLabel = text
let nodeSize = node.textNode.updateLayout(state.constrainedSize)
node.tintTextNode.attributedText = NSAttributedString(string: text, font: state.attributes.font, textColor: state.attributes.color)
node.noTintTextNode.attributedText = NSAttributedString(string: text, font: state.attributes.font, textColor: state.attributes.color)
node.tintTextNode.isAccessibilityElement = true
node.tintTextNode.accessibilityLabel = text
node.noTintTextNode.isAccessibilityElement = false
let nodeSize = node.tintTextNode.updateLayout(state.constrainedSize)
let _ = node.noTintTextNode.updateLayout(state.constrainedSize)
let nodeLayout = MultiScaleTextLayout(size: nodeSize)
if key == mainState {
mainLayout = nodeLayout
@ -93,7 +103,9 @@ public final class MultiScaleTextNode: ASDisplayNode {
let mainBounds = CGRect(origin: CGPoint(x: -mainLayout.size.width / 2.0, y: -mainLayout.size.height / 2.0), size: mainLayout.size)
for (key, _) in states {
if let node = self.stateNodes[key], let nodeLayout = result[key] {
node.textNode.frame = CGRect(origin: CGPoint(x: mainBounds.minX, y: mainBounds.minY + floor((mainBounds.height - nodeLayout.size.height) / 2.0)), size: nodeLayout.size)
let textFrame = CGRect(origin: CGPoint(x: mainBounds.minX, y: mainBounds.minY + floor((mainBounds.height - nodeLayout.size.height) / 2.0)), size: nodeLayout.size)
node.tintTextNode.frame = textFrame
node.noTintTextNode.frame = textFrame
}
}
}