1/* Pango
2 * pango-ot-info.c: Store tables for OpenType
3 *
4 * Copyright (C) 2000 Red Hat Software
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
20 */
21
22#include "config.h"
23
24#include "pango-ot-private.h"
25
26static void pango_ot_info_finalize (GObject *object);
27
28G_DEFINE_TYPE (PangoOTInfo, pango_ot_info, G_TYPE_OBJECT);
29
30static void
31pango_ot_info_init (PangoOTInfo *self)
32{
33}
34
35static void
36pango_ot_info_class_init (PangoOTInfoClass *klass)
37{
38 GObjectClass *object_class = G_OBJECT_CLASS (klass);
39
40 object_class->finalize = pango_ot_info_finalize;
41}
42
43static void
44pango_ot_info_finalize (GObject *object)
45{
46 PangoOTInfo *info = PANGO_OT_INFO (object);
47
48 if (info->hb_face)
49 hb_face_destroy (face: info->hb_face);
50
51 G_OBJECT_CLASS (pango_ot_info_parent_class)->finalize (object);
52}
53
54static void
55pango_ot_info_finalizer (void *object)
56{
57 FT_Face face = object;
58 PangoOTInfo *info = face->generic.data;
59
60 info->face = NULL;
61 g_object_unref (object: info);
62}
63
64
65/**
66 * pango_ot_info_get:
67 * @face: a `FT_Face`
68 *
69 * Returns the `PangoOTInfo` structure for the given FreeType font face.
70 *
71 * Return value: (transfer none): the `PangoOTInfo` for @face.
72 * This object will have the same lifetime as @face.
73 *
74 * Since: 1.2
75 */
76PangoOTInfo *
77pango_ot_info_get (FT_Face face)
78{
79 PangoOTInfo *info;
80
81 if (G_UNLIKELY (!face))
82 return NULL;
83
84 if (G_LIKELY (face->generic.data && face->generic.finalizer == pango_ot_info_finalizer))
85 return face->generic.data;
86 else
87 {
88 if (face->generic.finalizer)
89 face->generic.finalizer (face);
90
91 info = face->generic.data = g_object_new (PANGO_TYPE_OT_INFO, NULL);
92 face->generic.finalizer = pango_ot_info_finalizer;
93
94 info->face = face;
95 info->hb_face = hb_ft_face_create (ft_face: face, NULL);
96 }
97
98 return info;
99}
100
101static hb_tag_t
102get_hb_table_type (PangoOTTableType table_type)
103{
104 switch (table_type) {
105 case PANGO_OT_TABLE_GSUB: return HB_OT_TAG_GSUB;
106 case PANGO_OT_TABLE_GPOS: return HB_OT_TAG_GPOS;
107 default: return HB_TAG_NONE;
108 }
109}
110
111/**
112 * pango_ot_info_find_script:
113 * @info: a `PangoOTInfo`
114 * @table_type: the table type to obtain information about
115 * @script_tag: the tag of the script to find
116 * @script_index: (out) (optional): location to store the index of the script
117 *
118 * Finds the index of a script.
119 *
120 * If not found, tries to find the 'DFLT' and then 'dflt' scripts and
121 * return the index of that in @script_index. If none of those is found
122 * either, %PANGO_OT_NO_SCRIPT is placed in @script_index.
123 *
124 * All other functions taking an input script_index parameter know
125 * how to handle %PANGO_OT_NO_SCRIPT, so one can ignore the return
126 * value of this function completely and proceed, to enjoy the automatic
127 * fallback to the 'DFLT'/'dflt' script.
128 *
129 * Return value: %TRUE if the script was found
130 */
131gboolean
132pango_ot_info_find_script (PangoOTInfo *info,
133 PangoOTTableType table_type,
134 PangoOTTag script_tag,
135 guint *script_index)
136{
137 hb_tag_t tt = get_hb_table_type (table_type);
138
139 return hb_ot_layout_table_find_script (face: info->hb_face, table_tag: tt,
140 script_tag,
141 script_index);
142}
143
144/**
145 * pango_ot_info_find_language:
146 * @info: a `PangoOTInfo`
147 * @table_type: the table type to obtain information about
148 * @script_index: the index of the script whose languages are searched
149 * @language_tag: the tag of the language to find
150 * @language_index: (out) (optional): location to store the index of the language
151 * @required_feature_index: (out) (optional): location to store the
152 * required feature index of the language
153 *
154 * Finds the index of a language and its required feature index.
155 *
156 * If the language is not found, sets @language_index to %PANGO_OT_DEFAULT_LANGUAGE
157 * and the required feature of the default language system is returned in
158 * required_feature_index. For best compatibility with some fonts, also
159 * searches the language system tag 'dflt' before falling back to the default
160 * language system, but that is transparent to the user. The user can simply
161 * ignore the return value of this function to automatically fall back to the
162 * default language system.
163 *
164 * Return value: %TRUE if the language was found
165 */
166gboolean
167pango_ot_info_find_language (PangoOTInfo *info,
168 PangoOTTableType table_type,
169 guint script_index,
170 PangoOTTag language_tag,
171 guint *language_index,
172 guint *required_feature_index)
173{
174 gboolean ret;
175 guint l_index;
176 hb_tag_t tt = get_hb_table_type (table_type);
177
178 ret = hb_ot_layout_script_select_language (face: info->hb_face,
179 table_tag: table_type,
180 script_index,
181 language_count: 1,
182 language_tags: &language_tag,
183 language_index: &l_index);
184 if (language_index)
185 *language_index = l_index;
186
187 hb_ot_layout_language_get_required_feature_index (face: info->hb_face, table_tag: tt,
188 script_index,
189 language_index: l_index,
190 feature_index: required_feature_index);
191
192 return ret;
193}
194
195/**
196 * pango_ot_info_find_feature:
197 * @info: a `PangoOTInfo`
198 * @table_type: the table type to obtain information about
199 * @feature_tag: the tag of the feature to find
200 * @script_index: the index of the script
201 * @language_index: the index of the language whose features are searched,
202 * or %PANGO_OT_DEFAULT_LANGUAGE to use the default language of the script
203 * @feature_index: (out) (optional): location to store the index of
204 * the feature
205 *
206 * Finds the index of a feature.
207 *
208 * If the feature is not found, sets @feature_index to PANGO_OT_NO_FEATURE,
209 * which is safe to pass to [method@PangoOT.Ruleset.add_feature] and similar
210 * functions.
211 *
212 * In the future, this may set @feature_index to an special value that if
213 * used in [method@PangoOT.Ruleset.add_feature] will ask Pango to synthesize
214 * the requested feature based on Unicode properties and data. However, this
215 * function will still return %FALSE in those cases. So, users may want to
216 * ignore the return value of this function in certain cases.
217 *
218 * Return value: %TRUE if the feature was found
219 */
220gboolean
221pango_ot_info_find_feature (PangoOTInfo *info,
222 PangoOTTableType table_type,
223 PangoOTTag feature_tag,
224 guint script_index,
225 guint language_index,
226 guint *feature_index)
227{
228 hb_tag_t tt = get_hb_table_type (table_type);
229
230 return hb_ot_layout_language_find_feature (face: info->hb_face, table_tag: tt,
231 script_index,
232 language_index,
233 feature_tag,
234 feature_index);
235}
236
237/**
238 * pango_ot_info_list_scripts:
239 * @info: a `PangoOTInfo`
240 * @table_type: the table type to obtain information about
241 *
242 * Obtains the list of available scripts.
243 *
244 * Return value: a newly-allocated zero-terminated
245 * array containing the tags of the available scripts
246 */
247PangoOTTag *
248pango_ot_info_list_scripts (PangoOTInfo *info,
249 PangoOTTableType table_type)
250{
251 hb_tag_t tt = get_hb_table_type (table_type);
252 PangoOTTag *result;
253 unsigned int count;
254
255 count = hb_ot_layout_table_get_script_tags (face: info->hb_face, table_tag: tt, start_offset: 0, NULL, NULL);
256 result = g_new (PangoOTTag, count + 1);
257 hb_ot_layout_table_get_script_tags (face: info->hb_face, table_tag: tt, start_offset: 0, script_count: &count, script_tags: result);
258 result[count] = 0;
259
260 return result;
261}
262
263/**
264 * pango_ot_info_list_languages:
265 * @info: a `PangoOTInfo`
266 * @table_type: the table type to obtain information about
267 * @script_index: the index of the script to list languages for
268 * @language_tag: unused parameter
269 *
270 * Obtains the list of available languages for a given script.
271 *
272 * Return value: a newly-allocated zero-terminated
273 * array containing the tags of the available languages
274 */
275PangoOTTag *
276pango_ot_info_list_languages (PangoOTInfo *info,
277 PangoOTTableType table_type,
278 guint script_index,
279 PangoOTTag language_tag G_GNUC_UNUSED)
280{
281 hb_tag_t tt = get_hb_table_type (table_type);
282 PangoOTTag *result;
283 unsigned int count;
284
285 count = hb_ot_layout_script_get_language_tags (face: info->hb_face, table_tag: tt, script_index, start_offset: 0, NULL, NULL);
286 result = g_new (PangoOTTag, count + 1);
287 hb_ot_layout_script_get_language_tags (face: info->hb_face, table_tag: tt, script_index, start_offset: 0, language_count: &count, language_tags: result);
288 result[count] = 0;
289
290 return result;
291}
292
293/**
294 * pango_ot_info_list_features:
295 * @info: a `PangoOTInfo`
296 * @table_type: the table type to obtain information about
297 * @tag: unused parameter
298 * @script_index: the index of the script to obtain information about
299 * @language_index: the index of the language to list features for, or
300 * %PANGO_OT_DEFAULT_LANGUAGE, to list features for the default
301 * language of the script
302 *
303 * Obtains the list of features for the given language of the given script.
304 *
305 * Return value: a newly-allocated zero-terminated
306 * array containing the tags of the available features
307 */
308PangoOTTag *
309pango_ot_info_list_features (PangoOTInfo *info,
310 PangoOTTableType table_type,
311 PangoOTTag tag G_GNUC_UNUSED,
312 guint script_index,
313 guint language_index)
314{
315 hb_tag_t tt = get_hb_table_type (table_type);
316 PangoOTTag *result;
317 unsigned int count;
318
319 count = hb_ot_layout_language_get_feature_tags (face: info->hb_face, table_tag: tt, script_index, language_index, start_offset: 0, NULL, NULL);
320 result = g_new (PangoOTTag, count + 1);
321 hb_ot_layout_language_get_feature_tags (face: info->hb_face, table_tag: tt, script_index, language_index, start_offset: 0, feature_count: &count, feature_tags: result);
322 result[count] = 0;
323
324 return result;
325}
326

source code of gtk/subprojects/pango/pango/pango-ot-info.c