import CoreGraphics import Foundation extension Math { final class DisplayRadical: DisplayNode { var radicand: DisplayList? var degree: DisplayList? var radicalGlyph: DisplayNode? var radicalShift: CGFloat = 0 var topKern: CGFloat = 0 var lineThickness: CGFloat = 0 init(radicand: DisplayList?, glyph: DisplayNode, position: CGPoint, range: NSRange) { self.radicand = radicand self.radicalGlyph = glyph super.init() self.position = position self.range = range } func setDegree(_ degree: DisplayList?, fontMetrics: Math.FontMetrics) { guard let degree else { return } let kernBefore = fontMetrics.radicalKernBeforeDegree let kernAfter = fontMetrics.radicalKernAfterDegree let raise = fontMetrics.radicalDegreeBottomRaisePercent * (ascent - descent) self.degree = degree var shift = kernBefore + degree.width + kernAfter if shift < 0 { shift = 0 } radicalShift = shift degree.position = CGPoint(x: position.x + kernBefore, y: position.y + raise) width = shift + (radicalGlyph?.width ?? 0) + (radicand?.width ?? 0) updateRadicandPosition() } override var position: CGPoint { didSet { updateRadicandPosition() } } func updateRadicandPosition() { guard let radicand, let radicalGlyph else { return } radicand.position = CGPoint( x: position.x + radicalShift + radicalGlyph.width, y: position.y ) } } }