mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
Bot forums
This commit is contained in:
@@ -1018,6 +1018,30 @@ public final class InteractiveTextNodeLayout: NSObject {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public func sizeForGlyphCount(glyphCount: Int) -> CGSize {
|
||||
var height: CGFloat = 0.0
|
||||
if !self.segments.isEmpty, let line = self.segments[0].lines.first {
|
||||
height = line.frame.maxY
|
||||
}
|
||||
var count = 0
|
||||
for segment in self.segments {
|
||||
for line in segment.lines {
|
||||
if count >= glyphCount {
|
||||
break
|
||||
}
|
||||
let glyphRuns = CTLineGetGlyphRuns(line.line) as NSArray
|
||||
for run in glyphRuns {
|
||||
let run = run as! CTRun
|
||||
let glyphCount = CTRunGetGlyphCount(run)
|
||||
count += Int(glyphCount)
|
||||
}
|
||||
height = max(height, line.frame.maxY)
|
||||
}
|
||||
}
|
||||
height += self.insets.top + self.insets.bottom + 2.0
|
||||
return CGSize(width: self.size.width + self.insets.left + self.insets.right, height: ceil(height))
|
||||
}
|
||||
}
|
||||
|
||||
private func addSpoiler(line: InteractiveTextNodeLine, ascent: CGFloat, descent: CGFloat, startIndex: Int, endIndex: Int) {
|
||||
@@ -1144,6 +1168,7 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn
|
||||
}
|
||||
|
||||
public internal(set) var cachedLayout: InteractiveTextNodeLayout?
|
||||
public internal(set) var revealGlyphCount: Int?
|
||||
public var renderContentTypes: RenderContentTypes = .all
|
||||
private var contentItemLayers: [Int: TextContentItemLayer] = [:]
|
||||
|
||||
@@ -2068,6 +2093,65 @@ open class InteractiveTextNode: ASDisplayNode, TextNodeProtocol, UIGestureRecogn
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
public func getGlyphCount() -> Int {
|
||||
guard let cachedLayout = self.cachedLayout else {
|
||||
return 0
|
||||
}
|
||||
|
||||
var count: Int = 0
|
||||
|
||||
for segment in cachedLayout.segments {
|
||||
for line in segment.lines {
|
||||
let glyphRuns = CTLineGetGlyphRuns(line.line) as NSArray
|
||||
for run in glyphRuns {
|
||||
let run = run as! CTRun
|
||||
let glyphCount = CTRunGetGlyphCount(run)
|
||||
count += Int(glyphCount)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count
|
||||
}
|
||||
|
||||
public func updateRevealGlyphCount(count: Int?) {
|
||||
guard let cachedLayout = self.cachedLayout else {
|
||||
return
|
||||
}
|
||||
|
||||
self.revealGlyphCount = count
|
||||
|
||||
if let count {
|
||||
var nextItemId = 0
|
||||
var currentCount = 0
|
||||
for segment in cachedLayout.segments {
|
||||
let itemId = nextItemId
|
||||
nextItemId += 1
|
||||
|
||||
var segmentGlyphCount = 0
|
||||
for line in segment.lines {
|
||||
let glyphRuns = CTLineGetGlyphRuns(line.line) as NSArray
|
||||
for run in glyphRuns {
|
||||
let run = run as! CTRun
|
||||
let glyphCount = CTRunGetGlyphCount(run)
|
||||
segmentGlyphCount += Int(glyphCount)
|
||||
}
|
||||
}
|
||||
|
||||
let segmentInnerCount = min(max(0, count - currentCount), segmentGlyphCount)
|
||||
if let item = self.contentItemLayers[itemId] {
|
||||
item.updateMaxGlyphDrawCount(value: segmentInnerCount)
|
||||
}
|
||||
|
||||
currentCount += segmentGlyphCount
|
||||
}
|
||||
} else {
|
||||
for (_, item) in self.contentItemLayers {
|
||||
item.updateMaxGlyphDrawCount(value: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final class TextContentItem {
|
||||
@@ -2148,11 +2232,13 @@ final class TextContentItemLayer: SimpleLayer {
|
||||
let size: CGSize
|
||||
let item: TextContentItem
|
||||
let mask: RenderMask?
|
||||
let maxGlyphDrawCount: Int?
|
||||
|
||||
init(size: CGSize, item: TextContentItem, mask: RenderMask?) {
|
||||
init(size: CGSize, item: TextContentItem, mask: RenderMask?, maxGlyphDrawCount: Int?) {
|
||||
self.size = size
|
||||
self.item = item
|
||||
self.mask = mask
|
||||
self.maxGlyphDrawCount = maxGlyphDrawCount
|
||||
|
||||
super.init()
|
||||
}
|
||||
@@ -2232,6 +2318,8 @@ final class TextContentItemLayer: SimpleLayer {
|
||||
let offset = params.item.contentOffset
|
||||
let alignment: NSTextAlignment = .left
|
||||
|
||||
var drawnGlyphCount = 0
|
||||
|
||||
for i in 0 ..< params.item.segment.lines.count {
|
||||
let line = params.item.segment.lines[i]
|
||||
|
||||
@@ -2261,6 +2349,15 @@ final class TextContentItemLayer: SimpleLayer {
|
||||
for run in glyphRuns {
|
||||
let run = run as! CTRun
|
||||
let glyphCount = CTRunGetGlyphCount(run)
|
||||
|
||||
var runDrawGlyphCount = glyphCount
|
||||
if let maxGlyphDrawCount = params.maxGlyphDrawCount {
|
||||
if drawnGlyphCount >= maxGlyphDrawCount {
|
||||
break
|
||||
}
|
||||
runDrawGlyphCount = CFIndex(max(0, min(Int(glyphCount), maxGlyphDrawCount - drawnGlyphCount)))
|
||||
}
|
||||
|
||||
let attributes = CTRunGetAttributes(run) as NSDictionary
|
||||
if attributes["Attribute__EmbeddedItem"] != nil {
|
||||
continue
|
||||
@@ -2310,12 +2407,14 @@ final class TextContentItemLayer: SimpleLayer {
|
||||
let stringRange = CTRunGetStringRange(run)
|
||||
if line.attachments.contains(where: { $0.range.contains(stringRange.location) }) {
|
||||
} else {
|
||||
CTRunDraw(run, context, CFRangeMake(0, glyphCount))
|
||||
CTRunDraw(run, context, CFRangeMake(0, runDrawGlyphCount))
|
||||
}
|
||||
} else {
|
||||
CTRunDraw(run, context, CFRangeMake(0, glyphCount))
|
||||
CTRunDraw(run, context, CFRangeMake(0, runDrawGlyphCount))
|
||||
}
|
||||
|
||||
drawnGlyphCount += Int(glyphCount)
|
||||
|
||||
if fixDoubleEmoji {
|
||||
context.setBlendMode(.normal)
|
||||
}
|
||||
@@ -2464,6 +2563,8 @@ final class TextContentItemLayer: SimpleLayer {
|
||||
private var isAnimating: Bool = false
|
||||
private var currentContentMask: RenderMask?
|
||||
|
||||
private var maxGlyphDrawCount: Int?
|
||||
|
||||
init(displaysAsynchronously: Bool) {
|
||||
self.renderNode = RenderNode()
|
||||
self.renderNode.displaysAsynchronously = displaysAsynchronously
|
||||
@@ -2483,6 +2584,17 @@ final class TextContentItemLayer: SimpleLayer {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func updateMaxGlyphDrawCount(value: Int?) {
|
||||
if self.maxGlyphDrawCount != value {
|
||||
self.maxGlyphDrawCount = value
|
||||
|
||||
if let renderParams = self.renderNode.params {
|
||||
self.renderNode.params = RenderParams(size: renderParams.size, item: renderParams.item, mask: renderParams.mask, maxGlyphDrawCount: self.maxGlyphDrawCount)
|
||||
self.renderNode.displayImmediately()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func update(
|
||||
params: Params,
|
||||
animation: ListViewItemUpdateAnimation,
|
||||
@@ -2735,7 +2847,7 @@ final class TextContentItemLayer: SimpleLayer {
|
||||
|
||||
self.currentContentMask = contentMask
|
||||
|
||||
self.renderNode.params = RenderParams(size: contentFrame.size, item: params.item, mask: staticContentMask)
|
||||
self.renderNode.params = RenderParams(size: contentFrame.size, item: params.item, mask: staticContentMask, maxGlyphDrawCount: self.maxGlyphDrawCount)
|
||||
if synchronously {
|
||||
if let spoilerExpandRect, animation.isAnimated {
|
||||
let localSpoilerExpandRect = spoilerExpandRect.offsetBy(dx: -self.renderNode.frame.minX, dy: -self.renderNode.frame.minY)
|
||||
|
||||
Reference in New Issue
Block a user