add a fallback font system to render CJK text in the \text command
This commit is contained in:
10
Sources/SwiftMath/MathRender/MTFont.swift
Executable file → Normal file
10
Sources/SwiftMath/MathRender/MTFont.swift
Executable file → Normal file
@@ -11,12 +11,18 @@ import CoreText
|
||||
//
|
||||
|
||||
public class MTFont {
|
||||
|
||||
|
||||
var defaultCGFont: CGFont!
|
||||
var ctFont: CTFont!
|
||||
var mathTable: MTFontMathTable?
|
||||
var rawMathTable: NSDictionary?
|
||||
|
||||
|
||||
/// Fallback font for characters not supported by the main math font.
|
||||
/// Defaults to the system font at the same size. This is particularly useful
|
||||
/// for rendering text in \text{} commands with characters outside the math font's coverage
|
||||
/// (e.g., Chinese, Japanese, Korean, emoji, etc.)
|
||||
public var fallbackFont: CTFont?
|
||||
|
||||
init() {}
|
||||
|
||||
/// `MTFont(fontWithName:)` does not load the complete math font, it only has about half the glyphs of the full math font.
|
||||
|
||||
@@ -438,8 +438,15 @@ public struct MTMathListBuilder {
|
||||
} else {
|
||||
atom = MTMathAtomFactory.atom(forCharacter: char)
|
||||
if atom == nil {
|
||||
// Not a recognized character
|
||||
continue
|
||||
// Not a recognized character in standard math mode
|
||||
// In text mode (spacesAllowed && roman style), accept any Unicode character for fallback font support
|
||||
// This enables Chinese, Japanese, Korean, emoji, etc. in \text{} commands
|
||||
if spacesAllowed && currentFontStyle == .roman {
|
||||
atom = MTMathAtom(type: .ordinary, value: String(char))
|
||||
} else {
|
||||
// In math mode or non-text commands, skip unrecognized characters
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1276,11 +1276,18 @@ class MTTypesetter {
|
||||
func findGlyphForCharacterAtIndex(_ index:String.Index, inString str:String) -> CGGlyph {
|
||||
// Get the character at index taking into account UTF-32 characters
|
||||
var chars = Array(str[index].utf16)
|
||||
|
||||
|
||||
// Get the glyph from the font
|
||||
var glyph = [CGGlyph](repeating: CGGlyph.zero, count: chars.count)
|
||||
let found = CTFontGetGlyphsForCharacters(styleFont.ctFont, &chars, &glyph, chars.count)
|
||||
if !found {
|
||||
// Try fallback font if available
|
||||
if let fallbackFont = styleFont.fallbackFont {
|
||||
let fallbackFound = CTFontGetGlyphsForCharacters(fallbackFont, &chars, &glyph, chars.count)
|
||||
if fallbackFound {
|
||||
return glyph[0]
|
||||
}
|
||||
}
|
||||
// the font did not contain a glyph for our character, so we just return 0 (notdef)
|
||||
return 0
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user