/* Pango
* pango-ot-info.c: Store tables for OpenType
*
* Copyright (C) 2000 Red Hat Software
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
/**
* SECTION:opentype
* @short_description:Obtaining information from OpenType tables
* @title:OpenType Font Handling
* @stability:Unstable
*
* Functions and macros in this section are used to implement the OpenType Layout
* features and algorithms. These are mostly useful when writing Fontconfig-based
* shaping engines
*/
#include "config.h"
#include "pango-ot-private.h"
static void pango_ot_info_finalize (GObject *object);
G_DEFINE_TYPE (PangoOTInfo, pango_ot_info, G_TYPE_OBJECT);
static void
pango_ot_info_init (PangoOTInfo *self)
{
}
static void
pango_ot_info_class_init (PangoOTInfoClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->finalize = pango_ot_info_finalize;
}
static void
pango_ot_info_finalize (GObject *object)
{
PangoOTInfo *info = PANGO_OT_INFO (object);
if (info->hb_face)
hb_face_destroy (info->hb_face);
G_OBJECT_CLASS (pango_ot_info_parent_class)->finalize (object);
}
static void
pango_ot_info_finalizer (void *object)
{
FT_Face face = object;
PangoOTInfo *info = face->generic.data;
info->face = NULL;
g_object_unref (info);
}
/**
* pango_ot_info_get:
* @face: a <type>FT_Face</type>.
*
* Returns the #PangoOTInfo structure for the given FreeType font face.
*
* Return value: the #PangoOTInfo for @face. This object will have
* the same lifetime as @face.
*
* Since: 1.2
**/
PangoOTInfo *
pango_ot_info_get (FT_Face face)
{
PangoOTInfo *info;
if (G_UNLIKELY (!face))
return NULL;
if (G_LIKELY (face->generic.data && face->generic.finalizer == pango_ot_info_finalizer))
return face->generic.data;
else
{
if (face->generic.finalizer)
face->generic.finalizer (face);
info = face->generic.data = g_object_new (PANGO_TYPE_OT_INFO, NULL);
face->generic.finalizer = pango_ot_info_finalizer;
info->face = face;
info->hb_face = hb_ft_face_create (face, NULL);
}
return info;
}
static hb_tag_t
get_hb_table_type (PangoOTTableType table_type)
{
switch (table_type) {
case PANGO_OT_TABLE_GSUB: return HB_OT_TAG_GSUB;
case PANGO_OT_TABLE_GPOS: return HB_OT_TAG_GPOS;
default: return HB_TAG_NONE;
}
}
/**
* pango_ot_info_find_script:
* @info: a #PangoOTInfo.
* @table_type: the table type to obtain information about.
* @script_tag: the tag of the script to find.
* @script_index: (out) (optional): location to store the index of the
* script, or %NULL.
*
* Finds the index of a script. If not found, tries to find the 'DFLT'
* and then 'dflt' scripts and return the index of that in @script_index.
* If none of those is found either, %PANGO_OT_NO_SCRIPT is placed in
* @script_index.
*
* All other functions taking an input script_index parameter know
* how to handle %PANGO_OT_NO_SCRIPT, so one can ignore the return
* value of this function completely and proceed, to enjoy the automatic
* fallback to the 'DFLT'/'dflt' script.
*
* Return value: %TRUE if the script was found.
**/
gboolean
pango_ot_info_find_script (PangoOTInfo *info,
PangoOTTableType table_type,
PangoOTTag script_tag,
guint *script_index)
{
hb_tag_t tt = get_hb_table_type (table_type);
return hb_ot_layout_table_find_script (info->hb_face, tt,
script_tag,
script_index);
}
/**
* pango_ot_info_find_language:
* @info: a #PangoOTInfo.
* @table_type: the table type to obtain information about.
* @script_index: the index of the script whose languages are searched.
* @language_tag: the tag of the language to find.
* @language_index: (out) (optional): location to store the index of
* the language, or %NULL.
* @required_feature_index: (out) (optional): location to store the
* required feature index of the language, or %NULL.
*
* Finds the index of a language and its required feature index.
* If the language is not found, sets @language_index to
* PANGO_OT_DEFAULT_LANGUAGE and the required feature of the default language
* system is returned in required_feature_index. For best compatibility with
* some fonts, also searches the language system tag 'dflt' before falling
* back to the default language system, but that is transparent to the user.
* The user can simply ignore the return value of this function to
* automatically fall back to the default language system.
*
* Return value: %TRUE if the language was found.
**/
gboolean
pango_ot_info_find_language (PangoOTInfo *info,
PangoOTTableType table_type,
guint script_index,
PangoOTTag language_tag,
guint *language_index,
guint *required_feature_index)
{
gboolean ret;
unsigned l_index;
hb_tag_t tt = get_hb_table_type (table_type);
ret = hb_ot_layout_script_find_language (info->hb_face, tt,
script_index,
language_tag,
&l_index);
if (language_index) *language_index = l_index;
hb_ot_layout_language_get_required_feature_index (info->hb_face, tt,
script_index,
l_index,
required_feature_index);
return ret;
}
/**
* pango_ot_info_find_feature:
* @info: a #PangoOTInfo.
* @table_type: the table type to obtain information about.
* @feature_tag: the tag of the feature to find.
* @script_index: the index of the script.
* @language_index: the index of the language whose features are searched,
* or %PANGO_OT_DEFAULT_LANGUAGE to use the default language of the script.
* @feature_index: (out) (optional): location to store the index of
* the feature, or %NULL.
*
* Finds the index of a feature. If the feature is not found, sets
* @feature_index to PANGO_OT_NO_FEATURE, which is safe to pass to
* pango_ot_ruleset_add_feature() and similar functions.
*
* In the future, this may set @feature_index to an special value that if used
* in pango_ot_ruleset_add_feature() will ask Pango to synthesize the
* requested feature based on Unicode properties and data. However, this
* function will still return %FALSE in those cases. So, users may want to
* ignore the return value of this function in certain cases.
*
* Return value: %TRUE if the feature was found.
**/
gboolean
pango_ot_info_find_feature (PangoOTInfo *info,
PangoOTTableType table_type,
PangoOTTag feature_tag,
guint script_index,
guint language_index,
guint *feature_index)
{
hb_tag_t tt = get_hb_table_type (table_type);
return hb_ot_layout_language_find_feature (info->hb_face, tt,
script_index,
language_index,
feature_tag,
feature_index);
}
/**
* pango_ot_info_list_scripts:
* @info: a #PangoOTInfo.
* @table_type: the table type to obtain information about.
*
* Obtains the list of available scripts.
*
* Return value: a newly-allocated zero-terminated array containing the tags of the
* available scripts. Should be freed using g_free().
**/
PangoOTTag *
pango_ot_info_list_scripts (PangoOTInfo *info,
PangoOTTableType table_type)
{
hb_tag_t tt = get_hb_table_type (table_type);
PangoOTTag *result;
unsigned int count;
count = hb_ot_layout_table_get_script_tags (info->hb_face, tt, 0, NULL, NULL);
result = g_new (PangoOTTag, count + 1);
hb_ot_layout_table_get_script_tags (info->hb_face, tt, 0, &count, result);
result[count] = 0;
return result;
}
/**
* pango_ot_info_list_languages:
* @info: a #PangoOTInfo.
* @table_type: the table type to obtain information about.
* @script_index: the index of the script to list languages for.
* @language_tag: unused parameter.
*
* Obtains the list of available languages for a given script.
*
* Return value: a newly-allocated zero-terminated array containing the tags of the
* available languages. Should be freed using g_free().
**/
PangoOTTag *
pango_ot_info_list_languages (PangoOTInfo *info,
PangoOTTableType table_type,
guint script_index,
PangoOTTag language_tag G_GNUC_UNUSED)
{
hb_tag_t tt = get_hb_table_type (table_type);
PangoOTTag *result;
unsigned int count;
count = hb_ot_layout_script_get_language_tags (info->hb_face, tt, script_index, 0, NULL, NULL);
result = g_new (PangoOTTag, count + 1);
hb_ot_layout_script_get_language_tags (info->hb_face, tt, script_index, 0, &count, result);
result[count] = 0;
return result;
}
/**
* pango_ot_info_list_features:
* @info: a #PangoOTInfo.
* @table_type: the table type to obtain information about.
* @tag: unused parameter.
* @script_index: the index of the script to obtain information about.
* @language_index: the index of the language to list features for, or
* %PANGO_OT_DEFAULT_LANGUAGE, to list features for the default
* language of the script.
*
* Obtains the list of features for the given language of the given script.
*
* Return value: a newly-allocated zero-terminated array containing the tags of the
* available features. Should be freed using g_free().
**/
PangoOTTag *
pango_ot_info_list_features (PangoOTInfo *info,
PangoOTTableType table_type,
PangoOTTag tag G_GNUC_UNUSED,
guint script_index,
guint language_index)
{
hb_tag_t tt = get_hb_table_type (table_type);
PangoOTTag *result;
unsigned int count;
count = hb_ot_layout_language_get_feature_tags (info->hb_face, tt, script_index, language_index, 0, NULL, NULL);
result = g_new (PangoOTTag, count + 1);
hb_ot_layout_language_get_feature_tags (info->hb_face, tt, script_index, language_index, 0, &count, result);
result[count] = 0;
return result;
}