54 lines
1.5 KiB
Swift
54 lines
1.5 KiB
Swift
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
|
|
)
|
|
}
|
|
}
|
|
}
|