mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-07 08:01:10 +00:00
111 lines
3.2 KiB
Swift
111 lines
3.2 KiB
Swift
import Foundation
|
|
import CoreText
|
|
|
|
extension UnicodeScalar {
|
|
var isEmoji: Bool {
|
|
switch value {
|
|
case 0x1F600...0x1F64F, // Emoticons
|
|
0x1F300...0x1F5FF, // Misc Symbols and Pictographs
|
|
0x1F680...0x1F6FF, // Transport and Map
|
|
0x1F1E6...0x1F1FF, // Regional country flags
|
|
0x2600...0x26FF, // Misc symbols
|
|
0x2700...0x27BF, // Dingbats
|
|
0xE0020...0xE007F, // Tags
|
|
0xFE00...0xFE0F, // Variation Selectors
|
|
0x1F900...0x1F9FF, // Supplemental Symbols and Pictographs
|
|
127000...127600, // Various asian characters
|
|
65024...65039, // Variation selector
|
|
9100...9300, // Misc items
|
|
8400...8447: // Combining Diacritical Marks for Symbols
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
var isZeroWidthJoiner: Bool {
|
|
return value == 8205
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
func trimmingTrailingSpaces() -> String {
|
|
var t = self
|
|
while t.hasSuffix(" ") {
|
|
t = "" + t.dropLast()
|
|
}
|
|
return t
|
|
}
|
|
|
|
var glyphCount: Int {
|
|
let richText = NSAttributedString(string: self)
|
|
let line = CTLineCreateWithAttributedString(richText)
|
|
return CTLineGetGlyphCount(line)
|
|
}
|
|
|
|
var isSingleEmoji: Bool {
|
|
return glyphCount == 1 && containsEmoji
|
|
}
|
|
|
|
var containsEmoji: Bool {
|
|
return unicodeScalars.contains { $0.isEmoji }
|
|
}
|
|
|
|
var containsOnlyEmoji: Bool {
|
|
return !isEmpty && !unicodeScalars.contains(where: {
|
|
!$0.isEmoji && !$0.isZeroWidthJoiner
|
|
})
|
|
}
|
|
|
|
// The next tricks are mostly to demonstrate how tricky it can be to determine emoji's
|
|
// If anyone has suggestions how to improve this, please let me know
|
|
var emojiString: String {
|
|
return emojiScalars.map { String($0) }.reduce("", +)
|
|
}
|
|
|
|
var firstEmoji: String {
|
|
if let first = emojiScalars.first {
|
|
return String(first)
|
|
} else {
|
|
return ""
|
|
}
|
|
}
|
|
|
|
var emojis: [String] {
|
|
var scalars: [[UnicodeScalar]] = []
|
|
var currentScalarSet: [UnicodeScalar] = []
|
|
var previousScalar: UnicodeScalar?
|
|
|
|
for scalar in emojiScalars {
|
|
if let prev = previousScalar, !prev.isZeroWidthJoiner && !scalar.isZeroWidthJoiner {
|
|
scalars.append(currentScalarSet)
|
|
currentScalarSet = []
|
|
}
|
|
currentScalarSet.append(scalar)
|
|
|
|
previousScalar = scalar
|
|
}
|
|
|
|
scalars.append(currentScalarSet)
|
|
|
|
return scalars.map { $0.map{ String($0) } .reduce("", +) }
|
|
}
|
|
|
|
fileprivate var emojiScalars: [UnicodeScalar] {
|
|
var chars: [UnicodeScalar] = []
|
|
var previous: UnicodeScalar?
|
|
for cur in unicodeScalars {
|
|
if let previous = previous, previous.isZeroWidthJoiner && cur.isEmoji {
|
|
chars.append(previous)
|
|
chars.append(cur)
|
|
} else if cur.isEmoji {
|
|
chars.append(cur)
|
|
}
|
|
|
|
previous = cur
|
|
}
|
|
|
|
return chars
|
|
}
|
|
}
|