Skip to content

Commit

Permalink
ass_shaper: create hb_font_t eagerly during add_face
Browse files Browse the repository at this point in the history
  • Loading branch information
rcombs committed Apr 30, 2024
1 parent 728e54e commit 1dfb934
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 66 deletions.
18 changes: 13 additions & 5 deletions libass/ass_font.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,7 @@ static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch)
int i, index, uid;
ASS_FontStream stream = { NULL, NULL };
FT_Face face;
int ret = -1;

if (font->n_faces == ASS_FONT_MAX_FACES)
return -1;
Expand Down Expand Up @@ -457,8 +458,16 @@ static int add_face(ASS_FontSelector *fontsel, ASS_Font *font, uint32_t ch)
set_font_metrics(face);

font->faces[font->n_faces] = face;
font->faces_uid[font->n_faces++] = uid;
return font->n_faces - 1;
font->faces_uid[font->n_faces] = uid;
if (!ass_create_hb_font(font, font->n_faces)) {
FT_Done_Face(face);
goto fail;
}

ret = font->n_faces++;

fail:
return ret;
}

/**
Expand All @@ -483,7 +492,6 @@ size_t ass_font_construct(void *key, void *value, void *priv)

font->library = render_priv->library;
font->ftlibrary = render_priv->ftlibrary;
font->shaper_priv = NULL;
font->n_faces = 0;
font->desc.family = desc->family;
font->desc.bold = desc->bold;
Expand Down Expand Up @@ -698,11 +706,11 @@ bool ass_font_get_glyph(ASS_Font *font, int face_index, int index,
void ass_font_clear(ASS_Font *font)
{
int i;
if (font->shaper_priv)
ass_shaper_font_data_free(font->shaper_priv);
for (i = 0; i < font->n_faces; ++i) {
if (font->faces[i])
FT_Done_Face(font->faces[i]);
if (font->hb_fonts[i])
hb_font_destroy(font->hb_fonts[i]);
}
free((char *) font->desc.family.str);
}
Expand Down
2 changes: 1 addition & 1 deletion libass/ass_font.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ struct ass_font {
FT_Library ftlibrary;
int faces_uid[ASS_FONT_MAX_FACES];
FT_Face faces[ASS_FONT_MAX_FACES];
ASS_ShaperFontData *shaper_priv;
struct hb_font_t *hb_fonts[ASS_FONT_MAX_FACES];
int n_faces;
};

Expand Down
1 change: 0 additions & 1 deletion libass/ass_fontselect.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
#include <ft2build.h>
#include FT_FREETYPE_H

typedef struct ass_shaper_font_data ASS_ShaperFontData;
typedef struct font_selector ASS_FontSelector;
typedef struct font_info ASS_FontInfo;
typedef struct ass_font_stream ASS_FontStream;
Expand Down
89 changes: 32 additions & 57 deletions libass/ass_shaper.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,6 @@ struct ass_shaper_metrics_data {
int vertical;
};

struct ass_shaper_font_data {
hb_font_t *fonts[ASS_FONT_MAX_FACES];
struct ass_shaper_metrics_data *metrics_data[ASS_FONT_MAX_FACES];
};

/**
* \brief Print version information
*/
Expand Down Expand Up @@ -149,17 +144,6 @@ void ass_shaper_free(ASS_Shaper *shaper)
free(shaper);
}

void ass_shaper_font_data_free(ASS_ShaperFontData *priv)
{
int i;
for (i = 0; i < ASS_FONT_MAX_FACES; i++)
if (priv->fonts[i]) {
free(priv->metrics_data[i]);
hb_font_destroy(priv->fonts[i]);
}
free(priv);
}

