[util] separate face options from font options

This commit is contained in:
Behdad Esfahbod 2021-08-06 18:09:31 -06:00
parent b3a2f2bfcf
commit 869e20e09f
3 changed files with 93 additions and 60 deletions

View File

@ -93,7 +93,7 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts)
} }
unsigned int blob_length; unsigned int blob_length;
const char *blob_data = hb_blob_get_data (font_opts->blob, &blob_length); const char *blob_data = hb_blob_get_data (font_opts->get_blob (), &blob_length);
if (FT_New_Memory_Face (ft_library, if (FT_New_Memory_Face (ft_library,
(const FT_Byte *) blob_data, (const FT_Byte *) blob_data,

View File

@ -525,9 +525,27 @@ parse_font_ppem (const char *name G_GNUC_UNUSED,
} }
} }
void
face_options_t::add_options (option_parser_t *parser)
{
GOptionEntry entries[] =
{
{"font-file", 0, 0, G_OPTION_ARG_STRING, &this->font_file, "Set font file-name", "filename"},
{"face-index", 0, 0, G_OPTION_ARG_INT, &this->face_index, "Set face index (default: 0)", "index"},
{nullptr}
};
parser->add_group (entries,
"face",
"Font-face options:",
"Options for the font face",
this);
}
void void
font_options_t::add_options (option_parser_t *parser) font_options_t::add_options (option_parser_t *parser)
{ {
face_options_t::add_options (parser);
char *text = nullptr; char *text = nullptr;
{ {
@ -557,8 +575,6 @@ font_options_t::add_options (option_parser_t *parser)
GOptionEntry entries[] = GOptionEntry entries[] =
{ {
{"font-file", 0, 0, G_OPTION_ARG_STRING, &this->font_file, "Set font file-name", "filename"},
{"face-index", 0, 0, G_OPTION_ARG_INT, &this->face_index, "Set face index (default: 0)", "index"},
{"font-size", 0, DEFAULT_FONT_SIZE ? 0 : G_OPTION_FLAG_HIDDEN, {"font-size", 0, DEFAULT_FONT_SIZE ? 0 : G_OPTION_FLAG_HIDDEN,
G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_size, font_size_text, "1/2 integers or 'upem'"}, G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_size, font_size_text, "1/2 integers or 'upem'"},
{"font-ppem", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_ppem, "Set x,y pixels per EM (default: 0; disabled)", "1/2 integers"}, {"font-ppem", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_ppem, "Set x,y pixels per EM (default: 0; disabled)", "1/2 integers"},
@ -569,8 +585,8 @@ font_options_t::add_options (option_parser_t *parser)
}; };
parser->add_group (entries, parser->add_group (entries,
"font", "font",
"Font options:", "Font-instance options:",
"Options for the font", "Options for the font instance",
this); this);
const gchar *variations_help = "Comma-separated list of font variations\n" const gchar *variations_help = "Comma-separated list of font variations\n"
@ -646,15 +662,21 @@ output_options_t::add_options (option_parser_t *parser,
} }
font_options_t::cache_t font_options_t::cache {}; face_options_t::cache_t face_options_t::cache {};
hb_font_t * hb_blob_t *
font_options_t::get_font () const face_options_t::get_blob () const
{ {
if (font) // XXX This does the job for now; will move to post_parse.
return font; return cache.blob;
}
hb_face_t *
face_options_t::get_face () const
{
if (face)
return face;
/* Create the blob */
if (!font_file) if (!font_file)
fail (true, "No font file set"); fail (true, "No font file set");
@ -670,40 +692,42 @@ font_options_t::get_font () const
#endif #endif
} }
if (cache.font_path && 0 == strcmp (cache.font_path, font_path)) if (!cache.font_path || 0 != strcmp (cache.font_path, font_path))
blob = hb_blob_reference (cache.blob);
else
{ {
blob = hb_blob_create_from_file_or_fail (font_path); hb_blob_destroy (cache.blob);
cache.blob = hb_blob_create_from_file_or_fail (font_path);
if (!blob) free ((char *) cache.font_path);
cache.font_path = strdup (font_path);
if (!cache.blob)
fail (false, "%s: Failed reading file", font_path); fail (false, "%s: Failed reading file", font_path);
/* Update caches. */
hb_face_destroy (cache.face); hb_face_destroy (cache.face);
cache.face = nullptr; cache.face = nullptr;
cache.face_index = (unsigned) -1; cache.face_index = (unsigned) -1;
free ((char *) cache.font_path);
cache.font_path = strdup (font_path);
hb_blob_destroy (cache.blob);
cache.blob = hb_blob_reference (blob);
} }
hb_face_t *face = nullptr; if (cache.face_index != face_index)
if (cache.face_index == face_index)
face = hb_face_reference (cache.face);
else
{ {
face = hb_face_create (blob, face_index);
hb_blob_destroy (blob);
cache.face_index = face_index;
hb_face_destroy (cache.face); hb_face_destroy (cache.face);
cache.face = hb_face_reference (face); cache.face = hb_face_create (cache.blob, face_index);
cache.face_index = face_index;
} }
face = cache.face;
return face;
}
hb_font_t *
font_options_t::get_font () const
{
if (font)
return font;
auto *face = get_face ();
font = hb_font_create (face); font = hb_font_create (face);
@ -718,7 +742,6 @@ font_options_t::get_font () const
int scale_x = (int) scalbnf (font_size_x, subpixel_bits); int scale_x = (int) scalbnf (font_size_x, subpixel_bits);
int scale_y = (int) scalbnf (font_size_y, subpixel_bits); int scale_y = (int) scalbnf (font_size_y, subpixel_bits);
hb_font_set_scale (font, scale_x, scale_y); hb_font_set_scale (font, scale_x, scale_y);
hb_face_destroy (face);
hb_font_set_variations (font, variations, num_variations); hb_font_set_variations (font, variations, num_variations);

View File

@ -441,36 +441,12 @@ struct shape_options_t
}; };
struct font_options_t struct face_options_t
{ {
~font_options_t ()
{
g_free (font_file);
free (variations);
g_free (font_funcs);
hb_font_destroy (font);
}
void add_options (option_parser_t *parser); void add_options (option_parser_t *parser);
hb_font_t *get_font () const; hb_blob_t *get_blob () const;
hb_face_t *get_face () const;
char *font_file = nullptr;
mutable hb_blob_t *blob = nullptr;
unsigned face_index = 0;
hb_variation_t *variations = nullptr;
unsigned int num_variations = 0;
int x_ppem = 0;
int y_ppem = 0;
double ptem = 0.;
unsigned int subpixel_bits = SUBPIXEL_BITS;
mutable double font_size_x = DEFAULT_FONT_SIZE;
mutable double font_size_y = DEFAULT_FONT_SIZE;
char *font_funcs = nullptr;
int ft_load_flags = 2;
private:
mutable hb_font_t *font = nullptr;
static struct cache_t static struct cache_t
{ {
@ -486,6 +462,40 @@ struct font_options_t
unsigned face_index = (unsigned) -1; unsigned face_index = (unsigned) -1;
hb_face_t *face = nullptr; hb_face_t *face = nullptr;
} cache; } cache;
char *font_file = nullptr;
unsigned face_index = 0;
private:
mutable hb_face_t *face = nullptr;
};
struct font_options_t : face_options_t
{
~font_options_t ()
{
g_free (font_file);
free (variations);
g_free (font_funcs);
hb_font_destroy (font);
}
void add_options (option_parser_t *parser);
hb_font_t *get_font () const;
hb_variation_t *variations = nullptr;
unsigned int num_variations = 0;
int x_ppem = 0;
int y_ppem = 0;
double ptem = 0.;
unsigned int subpixel_bits = SUBPIXEL_BITS;
mutable double font_size_x = DEFAULT_FONT_SIZE;
mutable double font_size_y = DEFAULT_FONT_SIZE;
char *font_funcs = nullptr;
int ft_load_flags = 2;
private:
mutable hb_font_t *font = nullptr;
}; };