Add available font list
This commit is contained in:
parent
0ca6154229
commit
02509206ec
|
|
@ -16,6 +16,9 @@
|
|||
5705572E262C5F8B004A1FE3 /* FontModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5705572D262C5F8B004A1FE3 /* FontModel.swift */; };
|
||||
57055733262C602A004A1FE3 /* CharacterCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57055732262C602A004A1FE3 /* CharacterCellView.swift */; };
|
||||
5705573A262C61DF004A1FE3 /* NSCharacterSetExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57055739262C61DF004A1FE3 /* NSCharacterSetExtension.swift */; };
|
||||
57EDE58B262DC13600D4533C /* CharacterGraidView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57EDE58A262DC13600D4533C /* CharacterGraidView.swift */; };
|
||||
57EDE58F262DC22500D4533C /* FontProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57EDE58E262DC22500D4533C /* FontProvider.swift */; };
|
||||
57EDE593262DC5FC00D4533C /* AvailableFontListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57EDE592262DC5FC00D4533C /* AvailableFontListView.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
|
|
@ -30,6 +33,9 @@
|
|||
5705572D262C5F8B004A1FE3 /* FontModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontModel.swift; sourceTree = "<group>"; };
|
||||
57055732262C602A004A1FE3 /* CharacterCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCellView.swift; sourceTree = "<group>"; };
|
||||
57055739262C61DF004A1FE3 /* NSCharacterSetExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSCharacterSetExtension.swift; sourceTree = "<group>"; };
|
||||
57EDE58A262DC13600D4533C /* CharacterGraidView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterGraidView.swift; sourceTree = "<group>"; };
|
||||
57EDE58E262DC22500D4533C /* FontProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontProvider.swift; sourceTree = "<group>"; };
|
||||
57EDE592262DC5FC00D4533C /* AvailableFontListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvailableFontListView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -103,6 +109,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
5705572D262C5F8B004A1FE3 /* FontModel.swift */,
|
||||
57EDE58E262DC22500D4533C /* FontProvider.swift */,
|
||||
);
|
||||
path = Model;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -111,6 +118,8 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
57055732262C602A004A1FE3 /* CharacterCellView.swift */,
|
||||
57EDE58A262DC13600D4533C /* CharacterGraidView.swift */,
|
||||
57EDE592262DC5FC00D4533C /* AvailableFontListView.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -232,8 +241,11 @@
|
|||
5705571D262C5EA1004A1FE3 /* ContentView.swift in Sources */,
|
||||
5705571B262C5EA1004A1FE3 /* FontFaceApp.swift in Sources */,
|
||||
5705572E262C5F8B004A1FE3 /* FontModel.swift in Sources */,
|
||||
57EDE58B262DC13600D4533C /* CharacterGraidView.swift in Sources */,
|
||||
57EDE593262DC5FC00D4533C /* AvailableFontListView.swift in Sources */,
|
||||
5705573A262C61DF004A1FE3 /* NSCharacterSetExtension.swift in Sources */,
|
||||
57055733262C602A004A1FE3 /* CharacterCellView.swift in Sources */,
|
||||
57EDE58F262DC22500D4533C /* FontProvider.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -9,54 +9,18 @@ import SwiftUI
|
|||
|
||||
struct ContentView: View {
|
||||
|
||||
let columns = [
|
||||
GridItem(.flexible()),
|
||||
GridItem(.flexible()),
|
||||
GridItem(.flexible()),
|
||||
GridItem(.flexible()),
|
||||
GridItem(.flexible()),
|
||||
GridItem(.flexible()),
|
||||
]
|
||||
@State private var selectedFontFamily: String = ""
|
||||
@State private var selectedFontName: String = ""
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .top) {
|
||||
ScrollView {
|
||||
LazyVGrid(columns: columns) {
|
||||
ForEach(fetchFontList(), id: \.self) { characterModel in
|
||||
CharacterCellView(name: "PingFang", characterModel: characterModel)
|
||||
}
|
||||
}
|
||||
NavigationView {
|
||||
AvailableFontListView(selectedFontFamily: $selectedFontFamily, selectedFontName: $selectedFontName)
|
||||
CharacterGraidView(selectedFontFamily: $selectedFontFamily, selectedFontName: $selectedFontName)
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.frame(minWidth: 600, idealWidth: 700, minHeight: 400, idealHeight: 800, alignment: .center)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
Menu {
|
||||
|
||||
} label: {
|
||||
Image(systemName: "square.and.arrow.up.on.square.fill")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 获取字符集及其 Unicode
|
||||
/// - Returns: StringCharacter
|
||||
func fetchFontList() -> [CharacterModel] {
|
||||
if let name = NSFontManager.shared.availableFontFamilies.first {
|
||||
|
||||
if let font = NSFontManager.shared.font(withFamily: name, traits: .boldFontMask, weight: 1, size: 30) {
|
||||
|
||||
let set = font.coveredCharacterSet as NSCharacterSet
|
||||
|
||||
return set.characters
|
||||
}
|
||||
}
|
||||
|
||||
return []
|
||||
}
|
||||
|
||||
struct ContentView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import Foundation
|
|||
|
||||
struct FontModel: Hashable {
|
||||
var name: String
|
||||
var characters: [CharacterModel]
|
||||
var familyName: String
|
||||
}
|
||||
|
||||
struct CharacterModel: Hashable {
|
||||
|
|
@ -17,6 +17,6 @@ struct CharacterModel: Hashable {
|
|||
var unicode: String
|
||||
}
|
||||
|
||||
let mockFontModel = FontModel(name: "PingFang", characters: [mockCharacterModel])
|
||||
let mockFontModel = FontModel(name: "PingFang", familyName: "PingFang")
|
||||
|
||||
let mockCharacterModel = CharacterModel(character: "T", unicode: "\u{e638}")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,37 @@
|
|||
//
|
||||
// FontProvider.swift
|
||||
// FontFace (macOS)
|
||||
//
|
||||
// Created by 吕俊 on 2021/4/19.
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
|
||||
class FontProvider {
|
||||
static let shared = FontProvider()
|
||||
private init() {}
|
||||
|
||||
/// Fetch CharacterModel for given font family
|
||||
/// - Returns: CharacterModel List
|
||||
func fetchCharacterList(familyName: String) -> [CharacterModel] {
|
||||
|
||||
guard let font = NSFontManager.shared.font(withFamily: familyName, traits: .smallCapsFontMask, weight: 1, size: 30) else { return [] }
|
||||
|
||||
let set = font.coveredCharacterSet as NSCharacterSet
|
||||
|
||||
return set.characters.filter({ !$0.character.isEmpty || !$0.unicode.isEmpty})
|
||||
}
|
||||
|
||||
/// Fetch available font List
|
||||
/// - Returns: FontModel List
|
||||
func fetchAvailableFontList() -> [FontModel] {
|
||||
|
||||
return NSFontManager.shared.availableFontFamilies
|
||||
.compactMap({NSFontManager.shared.font(withFamily: $0, traits: .boldFontMask, weight: 1, size: 30)})
|
||||
.compactMap { font -> FontModel? in
|
||||
guard let name = font.displayName else { return nil }
|
||||
guard let familyName = font.familyName else { return nil }
|
||||
return FontModel(name: name, familyName: familyName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,6 @@ extension NSCharacterSet {
|
|||
let unicodeValue = String(data: dataenc!, encoding: String.Encoding.utf8) ?? ""
|
||||
|
||||
let v = CharacterModel(character: String(s), unicode: unicodeValue)
|
||||
|
||||
results.append(v)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// AvailableFontListView.swift
|
||||
// FontFace (macOS)
|
||||
//
|
||||
// Created by 吕俊 on 2021/4/19.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct AvailableFontListView: View {
|
||||
|
||||
@Binding var selectedFontFamily: String
|
||||
|
||||
@Binding var selectedFontName: String
|
||||
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
LazyVStack(alignment: .leading) {
|
||||
ForEach(FontProvider.shared.fetchAvailableFontList(), id: \.self) { fontModel in
|
||||
HStack {
|
||||
Text(fontModel.name)
|
||||
.font(.body)
|
||||
.padding()
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.onTapGesture {
|
||||
selectedFontFamily = fontModel.familyName
|
||||
selectedFontName = fontModel.name
|
||||
}
|
||||
.background(fontModel.name == selectedFontName ? Color.red : Color.clear)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct AvailableFontListView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
AvailableFontListView(selectedFontFamily: .constant(""), selectedFontName: .constant(""))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
//
|
||||
// CharacterGraidView.swift
|
||||
// FontFace (macOS)
|
||||
//
|
||||
// Created by 吕俊 on 2021/4/19.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct CharacterGraidView: View {
|
||||
|
||||
@Binding var selectedFontFamily: String
|
||||
@Binding var selectedFontName: String
|
||||
|
||||
let columns = [
|
||||
GridItem(.flexible()),
|
||||
GridItem(.flexible()),
|
||||
GridItem(.flexible()),
|
||||
GridItem(.flexible()),
|
||||
GridItem(.flexible()),
|
||||
GridItem(.flexible()),
|
||||
]
|
||||
|
||||
var body: some View {
|
||||
ZStack(alignment: .top) {
|
||||
let list = FontProvider.shared.fetchCharacterList(familyName: selectedFontFamily)
|
||||
|
||||
if list.isEmpty {
|
||||
Text("Select a font to preview")
|
||||
.font(.title)
|
||||
} else {
|
||||
ScrollView {
|
||||
LazyVGrid(columns: columns) {
|
||||
ForEach(list, id: \.self) { characterModel in
|
||||
CharacterCellView(name: selectedFontName, characterModel: characterModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.padding()
|
||||
.frame(minWidth: 600, idealWidth: 700, minHeight: 400, idealHeight: 800, alignment: .center)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .primaryAction) {
|
||||
Menu {
|
||||
|
||||
} label: {
|
||||
Image(systemName: "square.and.arrow.up.on.square.fill")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func empty() -> Bool {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct CharacterGraidView_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
CharacterGraidView(selectedFontFamily: .constant("PingFang"), selectedFontName: .constant("PingFang"))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue