mirror of
https://github.com/harfbuzz/harfbuzz.git
synced 2025-04-10 07:18:39 +00:00
[face] Two new APIs:
+ hb_face_create_from_file_or_fail_using() + hb_face_list_loaders()
This commit is contained in:
parent
50ea460b93
commit
39ade99d47
5 changed files with 158 additions and 72 deletions
105
src/hb-face.cc
105
src/hb-face.cc
|
@ -34,6 +34,13 @@
|
|||
#include "hb-ot-face.hh"
|
||||
#include "hb-ot-cmap-table.hh"
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
#include "hb-ft.h"
|
||||
#endif
|
||||
#ifdef HAVE_CORETEXT
|
||||
#include "hb-coretext.h"
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* SECTION:hb-face
|
||||
|
@ -320,6 +327,104 @@ hb_face_create_from_file_or_fail (const char *file_name,
|
|||
}
|
||||
#endif
|
||||
|
||||
static struct supported_face_loaders_t {
|
||||
char name[9];
|
||||
hb_face_t * (*func) (const char *font_file, unsigned face_index);
|
||||
} supported_face_loaders[] =
|
||||
{
|
||||
#ifndef HB_NO_OPEN
|
||||
{"ot", hb_face_create_from_file_or_fail},
|
||||
#endif
|
||||
#ifdef HAVE_FREETYPE
|
||||
{"ft", hb_ft_face_create_from_file_or_fail},
|
||||
#endif
|
||||
#ifdef HAVE_CORETEXT
|
||||
{"coretext", hb_coretext_face_create_from_file_or_fail},
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* hb_face_create_from_file_or_fail_using:
|
||||
* @file_name: A font filename
|
||||
* @index: The index of the face within the file
|
||||
* @loader_name: (nullable): The name of the loader to use, or `NULL`
|
||||
*
|
||||
* A thin wrapper around the face loader functions registered with HarfBuzz.
|
||||
* If @loader_name is `NULL`, the first available loader is used.
|
||||
*
|
||||
* Return value: (transfer full): The new face object, or `NULL` if
|
||||
* the file cannot be read or the loader fails to load the face.
|
||||
*
|
||||
* XSince: REPLACEME
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_face_create_from_file_or_fail_using (const char *file_name,
|
||||
unsigned int index,
|
||||
const char *loader_name)
|
||||
{
|
||||
if (loader_name && !*loader_name)
|
||||
loader_name = nullptr;
|
||||
for (unsigned i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++)
|
||||
{
|
||||
if (!loader_name || !strcmp (supported_face_loaders[i].name, loader_name))
|
||||
return supported_face_loaders[i].func (file_name, index);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static inline void free_static_face_loader_list ();
|
||||
|
||||
static const char * const nil_face_loader_list[] = {nullptr};
|
||||
|
||||
static struct hb_face_loader_list_lazy_loader_t : hb_lazy_loader_t<const char *,
|
||||
hb_face_loader_list_lazy_loader_t>
|
||||
{
|
||||
static const char ** create ()
|
||||
{
|
||||
const char **face_loader_list = (const char **) hb_calloc (1 + ARRAY_LENGTH (supported_face_loaders), sizeof (const char *));
|
||||
if (unlikely (!face_loader_list))
|
||||
return nullptr;
|
||||
|
||||
unsigned i;
|
||||
for (i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++)
|
||||
face_loader_list[i] = supported_face_loaders[i].name;
|
||||
face_loader_list[i] = nullptr;
|
||||
|
||||
hb_atexit (free_static_face_loader_list);
|
||||
|
||||
return face_loader_list;
|
||||
}
|
||||
static void destroy (const char **l)
|
||||
{ hb_free (l); }
|
||||
static const char * const * get_null ()
|
||||
{ return nil_face_loader_list; }
|
||||
} static_face_loader_list;
|
||||
|
||||
static inline
|
||||
void free_static_face_loader_list ()
|
||||
{
|
||||
static_face_loader_list.free_instance ();
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_face_list_loaders:
|
||||
*
|
||||
* Retrieves the list of face loaders supported by HarfBuzz.
|
||||
*
|
||||
* Return value: (transfer none) (array zero-terminated=1): a
|
||||
* `NULL`-terminated array of supported face loaders
|
||||
* constant strings. The returned array is owned by HarfBuzz
|
||||
* and should not be modified or freed.
|
||||
*
|
||||
* XSince: REPLACEME
|
||||
**/
|
||||
const char **
|
||||
hb_face_list_loaders ()
|
||||
{
|
||||
return static_face_loader_list.get_unconst ();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hb_face_get_empty:
|
||||
*
|
||||
|
|
|
@ -67,6 +67,15 @@ HB_EXTERN hb_face_t *
|
|||
hb_face_create_from_file_or_fail (const char *file_name,
|
||||
unsigned int index);
|
||||
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_face_create_from_file_or_fail_using (const char *file_name,
|
||||
unsigned int index,
|
||||
const char *loader_name);
|
||||
|
||||
HB_EXTERN const char **
|
||||
hb_face_list_loaders (void);
|
||||
|
||||
|
||||
/**
|
||||
* hb_reference_table_func_t:
|
||||
* @face: an #hb_face_t to reference table for
|
||||
|
|
|
@ -2336,7 +2336,7 @@ static struct supported_font_funcs_t {
|
|||
/**
|
||||
* hb_font_set_funcs_using:
|
||||
* @font: #hb_font_t to work upon
|
||||
* @name: The name of the font-functions structure to use
|
||||
* @name: The name of the font-functions structure to use, or `NULL`
|
||||
*
|
||||
* Sets the font-functions structure to use for a font, based on the
|
||||
* specified name.
|
||||
|
@ -2405,7 +2405,7 @@ void free_static_font_funcs_list ()
|
|||
*
|
||||
* Return value: (transfer none) (array zero-terminated=1): a
|
||||
* `NULL`-terminated array of supported font functions
|
||||
* constant string. The returned array is owned by HarfBuzz
|
||||
* constant strings. The returned array is owned by HarfBuzz
|
||||
* and should not be modified or freed.
|
||||
*
|
||||
* XSince: REPLACEME
|
||||
|
|
|
@ -29,13 +29,6 @@
|
|||
|
||||
#include "options.hh"
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
#include <hb-ft.h>
|
||||
#endif
|
||||
#ifdef HAVE_CORETEXT
|
||||
#include <hb-coretext.h>
|
||||
#endif
|
||||
|
||||
struct face_options_t
|
||||
{
|
||||
~face_options_t ()
|
||||
|
@ -74,20 +67,6 @@ struct face_options_t
|
|||
|
||||
face_options_t::cache_t face_options_t::cache {};
|
||||
|
||||
static struct supported_face_loaders_t {
|
||||
char name[9];
|
||||
hb_face_t * (*func) (const char *font_file, unsigned face_index);
|
||||
} supported_face_loaders[] =
|
||||
{
|
||||
{"ot", hb_face_create_from_file_or_fail},
|
||||
#ifdef HAVE_FREETYPE
|
||||
{"ft", hb_ft_face_create_from_file_or_fail},
|
||||
#endif
|
||||
#ifdef HAVE_CORETEXT
|
||||
{"coretext", hb_coretext_face_create_from_file_or_fail},
|
||||
#endif
|
||||
};
|
||||
|
||||
void
|
||||
face_options_t::post_parse (GError **error)
|
||||
{
|
||||
|
@ -112,46 +91,12 @@ face_options_t::post_parse (GError **error)
|
|||
#endif
|
||||
}
|
||||
|
||||
hb_face_t * (*face_load) (const char *file_name, unsigned face_index) = nullptr;
|
||||
if (!face_loader)
|
||||
{
|
||||
face_load = supported_face_loaders[0].func;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++)
|
||||
if (0 == g_ascii_strcasecmp (face_loader, supported_face_loaders[i].name))
|
||||
{
|
||||
face_load = supported_face_loaders[i].func;
|
||||
break;
|
||||
}
|
||||
if (!face_load)
|
||||
{
|
||||
GString *s = g_string_new (nullptr);
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (supported_face_loaders); i++)
|
||||
{
|
||||
if (i)
|
||||
g_string_append_c (s, '/');
|
||||
g_string_append (s, supported_face_loaders[i].name);
|
||||
}
|
||||
g_string_append_c (s, '\n');
|
||||
char *p = g_string_free (s, FALSE);
|
||||
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
|
||||
"Unknown face loader `%s'; supported values are: %s; default is %s",
|
||||
face_loader,
|
||||
p,
|
||||
supported_face_loaders[0].name);
|
||||
free (p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cache.font_path ||
|
||||
0 != strcmp (cache.font_path, font_path) ||
|
||||
cache.face_index != face_index)
|
||||
{
|
||||
hb_face_destroy (cache.face);
|
||||
cache.face = face_load (font_path, face_index);
|
||||
cache.face = hb_face_create_from_file_or_fail_using (font_path, face_index, face_loader);
|
||||
cache.face_index = face_index;
|
||||
|
||||
free ((char *) cache.font_path);
|
||||
|
@ -168,21 +113,37 @@ face_options_t::post_parse (GError **error)
|
|||
face = cache.face;
|
||||
}
|
||||
|
||||
static G_GNUC_NORETURN gboolean
|
||||
list_face_loaders (const char *name G_GNUC_UNUSED,
|
||||
const char *arg G_GNUC_UNUSED,
|
||||
gpointer data G_GNUC_UNUSED,
|
||||
GError **error G_GNUC_UNUSED)
|
||||
{
|
||||
for (const char **funcs = hb_face_list_loaders (); *funcs; funcs++)
|
||||
g_printf ("%s\n", *funcs);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
face_options_t::add_options (option_parser_t *parser)
|
||||
{
|
||||
char *face_loaders_text = nullptr;
|
||||
{
|
||||
static_assert ((ARRAY_LENGTH_CONST (supported_face_loaders) > 0),
|
||||
"No supported face-loaders found.");
|
||||
const char **supported_face_loaders = hb_face_list_loaders ();
|
||||
GString *s = g_string_new (nullptr);
|
||||
g_string_printf (s, "Set face loader to use (default: %s)\n Supported face loaders are: %s",
|
||||
supported_face_loaders[0].name,
|
||||
supported_face_loaders[0].name);
|
||||
for (unsigned int i = 1; i < ARRAY_LENGTH (supported_face_loaders); i++)
|
||||
if (unlikely (!supported_face_loaders))
|
||||
g_string_printf (s, "Set face loader to use (default: none)\n No supported face loaders found");
|
||||
else
|
||||
{
|
||||
g_string_append_c (s, '/');
|
||||
g_string_append (s, supported_face_loaders[i].name);
|
||||
g_string_printf (s, "Set face loader to use (default: %s)\n Supported face loaders are: %s",
|
||||
supported_face_loaders[0],
|
||||
supported_face_loaders[0]);
|
||||
for (unsigned i = 1; supported_face_loaders[i]; i++)
|
||||
{
|
||||
g_string_append_c (s, '/');
|
||||
g_string_append (s, supported_face_loaders[i]);
|
||||
}
|
||||
}
|
||||
face_loaders_text = g_string_free (s, FALSE);
|
||||
parser->free_later (face_loaders_text);
|
||||
|
@ -193,6 +154,8 @@ face_options_t::add_options (option_parser_t *parser)
|
|||
{"font-file", 0, 0, G_OPTION_ARG_STRING, &this->font_file, "Set font file-name", "filename"},
|
||||
{"face-index", 'y', 0, G_OPTION_ARG_INT, &this->face_index, "Set face index (default: 0)", "index"},
|
||||
{"face-loader", 0, 0, G_OPTION_ARG_STRING, &this->face_loader, face_loaders_text, "loader"},
|
||||
{"list-face-loaders",0, G_OPTION_FLAG_NO_ARG,
|
||||
G_OPTION_ARG_CALLBACK, (gpointer) &list_face_loaders, "List available face loaders and quit", nullptr},
|
||||
{nullptr}
|
||||
};
|
||||
parser->add_group (entries,
|
||||
|
|
|
@ -29,6 +29,10 @@
|
|||
|
||||
#include "face-options.hh"
|
||||
|
||||
#ifdef HAVE_FREETYPE
|
||||
#include <hb-ft.h>
|
||||
#endif
|
||||
|
||||
#define FONT_SIZE_UPEM 0x7FFFFFFF
|
||||
#define FONT_SIZE_NONE 0
|
||||
|
||||
|
@ -290,13 +294,18 @@ font_options_t::add_options (option_parser_t *parser)
|
|||
{
|
||||
const char **supported_font_funcs = hb_font_list_funcs ();
|
||||
GString *s = g_string_new (nullptr);
|
||||
g_string_printf (s, "Set font functions implementation to use (default: %s)\n Supported font function implementations are: %s",
|
||||
supported_font_funcs[0],
|
||||
supported_font_funcs[0]);
|
||||
for (unsigned i = 1; supported_font_funcs[i]; i++)
|
||||
if (unlikely (!supported_font_funcs[0]))
|
||||
g_string_printf (s, "Set font functions implementation to use (default: none)\n No supported font function implementations found");
|
||||
else
|
||||
{
|
||||
g_string_append_c (s, '/');
|
||||
g_string_append (s, supported_font_funcs[i]);
|
||||
g_string_printf (s, "Set font functions implementation to use (default: %s)\n Supported font function implementations are: %s",
|
||||
supported_font_funcs[0],
|
||||
supported_font_funcs[0]);
|
||||
for (unsigned i = 1; supported_font_funcs[i]; i++)
|
||||
{
|
||||
g_string_append_c (s, '/');
|
||||
g_string_append (s, supported_font_funcs[i]);
|
||||
}
|
||||
}
|
||||
font_funcs_text = g_string_free (s, FALSE);
|
||||
parser->free_later (font_funcs_text);
|
||||
|
|
Loading…
Add table
Reference in a new issue