using CPF.Mac.CoreFoundation; using CPF.Mac.CoreGraphics; using CPF.Mac.Foundation; using CPF.Mac.ObjCRuntime; using System; using System.Runtime.InteropServices; namespace CPF.Mac.CoreText { [Since(3, 2)] public class CTFont : INativeObject, IDisposable { internal IntPtr handle; public IntPtr Handle => handle; public double Size => CTFontGetSize(handle); public CGAffineTransform Matrix => CTFontGetMatrix(handle); public CTFontSymbolicTraits SymbolicTraits => CTFontGetSymbolicTraits(handle); public string PostScriptName => GetStringAndRelease(CTFontCopyPostScriptName(handle)); public string FamilyName => GetStringAndRelease(CTFontCopyFamilyName(handle)); public string FullName => GetStringAndRelease(CTFontCopyFullName(handle)); public string DisplayName => GetStringAndRelease(CTFontCopyDisplayName(handle)); public NSCharacterSet CharacterSet { get { NSCharacterSet nSCharacterSet = (NSCharacterSet)Runtime.GetNSObject(CTFontCopyCharacterSet(handle)); if (nSCharacterSet == null) { return null; } nSCharacterSet.Release(); return nSCharacterSet; } } public uint StringEncoding => CTFontGetStringEncoding(handle); public double AscentMetric => CTFontGetAscent(handle); public double DescentMetric => CTFontGetDescent(handle); public double LeadingMetric => CTFontGetLeading(handle); public uint UnitsPerEmMetric => CTFontGetUnitsPerEm(handle); public int GlyphCount => CTFontGetGlyphCount(handle); public CGRect BoundingBox => CTFontGetBoundingBox(handle); public double UnderlinePosition => CTFontGetUnderlinePosition(handle); public double UnderlineThickness => CTFontGetUnderlineThickness(handle); public double SlantAngle => CTFontGetSlantAngle(handle); public double CapHeightMetric => CTFontGetCapHeight(handle); public double XHeightMetric => CTFontGetXHeight(handle); internal CTFont(IntPtr handle) : this(handle, owns: false) { } internal CTFont(IntPtr handle, bool owns) { if (handle == IntPtr.Zero) { GC.SuppressFinalize(this); throw new ArgumentNullException("handle"); } this.handle = handle; if (!owns) { CFObject.CFRetain(handle); } } ~CTFont() { Dispose(disposing: false); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (handle != IntPtr.Zero) { CFObject.CFRelease(handle); handle = IntPtr.Zero; } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateWithName(IntPtr name, double size, IntPtr matrix); public CTFont(string name, double size) { if (name == null) { throw ConstructorError.ArgumentNull(this, "name"); } using (NSString nSString = new NSString(name)) { handle = CTFontCreateWithName(nSString.Handle, size, IntPtr.Zero); } if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateWithName(IntPtr name, double size, ref CGAffineTransform matrix); public CTFont(string name, double size, ref CGAffineTransform matrix) { if (name == null) { throw ConstructorError.ArgumentNull(this, "name"); } using (CFString cFString = (CFString)name) { handle = CTFontCreateWithName(cFString.Handle, size, ref matrix); } if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateWithFontDescriptor(IntPtr descriptor, double size, IntPtr matrix); public CTFont(CTFontDescriptor descriptor, double size) { if (descriptor == null) { throw ConstructorError.ArgumentNull(this, "descriptor"); } handle = CTFontCreateWithFontDescriptor(descriptor.Handle, size, IntPtr.Zero); if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateWithFontDescriptor(IntPtr descriptor, double size, ref CGAffineTransform matrix); public CTFont(CTFontDescriptor descriptor, double size, ref CGAffineTransform matrix) { if (descriptor == null) { throw ConstructorError.ArgumentNull(this, "descriptor"); } handle = CTFontCreateWithFontDescriptor(descriptor.Handle, size, ref matrix); if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateWithNameAndOptions(IntPtr name, double size, IntPtr matrix, CTFontOptions options); public CTFont(string name, double size, CTFontOptions options) { if (name == null) { throw ConstructorError.ArgumentNull(this, "name"); } using (CFString cFString = (CFString)name) { handle = CTFontCreateWithNameAndOptions(cFString.Handle, size, IntPtr.Zero, options); } if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateWithNameAndOptions(IntPtr name, double size, ref CGAffineTransform matrix, CTFontOptions options); public CTFont(string name, double size, ref CGAffineTransform matrix, CTFontOptions options) { if (name == null) { throw ConstructorError.ArgumentNull(this, "name"); } using (CFString cFString = (CFString)name) { handle = CTFontCreateWithNameAndOptions(cFString.Handle, size, ref matrix, options); } if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateWithFontDescriptorAndOptions(IntPtr descriptor, double size, IntPtr matrix, CTFontOptions options); public CTFont(CTFontDescriptor descriptor, double size, CTFontOptions options) { if (descriptor == null) { throw ConstructorError.ArgumentNull(this, "descriptor"); } handle = CTFontCreateWithFontDescriptorAndOptions(descriptor.Handle, size, IntPtr.Zero, options); if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateWithFontDescriptorAndOptions(IntPtr descriptor, double size, ref CGAffineTransform matrix, CTFontOptions options); public CTFont(CTFontDescriptor descriptor, double size, CTFontOptions options, ref CGAffineTransform matrix) { if (descriptor == null) { throw ConstructorError.ArgumentNull(this, "descriptor"); } handle = CTFontCreateWithFontDescriptorAndOptions(descriptor.Handle, size, ref matrix, options); if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateWithGraphicsFont(IntPtr cgfontRef, double size, ref CGAffineTransform affine, IntPtr attrs); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText", EntryPoint = "CTFontCreateWithGraphicsFont")] private static extern IntPtr CTFontCreateWithGraphicsFont2(IntPtr cgfontRef, double size, IntPtr affine, IntPtr attrs); public CTFont(CGFont font, double size, CGAffineTransform transform, CTFontDescriptor descriptor) { if (font == null) { throw new ArgumentNullException("font"); } handle = CTFontCreateWithGraphicsFont(font.Handle, size, ref transform, descriptor?.Handle ?? IntPtr.Zero); if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } public CTFont(CGFont font, double size, CTFontDescriptor descriptor) { if (font == null) { throw new ArgumentNullException("font"); } handle = CTFontCreateWithGraphicsFont2(font.Handle, size, IntPtr.Zero, descriptor?.Handle ?? IntPtr.Zero); if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } public CTFont(CGFont font, double size, CGAffineTransform transform) { if (font == null) { throw new ArgumentNullException("font"); } handle = CTFontCreateWithGraphicsFont(font.Handle, size, ref transform, IntPtr.Zero); if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateUIFontForLanguage(CTFontUIFontType uiType, double size, IntPtr language); public CTFont(CTFontUIFontType uiType, double size, string language) { if (language == null) { throw ConstructorError.ArgumentNull(this, "language"); } using (CFString cFString = (CFString)language) { handle = CTFontCreateUIFontForLanguage(uiType, size, cFString.Handle); } if (handle == IntPtr.Zero) { throw ConstructorError.Unknown(this); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateCopyWithAttributes(IntPtr font, double size, IntPtr matrix, IntPtr attributues); public CTFont WithAttributes(double size, CTFontDescriptor attributes) { if (attributes == null) { throw new ArgumentNullException("attributes"); } return CreateFont(CTFontCreateCopyWithAttributes(handle, size, IntPtr.Zero, attributes.Handle)); } private static CTFont CreateFont(IntPtr h) { if (h == IntPtr.Zero) { return null; } return new CTFont(h, owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateCopyWithAttributes(IntPtr font, double size, ref CGAffineTransform matrix, IntPtr attributues); public CTFont WithAttributes(double size, CTFontDescriptor attributes, ref CGAffineTransform matrix) { if (attributes == null) { throw new ArgumentNullException("attributes"); } return CreateFont(CTFontCreateCopyWithAttributes(handle, size, ref matrix, attributes.Handle)); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateCopyWithSymbolicTraits(IntPtr font, double size, IntPtr matrix, CTFontSymbolicTraits symTraitValue, CTFontSymbolicTraits symTraitMask); public CTFont WithSymbolicTraits(double size, CTFontSymbolicTraits symTraitValue, CTFontSymbolicTraits symTraitMask) { return CreateFont(CTFontCreateCopyWithSymbolicTraits(handle, size, IntPtr.Zero, symTraitValue, symTraitMask)); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateCopyWithSymbolicTraits(IntPtr font, double size, ref CGAffineTransform matrix, CTFontSymbolicTraits symTraitValue, CTFontSymbolicTraits symTraitMask); public CTFont WithSymbolicTraits(double size, CTFontSymbolicTraits symTraitValue, CTFontSymbolicTraits symTraitMask, ref CGAffineTransform matrix) { return CreateFont(CTFontCreateCopyWithSymbolicTraits(handle, size, ref matrix, symTraitValue, symTraitMask)); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateCopyWithFamily(IntPtr font, double size, IntPtr matrix, IntPtr family); public CTFont WithFamily(double size, string family) { if (family == null) { throw new ArgumentNullException("family"); } using (CFString cFString = (CFString)family) { return CreateFont(CTFontCreateCopyWithFamily(handle, size, IntPtr.Zero, cFString.Handle)); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateCopyWithFamily(IntPtr font, double size, ref CGAffineTransform matrix, IntPtr family); public CTFont WithFamily(double size, string family, ref CGAffineTransform matrix) { if (family == null) { throw new ArgumentNullException("family"); } using (CFString cFString = (CFString)family) { return CreateFont(CTFontCreateCopyWithFamily(handle, size, ref matrix, cFString.Handle)); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreateForString(IntPtr currentFont, IntPtr @string, NSRange range); public CTFont ForString(string value, NSRange range) { if (value == null) { throw new ArgumentNullException("value"); } using (CFString cFString = (CFString)value) { return CreateFont(CTFontCreateForString(handle, cFString.Handle, range)); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyFontDescriptor(IntPtr font); public CTFontDescriptor GetFontDescriptor() { IntPtr value = CTFontCopyFontDescriptor(handle); if (value == IntPtr.Zero) { return null; } return new CTFontDescriptor(value, owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyAttribute(IntPtr font, IntPtr attribute); public NSObject GetAttribute(NSString attribute) { if (attribute == null) { throw new ArgumentNullException("attribute"); } return Runtime.GetNSObject(CTFontCopyAttribute(handle, attribute.Handle)); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern double CTFontGetSize(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern CGAffineTransform CTFontGetMatrix(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern CTFontSymbolicTraits CTFontGetSymbolicTraits(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyTraits(IntPtr font); public CTFontTraits GetTraits() { NSDictionary nSDictionary = (NSDictionary)Runtime.GetNSObject(CTFontCopyTraits(handle)); if (nSDictionary == null) { return null; } nSDictionary.Release(); return new CTFontTraits(nSDictionary); } private static string GetStringAndRelease(IntPtr cfStringRef) { if (cfStringRef == IntPtr.Zero) { return null; } using (CFString x = new CFString(cfStringRef, owns: true)) { return x; } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyPostScriptName(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyFamilyName(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyFullName(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyDisplayName(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyName(IntPtr font, IntPtr nameKey); public string GetName(CTFontNameKey nameKey) { return GetStringAndRelease(CTFontCopyName(handle, CTFontNameKeyId.ToId(nameKey).Handle)); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyLocalizedName(IntPtr font, IntPtr nameKey); public string GetLocalizedName(CTFontNameKey nameKey) { return GetStringAndRelease(CTFontCopyLocalizedName(handle, CTFontNameKeyId.ToId(nameKey).Handle)); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyCharacterSet(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern uint CTFontGetStringEncoding(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopySupportedLanguages(IntPtr font); public string[] GetSupportedLanguages() { IntPtr intPtr = CTFontCopySupportedLanguages(handle); if (intPtr == IntPtr.Zero) { return new string[0]; } string[] result = NSArray.ArrayFromHandle(intPtr, CFString.FetchString); CFObject.CFRelease(intPtr); return result; } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern bool CTFontGetGlyphsForCharacters(IntPtr font, [In] char[] characters, [Out] ushort[] glyphs, int count); public bool GetGlyphsForCharacters(char[] characters, ushort[] glyphs, int count) { AssertCount(count); AssertLength("characters", characters, count); AssertLength("glyphs", characters, count); return CTFontGetGlyphsForCharacters(handle, characters, glyphs, count); } public bool GetGlyphsForCharacters(char[] characters, ushort[] glyphs) { return GetGlyphsForCharacters(characters, glyphs, Math.Min(characters.Length, glyphs.Length)); } private static void AssertCount(int count) { if (count < 0) { throw new ArgumentOutOfRangeException("count", "cannot be negative"); } } private static void AssertLength(string name, T[] array, int count) { AssertLength(name, array, count, canBeNull: false); } private static void AssertLength(string name, T[] array, int count, bool canBeNull) { if (!canBeNull || array != null) { if (array == null) { throw new ArgumentNullException(name); } if (array.Length < count) { throw new ArgumentException($"{name}.Length cannot be < count", name); } } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern double CTFontGetAscent(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern double CTFontGetDescent(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern double CTFontGetLeading(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern uint CTFontGetUnitsPerEm(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern int CTFontGetGlyphCount(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern CGRect CTFontGetBoundingBox(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern double CTFontGetUnderlinePosition(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern double CTFontGetUnderlineThickness(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern double CTFontGetSlantAngle(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern double CTFontGetCapHeight(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern double CTFontGetXHeight(IntPtr font); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern ushort CTFontGetGlyphWithName(IntPtr font, IntPtr glyphName); public ushort GetGlyphWithName(string glyphName) { if (glyphName == null) { throw new ArgumentNullException("glyphName"); } using (NSString nSString = new NSString(glyphName)) { return CTFontGetGlyphWithName(handle, nSString.Handle); } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern CGRect CTFontGetBoundingRectsForGlyphs(IntPtr font, CTFontOrientation orientation, [In] ushort[] glyphs, [Out] CGRect[] boundingRects, int count); public CGRect GetBoundingRects(CTFontOrientation orientation, ushort[] glyphs, CGRect[] boundingRects, int count) { AssertCount(count); AssertLength("glyphs", glyphs, count); AssertLength("boundingRects", boundingRects, count, canBeNull: true); return CTFontGetBoundingRectsForGlyphs(handle, orientation, glyphs, boundingRects, count); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern CGRect CTFontGetOpticalBoundsForGlyphs(IntPtr font, [In] ushort[] glyphs, [Out] CGRect[] boundingRects, int count, CTFontOptions options); [Since(6, 0)] public CGRect GetOpticalBounds(ushort[] glyphs, CGRect[] boundingRects, int count, CTFontOptions options = CTFontOptions.Default) { AssertCount(count); AssertLength("glyphs", glyphs, count); AssertLength("boundingRects", boundingRects, count, canBeNull: true); return CTFontGetOpticalBoundsForGlyphs(handle, glyphs, boundingRects, count, CTFontOptions.Default); } public CGRect GetBoundingRects(CTFontOrientation orientation, ushort[] glyphs) { if (glyphs == null) { throw new ArgumentNullException("glyphs"); } return GetBoundingRects(orientation, glyphs, null, glyphs.Length); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern double CTFontGetAdvancesForGlyphs(IntPtr font, CTFontOrientation orientation, [In] ushort[] glyphs, [Out] CGSize[] advances, int count); public double GetAdvancesForGlyphs(CTFontOrientation orientation, ushort[] glyphs, CGSize[] advances, int count) { AssertCount(count); AssertLength("glyphs", glyphs, count); AssertLength("advances", advances, count, canBeNull: true); return CTFontGetAdvancesForGlyphs(handle, orientation, glyphs, advances, count); } public double GetAdvancesForGlyphs(CTFontOrientation orientation, ushort[] glyphs) { if (glyphs == null) { throw new ArgumentNullException("glyphs"); } return GetAdvancesForGlyphs(orientation, glyphs, null, glyphs.Length); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern void CTFontGetVerticalTranslationsForGlyphs(IntPtr font, [In] ushort[] glyphs, [Out] CGSize[] translations, int count); public void GetVerticalTranslationsForGlyphs(ushort[] glyphs, CGSize[] translations, int count) { AssertCount(count); AssertLength("glyphs", glyphs, count); AssertLength("translations", translations, count); CTFontGetVerticalTranslationsForGlyphs(handle, glyphs, translations, count); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreatePathForGlyph(IntPtr font, ushort glyph, IntPtr transform); public CGPath GetPathForGlyph(ushort glyph) { IntPtr value = CTFontCreatePathForGlyph(handle, glyph, IntPtr.Zero); if (value == IntPtr.Zero) { return null; } return new CGPath(value, owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCreatePathForGlyph(IntPtr font, ushort glyph, ref CGAffineTransform transform); public CGPath GetPathForGlyph(ushort glyph, ref CGAffineTransform transform) { IntPtr value = CTFontCreatePathForGlyph(handle, glyph, ref transform); if (value == IntPtr.Zero) { return null; } return new CGPath(value, owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern void CTFontDrawGlyphs(IntPtr font, [In] ushort[] glyphs, [In] CGPoint[] positions, int count, IntPtr context); [Since(4, 2)] public void DrawGlyphs(CGContext context, ushort[] glyphs, CGPoint[] positions) { if (context == null) { throw new ArgumentNullException("context"); } if (glyphs == null) { throw new ArgumentNullException("glyphs"); } if (positions == null) { throw new ArgumentNullException("positions"); } int num = glyphs.Length; if (num != positions.Length) { throw new ArgumentException("array sizes fo context and glyphs differ"); } CTFontDrawGlyphs(handle, glyphs, positions, num, context.Handle); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern int CTFontGetLigatureCaretPositions(IntPtr handle, ushort glyph, [Out] double[] positions, int max); [Since(4, 2)] public int GetLigatureCaretPositions(ushort glyph, double[] positions) { if (positions == null) { throw new ArgumentNullException("positions"); } return CTFontGetLigatureCaretPositions(handle, glyph, positions, positions.Length); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyVariationAxes(IntPtr font); public CTFontVariationAxes[] GetVariationAxes() { IntPtr intPtr = CTFontCopyVariationAxes(handle); if (intPtr == IntPtr.Zero) { return new CTFontVariationAxes[0]; } CTFontVariationAxes[] result = NSArray.ArrayFromHandle(intPtr, (IntPtr d) => new CTFontVariationAxes((NSDictionary)Runtime.GetNSObject(d))); CFObject.CFRelease(intPtr); return result; } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyVariation(IntPtr font); public CTFontVariation GetVariation() { IntPtr intPtr = CTFontCopyVariation(handle); if (intPtr == IntPtr.Zero) { return null; } return new CTFontVariation((NSDictionary)Runtime.GetNSObject(intPtr)); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyFeatures(IntPtr font); public CTFontFeatures[] GetFeatures() { IntPtr intPtr = CTFontCopyFeatures(handle); if (intPtr == IntPtr.Zero) { return new CTFontFeatures[0]; } CTFontFeatures[] result = NSArray.ArrayFromHandle(intPtr, (IntPtr d) => new CTFontFeatures((NSDictionary)Runtime.GetNSObject(d))); CFObject.CFRelease(intPtr); return result; } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyFeatureSettings(IntPtr font); public CTFontFeatureSettings[] GetFeatureSettings() { IntPtr intPtr = CTFontCopyFeatureSettings(handle); if (intPtr == IntPtr.Zero) { return new CTFontFeatureSettings[0]; } CTFontFeatureSettings[] result = NSArray.ArrayFromHandle(intPtr, (IntPtr d) => new CTFontFeatureSettings((NSDictionary)Runtime.GetNSObject(d))); CFObject.CFRelease(intPtr); return result; } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyGraphicsFont(IntPtr font, IntPtr attributes); public CGFont ToCGFont(CTFontDescriptor attributes) { IntPtr value = CTFontCopyGraphicsFont(handle, attributes?.Handle ?? IntPtr.Zero); if (value == IntPtr.Zero) { return null; } return new CGFont(value, owns: true); } public CGFont ToCGFont() { return ToCGFont(null); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyAvailableTables(IntPtr font, CTFontTableOptions options); public CTFontTable[] GetAvailableTables(CTFontTableOptions options) { IntPtr intPtr = CTFontCopyAvailableTables(handle, options); if (intPtr == IntPtr.Zero) { return new CTFontTable[0]; } CTFontTable[] result = NSArray.ArrayFromHandle(intPtr, (IntPtr v) => (CTFontTable)(int)v); CFObject.CFRelease(intPtr); return result; } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText")] private static extern IntPtr CTFontCopyTable(IntPtr font, CTFontTable table, CTFontTableOptions options); public NSData GetFontTableData(CTFontTable table, CTFontTableOptions options) { IntPtr value = CTFontCopyTable(handle, table, options); if (value == IntPtr.Zero) { return null; } NSData nSData = new NSData(value); nSData.Release(); return nSData; } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText", EntryPoint = "CTFontGetTypeID")] private static extern IntPtr CTFontCopyDefaultCascadeListForLanguages(IntPtr font, IntPtr languagePrefList); [Since(6, 0)] public CTFontDescriptor[] GetDefaultCascadeList(string[] languages) { if (languages == null) { throw new ArgumentNullException("languages"); } using (NSArray nSArray = NSArray.FromStrings(languages)) { using (CFArray cFArray = new CFArray(CTFontCopyDefaultCascadeListForLanguages(handle, nSArray.Handle), owns: true)) { int count = cFArray.Count; CTFontDescriptor[] array = new CTFontDescriptor[count]; for (int i = 0; i < count; i++) { array[i] = new CTFontDescriptor(cFArray.GetValue(i), owns: true); } return array; } } } public override string ToString() { return FullName; } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Frameworks/CoreText.framework/CoreText", EntryPoint = "CTFontGetTypeID")] public static extern int GetTypeID(); } }