Get all available characters from a font
For each UIFont, you have to get characterSet of that font. For example, I take first UIFont.
let firsttFont = UIFont.familyNames.first
let first = UIFont(name: firsttFont!, size: 14)
let fontDescriptor = first!.fontDescriptor
let characterSet : NSCharacterSet = fontDescriptor.object(forKey: UIFontDescriptorCharacterSetAttribute) as! NSCharacterSet
Then, use this extension to get all characters of that NSCharacterSet:
extension NSCharacterSet {
var characters:[String] {
var chars = [String]()
for plane:UInt8 in 0...16 {
if self.hasMemberInPlane(plane) {
let p0 = UInt32(plane) << 16
let p1 = (UInt32(plane) + 1) << 16
for c:UTF32Char in p0..<p1 {
if self.longCharacterIsMember(c) {
var c1 = c.littleEndian
let s = NSString(bytes: &c1, length: 4, encoding: String.Encoding.utf32LittleEndian.rawValue)!
chars.append(String(s))
}
}
}
}
return chars
}
}
(Ref: NSArray from NSCharacterset)
So, at last, just call characterSet.characters
to get all characters (in String)
How to get all characters of the font with CTFontCopyCharacterSet() in Swift?
CFCharacterSet
is toll-free bridged with the Cocoa Foundation counterpart NSCharacterSet
, and can be bridged to the corresponding Swift value type CharacterSet
:
let charset = CTFontCopyCharacterSet(ctFont) as CharacterSet
Then the approach from NSArray from NSCharacterSet can be used to enumerate all Unicode scalar values of that character set (including non-BMP points, i.e. Unicode scalar values greater than U+FFFF).
The CTFontGetGlyphsForCharacters()
expects non-BMP characters as surrogate pair, i.e. as an array of UTF-16 code units.
Putting it together, the function would look like this:
func createUnicodeFontMap(ctFont: CTFont) -> [CGGlyph : UnicodeScalar] {
let charset = CTFontCopyCharacterSet(ctFont) as CharacterSet
var glyphToUnicode = [CGGlyph : UnicodeScalar]() // Start with empty map.
// Enumerate all Unicode scalar values from the character set:
for plane: UInt8 in 0...16 where charset.hasMember(inPlane: plane) {
for unicode in UTF32Char(plane) << 16 ..< UTF32Char(plane + 1) << 16 {
if let uniChar = UnicodeScalar(unicode), charset.contains(uniChar) {
// Get glyph for this `uniChar` ...
let utf16 = Array(uniChar.utf16)
var glyphs = [CGGlyph](repeating: 0, count: utf16.count)
if CTFontGetGlyphsForCharacters(ctFont, utf16, &glyphs, utf16.count) {
// ... and add it to the map.
glyphToUnicode[glyphs[0]] = uniChar
}
}
}
}
return glyphToUnicode
}
Finding out what characters a given font supports
Here is a method using the fontTools Python library (which you can install with something like pip install fonttools
):
#!/usr/bin/env python
from itertools import chain
import sys
from fontTools.ttLib import TTFont
from fontTools.unicode import Unicode
with TTFont(
sys.argv[1], 0, allowVID=0, ignoreDecompileErrors=True, fontNumber=-1
) as ttf:
chars = chain.from_iterable(
[y + (Unicode[y[0]],) for y in x.cmap.items()] for x in ttf["cmap"].tables
)
if len(sys.argv) == 2: # print all code points
for c in chars:
print(c)
elif len(sys.argv) >= 3: # search code points / characters
code_points = {c[0] for c in chars}
for i in sys.argv[2:]:
code_point = int(i) # search code point
#code_point = ord(i) # search character
print(Unicode[code_point])
print(code_point in code_points)
The script takes as arguments the font path and optionally code points / characters to search for:
$ python checkfont.py /usr/share/fonts/**/DejaVuSans.ttf
(32, 'space', 'SPACE')
(33, 'exclam', 'EXCLAMATION MARK')
(34, 'quotedbl', 'QUOTATION MARK')
…
$ python checkfont.py /usr/share/fonts/**/DejaVuSans.ttf 65 12622 # a ㅎ
LATIN CAPITAL LETTER A
True
HANGUL LETTER HIEUH
False
c# get all characters of a font as array or list
Please check the following code by Jawahar Suresh Babu in CodeProject. I believe it does what you want.
Character Map in WPF
http://www.codeproject.com/Articles/396811/Character-Map-in-WPF
To get the character escaped code, you can change the Select
event handler method in the code above as follows:
private void Select(object sender, RoutedEventArgs e)
{
if (currentindex != -1)
{
text.BeginChange();
if (text.Selection.Text != string.Empty)
{
text.Selection.Text = string.Empty;
}
var ch = new Run(((SymbolView) canvas.Children[currentindex]).charcter.Text)
{
FontFamily = fonts.SelectedItem as FontFamily
};
text.CaretPosition.Paragraph.Inlines.Add(ch);
text.EndChange();
// Displays escaped char code
MessageBox.Show(string.Format("{0:X4}", (int) ch.Text[0]));
}
}
EDIT: Included change to get the character escaped code.
Related Topics
How to Add a Show More/Show Less Uibutton to Control Uitextview
How to Move Application's Window Between Virtual Desktops in Os X
Swift-Setting a Physics Body Velocity by Angle
How to Add 3D Shapes in Swift Ui
How to Create a Hotspot Network in iOS App Using Swift
How to Synchronize Coredata with Webservices in Swift
Format Println Output in a Table
Switching a @State Property to a @Binding Property Interferes with Animation
How to Replace the Values of Labels in iOS-Charts
Swift Sprite Kit in App Purchase
Swift Build Time Too Long When the Configuration Is 'Release'
Xcode11 Error "Open(_:Options:Completionhandler:) Is Unavailable in Application Extensions"
Adopting Customnserror in Decodingerror
How to Prevent Multiple Instances of the Same Window from Opening in MACos