Files
swiftui-math/Sources/SwiftUIMath/Internal/Display/DisplayLargeOperator.swift
Guille Gonzalez e26d7d01b5 Add Typesetter
2026-01-03 08:11:38 +01:00

85 lines
2.5 KiB
Swift

import CoreGraphics
import Foundation
extension Math {
final class DisplayLargeOperator: DisplayNode {
var upperLimit: DisplayList?
var lowerLimit: DisplayList?
var nucleus: DisplayNode?
var limitShift: CGFloat = 0
var upperLimitGap: CGFloat = 0 { didSet { updateUpperLimitPosition() } }
var lowerLimitGap: CGFloat = 0 { didSet { updateLowerLimitPosition() } }
var extraPadding: CGFloat = 0
init(
nucleus: DisplayNode?, upperLimit: DisplayList?, lowerLimit: DisplayList?,
limitShift: CGFloat, extraPadding: CGFloat
) {
self.upperLimit = upperLimit
self.lowerLimit = lowerLimit
self.nucleus = nucleus
self.limitShift = limitShift
self.extraPadding = extraPadding
super.init()
var maxWidth = max(nucleus?.width ?? 0, upperLimit?.width ?? 0)
maxWidth = max(maxWidth, lowerLimit?.width ?? 0)
width = maxWidth
}
override var ascent: CGFloat {
get {
guard let nucleus else { return 0 }
if let upperLimit {
return nucleus.ascent + extraPadding + upperLimit.ascent + upperLimitGap
+ upperLimit.descent
}
return nucleus.ascent
}
set { super.ascent = newValue }
}
override var descent: CGFloat {
get {
guard let nucleus else { return 0 }
if let lowerLimit {
return nucleus.descent + extraPadding + lowerLimitGap + lowerLimit.descent
+ lowerLimit.ascent
}
return nucleus.descent
}
set { super.descent = newValue }
}
override var position: CGPoint {
didSet {
updateLowerLimitPosition()
updateUpperLimitPosition()
updateNucleusPosition()
}
}
private func updateLowerLimitPosition() {
guard let lowerLimit, let nucleus else { return }
lowerLimit.position = CGPoint(
x: position.x - limitShift + (width - lowerLimit.width) / 2,
y: position.y - nucleus.descent - lowerLimitGap - lowerLimit.ascent
)
}
private func updateUpperLimitPosition() {
guard let upperLimit, let nucleus else { return }
upperLimit.position = CGPoint(
x: position.x + limitShift + (width - upperLimit.width) / 2,
y: position.y + nucleus.ascent + upperLimitGap + upperLimit.descent
)
}
private func updateNucleusPosition() {
guard let nucleus else { return }
nucleus.position = CGPoint(x: position.x + (width - nucleus.width) / 2, y: position.y)
}
}
}