Visual_Novel_iOS/crush/Crush/Src/Components/IconFont/MWIconFont.swift

206 lines
6.9 KiB
Swift
Raw Normal View History

2025-10-09 10:29:35 +00:00
//
// MWIconFont.swift
// Test
//
// Created by MYK on 2019/5/2.
// Copyright © 2019 MYK. All rights reserved.
//
import UIKit
/// IconFont
@objcMembers open class MWIconFont: UIFont, @unchecked Sendable {
static func printIconCodeEnum() {
guard let fileURL = Bundle.main.url(forResource: "iconfont", withExtension: "json"),
let data = try? Data(contentsOf: fileURL),
let dict = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let root = try? JSONDecoder().decode(IconFontRootModel.self, from: data) else {
print("Error loading or parsing JSON file")
return
}
let list = root.glyphs
var set: [String] = []
for obj in list {
// Convert name to camelCase and make first character lowercase
var name = obj.name
.replacingOccurrences(of: "-", with: "_")
.replacingOccurrences(of: " ", with: "_")
// Simple camelCase conversion (you might need a more sophisticated version)
let components = name.components(separatedBy: "_")
name = components.enumerated().map { (index, component) in
index == 0 ? component.lowercased() : component.capitalized
}.joined()
let code = obj.unicode
let result = "case \(name) = 0x\(code)"
set.append(result)
}
let printStr = set.joined(separator: "\n")
print("\n\(printStr)\n")
}
private class func iconFont(_ size: CGFloat) -> UIFont? {
if size == 0.0 {
return nil
}
let iconfont = "iconfont" //
loadMyCustomFont(iconfont)
return UIFont(name: iconfont, size: size)
}
private class func loadMyCustomFont(_ name: String) {
guard let fontPath = Bundle(for: MWIconFont.self).path(forResource: name, ofType: "ttf") else {
return
}
var error: Unmanaged<CFError>?
guard let data = try? Data(contentsOf: URL(fileURLWithPath: fontPath)),
let provider = CGDataProvider(data: data as CFData)
else {
return
}
if let font = CGFont(provider) {
CTFontManagerRegisterGraphicsFont(font, &error)
if error != nil {
return
}
}
}
/// IntStringUnicodeeg: 0xe624 -> \u{E624}
private class func stringForIcon(_ iconInt: UInt32) -> String? {
var rawIcon = iconInt
let xPtr = withUnsafeMutablePointer(to: &rawIcon) { $0 }
return String(bytesNoCopy: xPtr,
length: MemoryLayout<UInt32>.size,
encoding: String.Encoding.utf32LittleEndian,
freeWhenDone: false)
}
/// IconFont
///
/// - Parameters:
/// - iconInt: Unicode-Int eg: 0xe624
/// - size: fontSize
/// - color: fontColor
/// - Returns: font?
@objc public class func attributedString(
fromIconInt iconInt: UInt32,
size: CGFloat,
color: UIColor?) -> NSAttributedString?
{
guard let string = stringForIcon(iconInt) else {
return nil
}
return MWIconFont.attributedString(fromIconStr: string, size: size, color: color)
}
/// IconFont
///
/// - Parameters:
/// - iconStr: Unicode-String eg: "\u{E624}"
/// - size: fontSize
/// - color: fontColor
/// - Returns: font?
@objc public class func attributedString(
fromIconStr iconStr: String,
size: CGFloat,
color: UIColor?) -> NSAttributedString?
{
guard let font = MWIconFont.iconFont(size) else {
return nil
}
var attributes = [NSAttributedString.Key: AnyObject]()
attributes[NSAttributedString.Key.font] = font
if let color = color {
attributes[NSAttributedString.Key.foregroundColor] = color
}
return NSAttributedString(string: iconStr, attributes: attributes)
}
/// iconfontimage
///
/// - Parameters:
/// - iconInt: Unicode-Int eg: 0xe624
/// - size:
/// - color:
/// - Returns: image?
@objc public class func image(
fromIconInt iconInt: UInt32,
size: CGSize,
color: UIColor?,
edgeInsets: UIEdgeInsets = UIEdgeInsets.zero) -> UIImage?
{
guard let string = stringForIcon(iconInt) else {
return nil
}
return MWIconFont.image(fromIconStr: string, size: size, color: color, edgeInsets: edgeInsets)
}
@objc public class func image(
fromIcon iconEnum: IconCode,
size: CGSize,
color: UIColor?,
edgeInsets: UIEdgeInsets = UIEdgeInsets.zero) -> UIImage?
{
guard let string = stringForIcon(iconEnum.rawValue) else {
return nil
}
return MWIconFont.image(fromIconStr: string, size: size, color: color, edgeInsets: edgeInsets)
}
/// iconfontimage
///
/// - Parameters:
/// - iconStr: Unicode-String eg: "\u{E624}"
/// - size:
/// - color:
/// - Returns: image?
private class func image(
fromIconStr iconStr: String,
size: CGSize,
color: UIColor?,
edgeInsets: UIEdgeInsets = UIEdgeInsets.zero) -> UIImage?
{
if size == CGSize.zero {
return nil
}
let pointSize = min(size.width, size.height)
guard let aString = MWIconFont.attributedString(fromIconStr: iconStr, size: pointSize, color: color) else {
return nil
}
let mString = NSMutableAttributedString(attributedString: aString)
var rect = CGRect(origin: CGPoint.zero, size: size)
rect.origin.y -= edgeInsets.top
rect.size.width -= edgeInsets.left + edgeInsets.right //
rect.size.height -= edgeInsets.top + edgeInsets.bottom
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let range = NSRange(location: 0, length: mString.length)
mString.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: range)
// render the attributed string as image using Text Kit
UIGraphicsBeginImageContextWithOptions(rect.size, false, 0.0)
mString.draw(in: rect)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
struct IconFontRootModel: Codable {
let glyphs: [IconFontModel]
}
struct IconFontModel: Codable {
let name: String
let unicode: String
}