diff --git a/Sources/SwiftMath/MathBundle/MathTable.swift b/Sources/Obsolete/MathTable.swift similarity index 95% rename from Sources/SwiftMath/MathBundle/MathTable.swift rename to Sources/Obsolete/MathTable.swift index e86886c..5bd282c 100644 --- a/Sources/SwiftMath/MathBundle/MathTable.swift +++ b/Sources/Obsolete/MathTable.swift @@ -26,8 +26,8 @@ internal struct MathTable { let kConstants = "constants" let font: MathFont - private let unitsPerEm: UInt - private let fontSize: CGFloat + let unitsPerEm: UInt + let fontSize: CGFloat weak var fontMathTable: NSDictionary? init(withFont font: MathFont, fontSize: CGFloat, unitsPerEm: UInt) { @@ -176,13 +176,15 @@ internal struct MathTable { let glyphName = font.get(nameForGlyph: glyph) let variantGlyphs = variants[glyphName] as? NSArray var glyphArray = [NSNumber]() - if variantGlyphs == nil || variantGlyphs?.count == 0, let glyph = font.get(glyphWithName: glyphName) { + if variantGlyphs == nil || variantGlyphs?.count == 0 { // There are no extra variants, so just add the current glyph to it. + let glyph = font.get(glyphWithName: glyphName) glyphArray.append(NSNumber(value:glyph)) return glyphArray } else if let variantGlyphs = variantGlyphs { for gvn in variantGlyphs { - if let glyphVariantName = gvn as? String, let variantGlyph = font.get(glyphWithName: glyphVariantName) { + if let glyphVariantName = gvn as? String { + let variantGlyph = font.get(glyphWithName: glyphVariantName) glyphArray.append(NSNumber(value:variantGlyph)) } } @@ -204,9 +206,8 @@ internal struct MathTable { // Find the first variant with a different name. for gvn in variantGlyphs! { if let glyphVariantName = gvn as? String, - glyphVariantName != glyphName, - let variantGlyph = font.get(glyphWithName: glyphVariantName) { - return variantGlyph + glyphVariantName != glyphName { + return font.get(glyphWithName: glyphVariantName) } } // We did not find any variants of this glyph so return it. @@ -243,9 +244,7 @@ internal struct MathTable { } else { // If no top accent is defined then it is the center of the advance width. var advances = CGSize.zero - guard let ctFont = font.ctFont(withSize: fontSize) else { - fatalError("\(#function) unable to obtain ctFont resource name: \(font.rawValue) with size \(fontSize)") - } + let ctFont = font.ctFont(withSize: fontSize) CTFontGetAdvancesForGlyphs(ctFont, .horizontal, &glyph, &advances, 1) return advances.width/2 } @@ -272,7 +271,8 @@ internal struct MathTable { } var rv = [GlyphPart]() for part in parts { - guard let partInfo = part as? NSDictionary, let glyph = font.get(glyphWithName: glyphName) else { continue } + guard let partInfo = part as? NSDictionary else { continue } + let glyph = font.get(glyphWithName: glyphName) var part = GlyphPart(glyph: glyph) if let adv = partInfo["advance"] as? NSNumber, let end = partInfo["endConnector"] as? NSNumber, diff --git a/Sources/SwiftMath/MathBundle/MTFontMathTableV2.swift b/Sources/SwiftMath/MathBundle/MTFontMathTableV2.swift new file mode 100644 index 0000000..6e580bc --- /dev/null +++ b/Sources/SwiftMath/MathBundle/MTFontMathTableV2.swift @@ -0,0 +1,160 @@ +// +// MTFontMathTableV2.swift +// +// +// Created by Peter Tang on 15/9/2023. +// + +import Foundation +import CoreGraphics +import CoreText + +internal class MTFontMathTableV2: MTFontMathTable { + private let mathFont: MathFont + private let fontSize: CGFloat + private let unitsPerEm: UInt + private let mTable: NSDictionary + init(mathFont: MathFont, size: CGFloat) { + self.mathFont = mathFont + self.fontSize = size + mTable = mathFont.mathTable() + unitsPerEm = mathFont.ctFont(withSize: fontSize).unitsPerEm + super.init(withFont: mathFont.mtfont(size: fontSize), mathTable: mTable) + super._mathTable = nil + // disable all possible access to _mathTable in superclass! + } + override var _mathTable: NSDictionary? { + set { fatalError("\(#function) change to _mathTable \(mathFont.rawValue) not allowed.") } + get { mTable } + } + override var muUnit: CGFloat { fontSize/18 } + + override func fontUnitsToPt(_ fontUnits:Int) -> CGFloat { + CGFloat(fontUnits) * fontSize / CGFloat(unitsPerEm) + } + override func constantFromTable(_ constName: String) -> CGFloat { + guard let consts = mTable[kConstants] as? NSDictionary, let val = consts[constName] as? NSNumber else { + return .zero + } + return fontUnitsToPt(val.intValue) + } + override func percentFromTable(_ percentName: String) -> CGFloat { + guard let consts = mTable[kConstants] as? NSDictionary, let val = consts[percentName] as? NSNumber else { + return .zero + } + return CGFloat(val.floatValue) / 100 + } + /** Returns an Array of all the vertical variants of the glyph if any. If + there are no variants for the glyph, the array contains the given glyph. */ + override func getVerticalVariantsForGlyph(_ glyph: CGGlyph) -> [NSNumber?] { + guard let variants = mTable[kVertVariants] as? NSDictionary else { return [] } + return self.getVariantsForGlyph(glyph, inDictionary: variants) + } + /** Returns an Array of all the horizontal variants of the glyph if any. If + there are no variants for the glyph, the array contains the given glyph. */ + override func getHorizontalVariantsForGlyph(_ glyph: CGGlyph) -> [NSNumber?] { + guard let variants = mTable[kHorizVariants] as? NSDictionary else { return [] } + return self.getVariantsForGlyph(glyph, inDictionary:variants) + } + override func getVariantsForGlyph(_ glyph: CGGlyph, inDictionary variants: NSDictionary) -> [NSNumber?] { + let font = mathFont.mtfont(size: fontSize) + let glyphName = font.get(nameForGlyph: glyph) + + var glyphArray = [NSNumber]() + let variantGlyphs = variants[glyphName] as? NSArray + + guard let variantGlyphs = variantGlyphs, variantGlyphs.count != .zero else { + // There are no extra variants, so just add the current glyph to it. + let glyph = font.get(glyphWithName: glyphName) + glyphArray.append(NSNumber(value:glyph)) + return glyphArray + } + for gvn in variantGlyphs { + if let glyphVariantName = gvn as? String { + let variantGlyph = font.get(glyphWithName: glyphVariantName) + glyphArray.append(NSNumber(value:variantGlyph)) + } + } + return glyphArray + } + /** Returns a larger vertical variant of the given glyph if any. + If there is no larger version, this returns the current glyph. + */ + override func getLargerGlyph(_ glyph: CGGlyph) -> CGGlyph { + let font = mathFont.mtfont(size: fontSize) + let glyphName = font.get(nameForGlyph: glyph) + + guard let variants = mTable[kVertVariants] as? NSDictionary, + let variantGlyphs = variants[glyphName] as? NSArray, variantGlyphs.count != .zero else { + // There are no extra variants, so just returnt the current glyph. + return glyph + } + // Find the first variant with a different name. + for gvn in variantGlyphs { + if let glyphVariantName = gvn as? String, glyphVariantName != glyphName { + let variantGlyph = font.get(glyphWithName: glyphVariantName) + return variantGlyph + } + } + // We did not find any variants of this glyph so return it. + return glyph + } + /** Returns the italic correction for the given glyph if any. If there + isn't any this returns 0. */ + override func getItalicCorrection(_ glyph: CGGlyph) -> CGFloat { + let font = mathFont.mtfont(size: fontSize) + let glyphName = font.get(nameForGlyph: glyph) + + guard let italics = mTable[kItalic] as? NSDictionary, let val = italics[glyphName] as? NSNumber else { + return .zero + } + // if val is nil, this returns 0. + return fontUnitsToPt(val.intValue) + } + override func getTopAccentAdjustment(_ glyph: CGGlyph) -> CGFloat { + let font = mathFont.mtfont(size: fontSize) + let glyphName = font.get(nameForGlyph: glyph) + + guard let accents = mTable[kAccents] as? NSDictionary, let val = accents[glyphName] as? NSNumber else { + // If no top accent is defined then it is the center of the advance width. + var glyph = glyph + var advances = CGSize.zero + CTFontGetAdvancesForGlyphs(font.ctFont, .horizontal, &glyph, &advances, 1) + return advances.width/2 + } + return fontUnitsToPt(val.intValue) + } + override func getVerticalGlyphAssembly(forGlyph glyph: CGGlyph) -> [GlyphPart] { + let font = mathFont.mtfont(size: fontSize) + let glyphName = font.get(nameForGlyph: glyph) + + guard let assemblyTable = mTable[kVertAssembly] as? NSDictionary, + let assemblyInfo = assemblyTable[glyphName] as? NSDictionary, + let parts = assemblyInfo[kAssemblyParts] as? NSArray else { + // No vertical assembly defined for glyph + // parts should always have been defined, but if it isn't return nil + return [] + } + + var rv = [GlyphPart]() + for part in parts { + guard let partInfo = part as? NSDictionary, + let adv = partInfo["advance"] as? NSNumber, + let end = partInfo["endConnector"] as? NSNumber, + let start = partInfo["startConnector"] as? NSNumber, + let ext = partInfo["extender"] as? NSNumber, + let glyphName = partInfo["glyph"] as? String else { continue } + let fullAdvance = fontUnitsToPt(adv.intValue) + let endConnectorLength = fontUnitsToPt(end.intValue) + let startConnectorLength = fontUnitsToPt(start.intValue) + let isExtender = ext.boolValue + let glyph = font.get(glyphWithName: glyphName) + let part = GlyphPart(glyph: glyph, fullAdvance: fullAdvance, + startConnectorLength: startConnectorLength, + endConnectorLength: endConnectorLength, + isExtender: isExtender) + rv.append(part) + } + return rv + } +} diff --git a/Sources/SwiftMath/MathBundle/MTFontV2.swift b/Sources/SwiftMath/MathBundle/MTFontV2.swift new file mode 100644 index 0000000..53b7fe3 --- /dev/null +++ b/Sources/SwiftMath/MathBundle/MTFontV2.swift @@ -0,0 +1,57 @@ +// +// MTFontV2.swift +// +// +// Created by Peter Tang on 15/9/2023. +// + +import Foundation +import CoreGraphics +import CoreText + +extension MathFont { + public func mtfont(size: CGFloat) -> MTFontV2 { + MTFontV2(font: self, size: size) + } +} +public final class MTFontV2: MTFont { + let font: MathFont + let size: CGFloat + private lazy var _cgFont: CGFont = { + font.cgFont() + }() + private lazy var _ctFont: CTFont = { + font.ctFont(withSize: size) + }() + private lazy var _mathTab = MTFontMathTableV2(mathFont: font, size: size) + init(font: MathFont = .latinModernFont, size: CGFloat) { + self.font = font + self.size = size + + super.init() + + super.defaultCGFont = nil + super.ctFont = nil + super.mathTable = nil + super.rawMathTable = nil + } + override var defaultCGFont: CGFont! { + set { fatalError("\(#function): change to \(font.fontName) not allowed.") } + get { _cgFont } + } + override var ctFont: CTFont! { + set { fatalError("\(#function): change to \(font.fontName) not allowed.") } + get { _ctFont } + } + override var mathTable: MTFontMathTable? { + set { fatalError("\(#function): change to \(font.rawValue) not allowed.") } + get { _mathTab } + } + override var rawMathTable: NSDictionary? { + set { fatalError("\(#function): change to \(font.rawValue) not allowed.") } + get { fatalError("\(#function): access to \(font.rawValue) not allowed.") } + } + public override func copy(withSize size: CGFloat) -> MTFont { + MTFontV2(font: font, size: size) + } +} diff --git a/Sources/SwiftMath/MathBundle/MathFont.swift b/Sources/SwiftMath/MathBundle/MathFont.swift index 129c350..4c8a1b6 100644 --- a/Sources/SwiftMath/MathBundle/MathFont.swift +++ b/Sources/SwiftMath/MathBundle/MathFont.swift @@ -1,5 +1,5 @@ // -// File.swift +// MathFont.swift // // // Created by Peter Tang on 10/9/2023. @@ -7,9 +7,7 @@ #if os(iOS) import UIKit -#endif - -#if os(macOS) +#elseif os(macOS) import AppKit #endif @@ -39,10 +37,10 @@ public enum MathFont: String, CaseIterable { case .termesFont: return "TeXGyreTermesMath-Regular" } } - public func cgFont() -> CGFont? { + public func cgFont() -> CGFont { BundleManager.manager.obtainCGFont(font: self) } - public func ctFont(withSize size: CGFloat) -> CTFont? { + public func ctFont(withSize size: CGFloat) -> CTFont { BundleManager.manager.obtainCTFont(font: self, withSize: size) } #if os(iOS) @@ -55,16 +53,10 @@ public enum MathFont: String, CaseIterable { NSFont(name: fontName, size: size) } #endif - internal func mathTable() -> NSDictionary? { + internal func mathTable() -> NSDictionary { BundleManager.manager.obtainMathTable(font: self) } - internal func get(nameForGlyph glyph: CGGlyph) -> String { - let name = cgFont()?.name(for: glyph) as? String - return name ?? "" - } - internal func get(glyphWithName name: String) -> CGGlyph? { - cgFont()?.getGlyphWithGlyphName(name: name as CFString) - } + } internal extension CTFont { /** The size of this font in points. */ @@ -104,7 +96,7 @@ private class BundleManager { guard CTFontManagerRegisterGraphicsFont(defaultCGFont, &errorRef) else { throw FontError.registerFailed } - print("mathFonts bundle resource: \(mathFont.rawValue), font: \(defaultCGFont.fullName!) registered.") + debugPrint("mathFonts bundle resource: \(mathFont.rawValue), font: \(defaultCGFont.fullName!) registered.") } private func registerMathTable(mathFont: MathFont) throws { @@ -117,9 +109,8 @@ private class BundleManager { version == "1.3" else { throw FontError.invalidMathTable } - //FIXME: mathTable = MTFontMathTable(withFont:self, mathTable:rawMathTable) mathTables[mathFont] = rawMathTable - print("mathFonts bundle resource: \(mathFont.rawValue).plist registered.") + debugPrint("mathFonts bundle resource: \(mathFont.rawValue).plist registered.") } private func registerAllBundleResources() { @@ -135,13 +126,28 @@ private class BundleManager { initializedOnceAlready.toggle() } - fileprivate func obtainCGFont(font: MathFont) -> CGFont? { - if !initializedOnceAlready { registerAllBundleResources() } - return cgFonts[font] + private func onDemandRegistration(mathFont: MathFont) { + guard cgFonts[mathFont] == nil else { return } + do { + try BundleManager.manager.registerCGFont(mathFont: mathFont) + try BundleManager.manager.registerMathTable(mathFont: mathFont) + + } catch { + fatalError("MTMathFonts:\(#function) ondemand loading failed, mathFont \(mathFont.rawValue), reason \(error)") + } + } + fileprivate func obtainCGFont(font: MathFont) -> CGFont { + // if !initializedOnceAlready { registerAllBundleResources() } + onDemandRegistration(mathFont: font) + guard let cgFont = cgFonts[font] else { + fatalError("\(#function) unable to locate CGFont \(font.fontName)") + } + return cgFont } - fileprivate func obtainCTFont(font: MathFont, withSize size: CGFloat) -> CTFont? { - if !initializedOnceAlready { registerAllBundleResources() } + fileprivate func obtainCTFont(font: MathFont, withSize size: CGFloat) -> CTFont { + // if !initializedOnceAlready { registerAllBundleResources() } + onDemandRegistration(mathFont: font) let fontPair = CTFontPair(font: font, size: size) guard let ctFont = ctFonts[fontPair] else { if let cgFont = cgFonts[font] { @@ -149,13 +155,17 @@ private class BundleManager { ctFonts[fontPair] = ctFont return ctFont } - return nil + fatalError("\(#function) unable to locate CGFont \(font.fontName), nor create CTFont") } return ctFont } - fileprivate func obtainMathTable(font: MathFont) -> NSDictionary? { - if !initializedOnceAlready { registerAllBundleResources() } - return mathTables[font] + fileprivate func obtainMathTable(font: MathFont) -> NSDictionary { + // if !initializedOnceAlready { registerAllBundleResources() } + onDemandRegistration(mathFont: font) + guard let mathTable = mathTables[font] else { + fatalError("\(#function) unable to locate mathTable: \(font.rawValue).plist") + } + return mathTable } deinit { ctFonts.removeAll() diff --git a/Sources/SwiftMath/MathBundle/MathImage.swift b/Sources/SwiftMath/MathBundle/MathImage.swift new file mode 100644 index 0000000..8235a4e --- /dev/null +++ b/Sources/SwiftMath/MathBundle/MathImage.swift @@ -0,0 +1,108 @@ +// +// MathImage.swift +// +// +// Created by Peter Tang on 15/9/2023. +// + +import Foundation + +#if os(iOS) + import UIKit +#elseif os(macOS) + import AppKit +#endif + +public struct MathImage { + public var font: MathFont = .latinModernFont + public var fontSize: CGFloat + public var textColor: MTColor + + public var labelMode: MTMathUILabelMode + public var textAlignment: MTTextAlignment + + public var contentInsets: MTEdgeInsets = MTEdgeInsetsZero + + public let latex: String + + private(set) var intrinsicContentSize = CGSize.zero + + public init(latex: String, fontSize: CGFloat, textColor: MTColor, labelMode: MTMathUILabelMode = .display, textAlignment: MTTextAlignment = .center) { + self.latex = latex + self.fontSize = fontSize + self.textColor = textColor + self.labelMode = labelMode + self.textAlignment = textAlignment + } +} +extension MathImage { + public var currentStyle: MTLineStyle { + switch labelMode { + case .display: return .display + case .text: return .text + } + } + private func intrinsicContentSize(_ displayList: MTMathListDisplay) -> CGSize { + CGSize(width: displayList.width + contentInsets.left + contentInsets.right, + height: displayList.ascent + displayList.descent + contentInsets.top + contentInsets.bottom) + } + public mutating func asImage() -> (NSError?, MTImage?) { + func layoutImage(size: CGSize, displayList: MTMathListDisplay) { + var textX = CGFloat(0) + switch self.textAlignment { + case .left: textX = contentInsets.left + case .center: textX = (size.width - contentInsets.left - contentInsets.right - displayList.width) / 2 + contentInsets.left + case .right: textX = size.width - displayList.width - contentInsets.right + } + let availableHeight = size.height - contentInsets.bottom - contentInsets.top + + // center things vertically + var height = displayList.ascent + displayList.descent + if height < fontSize/2 { + height = fontSize/2 // set height to half the font size + } + let textY = (availableHeight - height) / 2 + displayList.descent + contentInsets.bottom + displayList.position = CGPoint(x: textX, y: textY) + } + var error: NSError? + let mtfont: MTFont? = font.mtfont(size: fontSize) + guard let mathList = MTMathListBuilder.build(fromString: latex, error: &error), error == nil, + let displayList = MTTypesetter.createLineForMathList(mathList, font: mtfont, style: currentStyle) else { + return (error, nil) + } + + intrinsicContentSize = intrinsicContentSize(displayList) + displayList.textColor = textColor + + let size = intrinsicContentSize + layoutImage(size: size, displayList: displayList) + + #if os(iOS) + let renderer = UIGraphicsImageRenderer(size: size) + let image = renderer.image { rendererContext in + rendererContext.cgContext.saveGState() + rendererContext.cgContext.concatenate(.flippedVertically(size.height)) + displayList.draw(rendererContext.cgContext) + rendererContext.cgContext.restoreGState() + } + return (nil, image) + #endif + #if os(macOS) + let image = NSImage(size: size, flipped: false) { bounds in + guard let context = NSGraphicsContext.current?.cgContext else { return false } + context.saveGState() + displayList.draw(context) + context.restoreGState() + return true + } + return (nil, image) + #endif + } +} +private extension CGAffineTransform { + static func flippedVertically(_ height: CGFloat) -> CGAffineTransform { + var transform = CGAffineTransform(scaleX: 1, y: -1) + transform = transform.translatedBy(x: 0, y: -height) + return transform + } +} diff --git a/Tests/Obsolete/MathTableTests.swift b/Tests/Obsolete/MathTableTests.swift new file mode 100644 index 0000000..f72509b --- /dev/null +++ b/Tests/Obsolete/MathTableTests.swift @@ -0,0 +1,35 @@ +import XCTest +@testable import SwiftMath + +// +// MathTableTests.swift +// +// +// Created by Peter Tang on 12/9/2023. +// + +final class MathTableTests: XCTestCase { + func testMathFontScript() throws { + // let size = Int.random(in: 20 ... 40) + // MathFont.allCases.forEach { + // // print("\(#function) cgfont \($0.cgFont())") + // // print("\(#function) ctfont \($0.ctFont(withSize: CGFloat(size)))") + // // XCTAssertNotNil($0.cgFont()) + // // XCTAssertNotNil($0.ctFont(withSize: CGFloat(size))) + // // XCTAssertEqual($0.ctFont(withSize: CGFloat(size))?.fontSize, CGFloat(size), "ctFont fontSize test") + // let ctFont = $0.ctFont(withSize: CGFloat(size)) + // let unitsPerEm = ctFont.unitsPerEm + // let mathTable = MathTable(withFont: $0, fontSize: CGFloat(size), unitsPerEm: unitsPerEm) + // + // let values = [ + // mathTable.fractionNumeratorDisplayStyleShiftUp, + // mathTable.fractionNumeratorShiftUp, + // mathTable.fractionDenominatorDisplayStyleShiftDown, + // mathTable.fractionDenominatorShiftDown, + // mathTable.fractionNumeratorDisplayStyleGapMin, + // mathTable.fractionNumeratorGapMin, + // ] + // print("\(ctFont) -> \(values)") + // } + } +} diff --git a/Tests/SwiftMathTests/MTFontMathTableV2Tests.swift b/Tests/SwiftMathTests/MTFontMathTableV2Tests.swift new file mode 100644 index 0000000..0e2da91 --- /dev/null +++ b/Tests/SwiftMathTests/MTFontMathTableV2Tests.swift @@ -0,0 +1,28 @@ +// +// MTFontMathTableV2Tests.swift +// +// +// Created by Peter Tang on 15/9/2023. +// + +import XCTest +@testable import SwiftMath + +final class MTFontMathTableV2Tests: XCTestCase { + func testMTFontV2Script() throws { + let size = CGFloat(Int.random(in: 20 ... 40)) + MathFont.allCases.forEach { + let mTable = $0.mtfont(size: size).mathTable + XCTAssertNotNil(mTable) + let values = [ + mTable?.fractionNumeratorDisplayStyleShiftUp, + mTable?.fractionNumeratorShiftUp, + mTable?.fractionDenominatorDisplayStyleShiftDown, + mTable?.fractionDenominatorShiftDown, + mTable?.fractionNumeratorDisplayStyleGapMin, + mTable?.fractionNumeratorGapMin, + ].compactMap{$0} + print("\($0.rawValue).plist: \(values)") + } + } +} diff --git a/Tests/SwiftMathTests/MTFontV2Tests.swift b/Tests/SwiftMathTests/MTFontV2Tests.swift new file mode 100644 index 0000000..37c97ef --- /dev/null +++ b/Tests/SwiftMathTests/MTFontV2Tests.swift @@ -0,0 +1,21 @@ +// +// MTFontV2Tests.swift +// +// +// Created by Peter Tang on 15/9/2023. +// + +import XCTest +@testable import SwiftMath + +final class MTFontV2Tests: XCTestCase { + func testMTFontV2Script() throws { + let size = CGFloat(Int.random(in: 20 ... 40)) + MathFont.allCases.forEach { + let mtfont = $0.mtfont(size: size) + let mTable = mtfont.mathTable?._mathTable + XCTAssertNotNil(mtfont) + XCTAssertNotNil(mTable) + } + } +} diff --git a/Tests/SwiftMathTests/MathFontTests.swift b/Tests/SwiftMathTests/MathFontTests.swift index dff78fb..ed2f441 100644 --- a/Tests/SwiftMathTests/MathFontTests.swift +++ b/Tests/SwiftMathTests/MathFontTests.swift @@ -16,7 +16,7 @@ final class MathFontTests: XCTestCase { // print("\(#function) ctfont \($0.ctFont(withSize: CGFloat(size)))") XCTAssertNotNil($0.cgFont()) XCTAssertNotNil($0.ctFont(withSize: CGFloat(size))) - XCTAssertEqual($0.ctFont(withSize: CGFloat(size))?.fontSize, CGFloat(size), "ctFont fontSize test") + XCTAssertEqual($0.ctFont(withSize: CGFloat(size)).fontSize, CGFloat(size), "ctFont fontSize test") } #if os(iOS) // for family in UIFont.familyNames.sorted() { @@ -37,6 +37,13 @@ final class MathFontTests: XCTestCase { } #endif } + func testOnDemandMathFontScript() throws { + let size = Int.random(in: 20 ... 40) + let mathFont = MathFont.allCases.randomElement()! + XCTAssertNotNil(mathFont.cgFont()) + XCTAssertNotNil(mathFont.ctFont(withSize: CGFloat(size))) + XCTAssertEqual(mathFont.ctFont(withSize: CGFloat(size)).fontSize, CGFloat(size), "ctFont fontSize test") + } var fontNames: [String] { MathFont.allCases.map { $0.fontName } } diff --git a/Tests/SwiftMathTests/MathTableTests.swift b/Tests/SwiftMathTests/MathTableTests.swift deleted file mode 100644 index 21798b8..0000000 --- a/Tests/SwiftMathTests/MathTableTests.swift +++ /dev/null @@ -1,36 +0,0 @@ -import XCTest -@testable import SwiftMath - -// -// MathTableTests.swift -// -// -// Created by Peter Tang on 12/9/2023. -// - -final class MathTableTests: XCTestCase { - func testMathFontScript() throws { - let size = Int.random(in: 20 ... 40) - MathFont.allCases.forEach { - // print("\(#function) cgfont \($0.cgFont())") - // print("\(#function) ctfont \($0.ctFont(withSize: CGFloat(size)))") - // XCTAssertNotNil($0.cgFont()) - // XCTAssertNotNil($0.ctFont(withSize: CGFloat(size))) - // XCTAssertEqual($0.ctFont(withSize: CGFloat(size))?.fontSize, CGFloat(size), "ctFont fontSize test") - let ctFont = $0.ctFont(withSize: CGFloat(size)) - if let unitsPerEm = ctFont?.unitsPerEm { - let mathTable = MathTable(withFont: $0, fontSize: CGFloat(size), unitsPerEm: unitsPerEm) - - let values = [ - mathTable.fractionNumeratorDisplayStyleShiftUp, - mathTable.fractionNumeratorShiftUp, - mathTable.fractionDenominatorDisplayStyleShiftDown, - mathTable.fractionDenominatorShiftDown, - mathTable.fractionNumeratorDisplayStyleGapMin, - mathTable.fractionNumeratorGapMin, - ] - print("\(ctFont) -> \(values)") - } - } - } -}