/**
* \brief set up the HarfBuzz OpenType feature list with some
* standard features.
Expand Down Expand Up @@ -442,6 +426,26 @@ get_contour_point(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
return true;
}

bool ass_create_hb_font(ASS_Font *font, int index)
{
FT_Face face = font->faces[index];
hb_face_t *hb_face = hb_face_create_for_tables(get_reference_table, face, NULL);
if (!hb_face)
return false;

hb_face_set_index(hb_face, face->face_index);
hb_face_set_upem(hb_face, face->units_per_EM);

hb_font_t *hb_font = hb_font_create(hb_face);
hb_face_destroy(hb_face);
if (!hb_font)
return false;

font->hb_fonts[index] = hb_font;

return true;
}

/**
* \brief Retrieve HarfBuzz font from cache.
* Create it from FreeType font, if needed.
Expand All @@ -451,54 +455,25 @@ get_contour_point(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
static hb_font_t *get_hb_font(ASS_Shaper *shaper, GlyphInfo *info)
{
ASS_Font *font = info->font;
hb_font_t **hb_fonts;

if (!font->shaper_priv)
font->shaper_priv = calloc(sizeof(ASS_ShaperFontData), 1);
if (!font->shaper_priv)
hb_font_t *hb_font = font->hb_fonts[info->face_index];
if (!hb_font)
return NULL;

hb_fonts = font->shaper_priv->fonts;
if (!hb_fonts[info->face_index]) {
FT_Face face = font->faces[info->face_index];
hb_face_t *hb_face = hb_face_create_for_tables(get_reference_table, face, NULL);
if (!hb_face)
return NULL;
hb_face_set_index(hb_face, face->face_index);
hb_face_set_upem(hb_face, face->units_per_EM);

hb_font_t *hb_font = hb_fonts[info->face_index] = hb_font_create(hb_face);
hb_face_destroy(hb_face);
if (!hb_font)
return NULL;

hb_font_set_scale(hb_font,
(int)(((uint64_t)face->size->metrics.x_scale * face->units_per_EM + (1<<15)) >> 16),
(int)(((uint64_t)face->size->metrics.y_scale * face->units_per_EM + (1<<15)) >> 16));

// set up cached metrics access
struct ass_shaper_metrics_data *metrics =
font->shaper_priv->metrics_data[info->face_index] =
calloc(sizeof(struct ass_shaper_metrics_data), 1);
if (!metrics)
return NULL;
metrics->metrics_cache = shaper->metrics_cache;
metrics->vertical = info->font->desc.vertical;

hb_font_set_funcs(hb_font, shaper->font_funcs, metrics, NULL);
}

// set up cached metrics access
struct ass_shaper_metrics_data *metrics = calloc(sizeof(struct ass_shaper_metrics_data), 1);
if (!metrics)
return NULL;
ass_face_set_size(font->faces[info->face_index], info->font_size);
update_hb_size(hb_fonts[info->face_index], font->faces[info->face_index]);

// update hash key for cached metrics
struct ass_shaper_metrics_data *metrics =
font->shaper_priv->metrics_data[info->face_index];
update_hb_size(hb_font, font->faces[info->face_index]);
metrics->metrics_cache = shaper->metrics_cache;
metrics->hash_key.font = info->font;
metrics->hash_key.face_index = info->face_index;
metrics->hash_key.size = info->font_size;
metrics->vertical = info->font->desc.vertical;

hb_font_set_funcs(hb_font, shaper->font_funcs, metrics, free);

return hb_fonts[info->face_index];
return hb_font;
}

/**
Expand Down
3 changes: 1 addition & 2 deletions libass/ass_shaper.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ typedef struct ass_shaper ASS_Shaper;
void ass_shaper_info(ASS_Library *lib);
ASS_Shaper *ass_shaper_new(Cache *metrics_cache);
void ass_shaper_free(ASS_Shaper *shaper);
bool ass_create_hb_font(ASS_Font *font, int index);
void ass_shaper_set_kerning(ASS_Shaper *shaper, bool kern);
void ass_shaper_find_runs(ASS_Shaper *shaper, ASS_Renderer *render_priv,
GlyphInfo *glyphs, size_t len);
Expand All @@ -49,6 +50,4 @@ FriBidiStrIndex *ass_shaper_reorder(ASS_Shaper *shaper, TextInfo *text_info);
FriBidiStrIndex *ass_shaper_get_reorder_map(ASS_Shaper *shaper);
FriBidiParType ass_resolve_base_direction(int font_encoding);

void ass_shaper_font_data_free(ASS_ShaperFontData *priv);

#endif

0 comments on commit 1dfb934

Please sign in to comment.