1 module skia.SKFontManager;
2 
3 import skia.SKObject;
4 import skia.SkiaApi;
5 import skia.SKFontStyle;
6 import skia.SKTypeface;
7 import skia.SKStream;
8 import skia.Definitions;
9 import skia.SKData;
10 import skia.SKFontStyleSet;
11 import skia.SKString;
12 import skia.Exceptions;
13 import std.concurrency : initOnce;
14 
15 class SKFontManager : SKObject {
16 	// private static const SKFontManager defaultManager;
17 
18 	// static SKFontManager ()
19 	// {
20 	// 	defaultManager = new SKFontManagerStatic (SkiaApi.sk_fontmgr_ref_default ());
21 	// }
22 	static SKFontManager defaultManager() {
23 		__gshared SKFontManager defaultManager;
24 		return initOnce!defaultManager(new SKFontManagerStatic(SkiaApi.sk_fontmgr_ref_default()));
25 	}
26 
27 	static void EnsureStaticInstanceAreInitialized() {
28 		// IMPORTANT: do not remove to ensure that the static instances
29 		//            are initialized before any access is made to them
30 	}
31 
32 	this(void* handle, bool owns) {
33 		super(handle, owns);
34 	}
35 
36 	protected override void Dispose(bool disposing) {
37 		return super.Dispose(disposing);
38 	}
39 
40 	static SKFontManager Default() {
41 		return defaultManager;
42 	}
43 
44 	int FontFamilyCount() {
45 		return SkiaApi.sk_fontmgr_count_families(cast(sk_fontmgr_t*) Handle);
46 	}
47 
48 	// IEnumerable!(string) FontFamilies() {
49 
50 	// 		auto count = FontFamilyCount;
51 	// 		for (var i = 0; i < count; i++) {
52 	// 			yield return GetFamilyName (i);
53 	// 		}
54 
55 	// }
56 
57 	string GetFamilyName(int index) {
58 
59 		SKString str = new SKString();
60 		SkiaApi.sk_fontmgr_get_family_name(cast(sk_fontmgr_t*) Handle, index,
61 				cast(sk_string_t*) str.Handle);
62 		return cast(string) str;
63 	}
64 
65 	// string[] GetFontFamilies ()
66 	// {
67 	//   return FontFamilies.ToArray ();
68 	// } 
69 
70 	SKFontStyleSet GetFontStyles(int index) {
71 		return SKFontStyleSet.GetObject(
72 				SkiaApi.sk_fontmgr_create_styleset(cast(sk_fontmgr_t*) Handle, index));
73 	}
74 
75 	SKFontStyleSet GetFontStyles(string familyName) {
76 		return SKFontStyleSet.GetObject(
77 				SkiaApi.sk_fontmgr_match_family(cast(sk_fontmgr_t*) Handle, familyName));
78 	}
79 
80 	SKTypeface MatchFamily(string familyName) {
81 		return MatchFamily(familyName, SKFontStyle.Normal);
82 	}
83 
84 	SKTypeface MatchFamily(string familyName, SKFontStyle style) {
85 		if (style is null)
86 			throw new ArgumentNullException(style.stringof);
87 
88 		auto tf = SKTypeface.GetObject(SkiaApi.sk_fontmgr_match_family_style(cast(sk_fontmgr_t*) Handle,
89 				familyName, cast(sk_fontstyle_t*) style.Handle));
90 		tf.PreventPublicDisposal();
91 		return tf;
92 	}
93 
94 	SKTypeface MatchTypeface(SKTypeface face, SKFontStyle style) {
95 		if (face is null)
96 			throw new ArgumentNullException(face.stringof);
97 		if (style is null)
98 			throw new ArgumentNullException(style.stringof);
99 
100 		auto tf = SKTypeface.GetObject(SkiaApi.sk_fontmgr_match_face_style(cast(sk_fontmgr_t*) Handle,
101 				cast(sk_typeface_t*) face.Handle, cast(sk_fontstyle_t*) style.Handle));
102 		tf.PreventPublicDisposal();
103 		return tf;
104 	}
105 
106 	SKTypeface CreateTypeface(string path, int index = 0) {
107 		if (path is null)
108 			throw new ArgumentNullException(path.stringof);
109 
110 		// auto utf8path = StringUtilities.GetEncodedText (path, SKTextEncoding.Utf8, true);
111 		// byte* u = utf8path;
112 		string utf8path;
113 		return SKTypeface.GetObject(SkiaApi.sk_fontmgr_create_from_file(
114 				cast(sk_fontmgr_t*) Handle, utf8path, index));
115 	}
116 
117 	// SKTypeface CreateTypeface(Stream stream, int index = 0) {
118 	// 	if (&stream is null)
119 	// 		throw new ArgumentNullException(stream.stringof);
120 
121 	// 	// return CreateTypeface (new SKManagedStream (stream, true), index);
122 	// 	return null;
123 	// }
124 
125 	SKTypeface CreateTypeface(SKStreamAsset stream, int index = 0) {
126 		if (&stream is null)
127 			throw new ArgumentNullException(stream.stringof);
128 
129 		// SKManagedStream st = cast(SKManagedStream)stream;
130 		// if (st !is null) {
131 		// 	// SKManagedStream managed = stream;
132 		// 	// managed.ToMemoryStream ();
133 		// 	// managed.Dispose ();
134 		// }
135 
136 		auto typeface = SKTypeface.GetObject(SkiaApi.sk_fontmgr_create_from_stream(
137 				cast(sk_fontmgr_t*) Handle, cast(sk_stream_asset_t*) stream.Handle, index));
138 		stream.RevokeOwnership(typeface);
139 		return typeface;
140 	}
141 
142 	SKTypeface CreateTypeface(SKData data, int index = 0) {
143 		if (data is null)
144 			throw new ArgumentNullException(data.stringof);
145 
146 		return SKTypeface.GetObject(SkiaApi.sk_fontmgr_create_from_data(
147 				cast(sk_fontmgr_t*) Handle, cast(sk_data_t*) data.Handle, index));
148 	}
149 
150 	SKTypeface MatchCharacter(char character) {
151 		return MatchCharacter(null, SKFontStyle.Normal, null, character);
152 	}
153 
154 	SKTypeface MatchCharacter(int character) {
155 		return MatchCharacter(null, SKFontStyle.Normal, null, character);
156 	}
157 
158 	SKTypeface MatchCharacter(string familyName, char character) {
159 		return MatchCharacter(familyName, SKFontStyle.Normal, null, character);
160 	}
161 
162 	SKTypeface MatchCharacter(string familyName, int character) {
163 		return MatchCharacter(familyName, SKFontStyle.Normal, null, character);
164 	}
165 
166 	SKTypeface MatchCharacter(string familyName, string[] bcp47, char character) {
167 		return MatchCharacter(familyName, SKFontStyle.Normal, bcp47, character);
168 	}
169 
170 	SKTypeface MatchCharacter(string familyName, string[] bcp47, int character) {
171 		return MatchCharacter(familyName, SKFontStyle.Normal, bcp47, character);
172 	}
173 
174 	SKTypeface MatchCharacter(string familyName, SKFontStyleWeight weight,
175 			SKFontStyleWidth width, SKFontStyleSlant slant, string[] bcp47, char character) {
176 		return MatchCharacter(familyName, new SKFontStyle(weight, width, slant), bcp47, character);
177 	}
178 
179 	SKTypeface MatchCharacter(string familyName, SKFontStyleWeight weight,
180 			SKFontStyleWidth width, SKFontStyleSlant slant, string[] bcp47, int character) {
181 		return MatchCharacter(familyName, new SKFontStyle(weight, width, slant), bcp47, character);
182 	}
183 
184 	SKTypeface MatchCharacter(string familyName, int weight, int width,
185 			SKFontStyleSlant slant, string[] bcp47, int character) {
186 		return MatchCharacter(familyName, new SKFontStyle(weight, width, slant), bcp47, character);
187 	}
188 
189 	SKTypeface MatchCharacter(string familyName, SKFontStyle style, string[] bcp47, int character) {
190 		if (style is null)
191 			throw new ArgumentNullException(style.stringof);
192 
193 		// TODO: work around for https://bugs.chromium.org/p/skia/issues/detail?id=6196
194 		// if (familyName is null)
195 		// 	familyName = string.Empty;
196 
197 		auto tf = SKTypeface.GetObject(SkiaApi.sk_fontmgr_match_family_style_character(cast(sk_fontmgr_t*) Handle,
198 				familyName, cast(sk_fontstyle_t*) style.Handle, bcp47,
199 				cast(int)(bcp47.length ? bcp47.length : 0), character));
200 		tf.PreventPublicDisposal();
201 		return tf;
202 	}
203 
204 	static SKFontManager CreateDefault() {
205 		return GetObject(SkiaApi.sk_fontmgr_create_default());
206 	}
207 
208 	//
209 
210 	static SKFontManager GetObject(void* handle) {
211 		return GetOrAddObject!(SKFontManager)(handle, delegate SKFontManager(h, o) {
212 			return new SKFontManager(h, o);
213 		});
214 	}
215 
216 }
217 
218 //
219 
220 private final class SKFontManagerStatic : SKFontManager {
221 	this(void* x) {
222 		super(x, true);
223 		IgnorePublicDispose = true;
224 	}
225 }