summaryrefslogtreecommitdiffstats
path: root/libass
diff options
context:
space:
mode:
Diffstat (limited to 'libass')
-rw-r--r--libass/ass/meson.build13
-rw-r--r--libass/ass_compat.h11
-rw-r--r--libass/ass_directwrite.h7
-rw-r--r--libass/ass_drawing.c3
-rw-r--r--libass/ass_filesystem.c1
-rw-r--r--libass/ass_font.c21
-rw-r--r--libass/ass_font.h3
-rw-r--r--libass/ass_fontselect.h1
-rw-r--r--libass/ass_parse.c2
-rw-r--r--libass/ass_render.c87
-rw-r--r--libass/ass_render.h3
-rw-r--r--libass/ass_shaper.c166
-rw-r--r--libass/ass_shaper.h3
-rw-r--r--libass/meson.build149
-rw-r--r--libass/x86/x86inc.asm309
15 files changed, 534 insertions, 245 deletions
diff --git a/libass/ass/meson.build b/libass/ass/meson.build
new file mode 100644
index 0000000..6b4de1f
--- /dev/null
+++ b/libass/ass/meson.build
@@ -0,0 +1,13 @@
+# See: https://github.com/mesonbuild/meson/issues/2546
+# This hack is needed because the install directory of the libass public headers
+# ('ass') is different than the name of the directory ('libass') that they live under
+# in the source tree. In the scenario where the libass meson build system is being used
+# as a subproject of some parent project, that parent project will need the libass
+# headers to be copied into the appropriate 'ass' directory either before or during the
+# build process so that they are in an appropriate include path prior to the time that
+# the build system starts trying to build the parent project that needs to include
+# them.
+fs = import('fs')
+foreach header : libass_headers
+ fake_installed_headers += fs.copyfile(header, fs.name(header))
+endforeach
diff --git a/libass/ass_compat.h b/libass/ass_compat.h
index 38df913..52ac282 100644
--- a/libass/ass_compat.h
+++ b/libass/ass_compat.h
@@ -43,4 +43,15 @@ char *ass_strndup_fallback(const char *s, size_t n); // definition in ass_utils.
#define strndup ass_strndup_fallback
#endif
+#ifdef _WIN32
+
+#ifdef WINAPI_FAMILY
+#include <winapifamily.h>
+#define ASS_WINAPI_DESKTOP WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
+#else
+#define ASS_WINAPI_DESKTOP 1
+#endif
+
+#endif // _WIN32
+
#endif /* LIBASS_COMPAT_H */
diff --git a/libass/ass_directwrite.h b/libass/ass_directwrite.h
index a14b951..bb1159c 100644
--- a/libass/ass_directwrite.h
+++ b/libass/ass_directwrite.h
@@ -22,13 +22,6 @@
#ifndef ASS_DIRECTWRITE_H
#define ASS_DIRECTWRITE_H
-#ifdef WINAPI_FAMILY
-#include <winapifamily.h>
-#define ASS_WINAPI_DESKTOP WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
-#else
-#define ASS_WINAPI_DESKTOP 1
-#endif
-
ASS_FontProvider *
ass_directwrite_add_provider(ASS_Library *lib, ASS_FontSelector *selector,
const char *config, FT_Library ftlib);
diff --git a/libass/ass_drawing.c b/libass/ass_drawing.c
index a4ed04c..770f555 100644
--- a/libass/ass_drawing.c
+++ b/libass/ass_drawing.c
@@ -124,8 +124,7 @@ static size_t add_many_points(const char **str, ASS_DrawingToken **tail,
ASS_TokenType type, size_t batch_size, bool *error)
{
ASS_Vector buf[3];
- size_t max_buf = sizeof(buf) / sizeof(*buf);
- assert(batch_size <= max_buf);
+ assert(batch_size <= (sizeof(buf) / sizeof(*buf)));
if (!*str)
return 0;
diff --git a/libass/ass_filesystem.c b/libass/ass_filesystem.c
index 79a0d80..eb330c2 100644
--- a/libass/ass_filesystem.c
+++ b/libass/ass_filesystem.c
@@ -118,7 +118,6 @@ void ass_close_dir(ASS_Dir *dir)
#else // Windows
#include <windows.h>
-#include "ass_directwrite.h" // for ASS_WINAPI_DESKTOP
static const uint8_t wtf8_len_table[256] = {
diff --git a/libass/ass_font.c b/libass/ass_font.c
index d17258a..72ec888 100644
--- a/libass/ass_font.c
+++ b/libass/ass_font.c
@@ -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;
@@ -457,9 +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;
- ass_face_set_size(face, font->size);
- 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;
}
/**
@@ -484,15 +492,12 @@ 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;
font->desc.italic = desc->italic;
font->desc.vertical = desc->vertical;
- font->size = 0.;
-
int error = add_face(render_priv->fontselect, font, 0);
if (error == -1)
font->library = NULL;
@@ -701,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);
}
diff --git a/libass/ass_font.h b/libass/ass_font.h
index ea1130f..df9fb30 100644
--- a/libass/ass_font.h
+++ b/libass/ass_font.h
@@ -44,9 +44,8 @@ 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;
- double size;
};
void ass_charmap_magic(ASS_Library *library, FT_Face face);
diff --git a/libass/ass_fontselect.h b/libass/ass_fontselect.h
index 43366bb..23bcad4 100644
--- a/libass/ass_fontselect.h
+++ b/libass/ass_fontselect.h
@@ -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;
diff --git a/libass/ass_parse.c b/libass/ass_parse.c
index fae575a..d1b6051 100644
--- a/libass/ass_parse.c
+++ b/libass/ass_parse.c
@@ -1022,7 +1022,7 @@ void ass_apply_transition_effects(RenderContext *state)
*/
void ass_process_karaoke_effects(RenderContext *state)
{
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
long long tm_current = state->renderer->time - state->event->Start;
int32_t timing = 0, skip_timing = 0;
diff --git a/libass/ass_render.c b/libass/ass_render.c
index f95479c..afcbf42 100644
--- a/libass/ass_render.c
+++ b/libass/ass_render.c
@@ -76,6 +76,29 @@ static void text_info_done(TextInfo* text_info)
free(text_info->combined_bitmaps);
}
+static bool render_context_init(RenderContext *state, ASS_Renderer *priv)
+{
+ state->renderer = priv;
+
+ if (!text_info_init(&state->text_info))
+ return false;
+
+ if (!(state->shaper = ass_shaper_new(priv->cache.metrics_cache)))
+ return false;
+
+ return ass_rasterizer_init(&priv->engine, &state->rasterizer, RASTERIZER_PRECISION);
+}
+
+static void render_context_done(RenderContext *state)
+{
+ ass_rasterizer_done(&state->rasterizer);
+
+ if (state->shaper)
+ ass_shaper_free(state->shaper);
+
+ text_info_done(&state->text_info);
+}
+
ASS_Renderer *ass_renderer_init(ASS_Library *library)
{
int error;
@@ -112,9 +135,6 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
#endif
priv->engine = ass_bitmap_engine_init(flags);
- if (!ass_rasterizer_init(&priv->engine, &priv->state.rasterizer, RASTERIZER_PRECISION))
- goto fail;
-
priv->cache.font_cache = ass_font_cache_create();
priv->cache.bitmap_cache = ass_bitmap_cache_create();
priv->cache.composite_cache = ass_composite_cache_create();
@@ -127,20 +147,14 @@ ASS_Renderer *ass_renderer_init(ASS_Library *library)
priv->cache.bitmap_max_size = BITMAP_CACHE_MAX_SIZE;
priv->cache.composite_max_size = COMPOSITE_CACHE_MAX_SIZE;
- if (!text_info_init(&priv->text_info))
+ if (!render_context_init(&priv->state, priv))
goto fail;
priv->user_override_style.Name = "OverrideStyle"; // name insignificant
- priv->state.renderer = priv;
- priv->state.text_info = &priv->text_info;
-
priv->settings.font_size_coeff = 1.;
priv->settings.selective_style_overrides = ASS_OVERRIDE_BIT_SELECTIVE_FONT_SCALE;
- if (!(priv->state.shaper = ass_shaper_new(priv->cache.metrics_cache)))
- goto fail;
-
ass_shaper_info(library);
priv->settings.shaper = ASS_SHAPING_COMPLEX;
@@ -167,18 +181,15 @@ void ass_renderer_done(ASS_Renderer *render_priv)
ass_cache_done(render_priv->cache.bitmap_cache);
ass_cache_done(render_priv->cache.outline_cache);
ass_cache_done(render_priv->cache.metrics_cache);
- ass_shaper_free(render_priv->state.shaper);
ass_cache_done(render_priv->cache.font_cache);
- ass_rasterizer_done(&render_priv->state.rasterizer);
-
if (render_priv->fontselect)
ass_fontselect_free(render_priv->fontselect);
if (render_priv->ftlibrary)
FT_Done_FreeType(render_priv->ftlibrary);
free(render_priv->eimg);
- text_info_done(&render_priv->text_info);
+ render_context_done(&render_priv->state);
free(render_priv->settings.default_font);
free(render_priv->settings.default_family);
@@ -809,8 +820,8 @@ static ASS_Image *render_text(RenderContext *state)
{
ASS_Image *head;
ASS_Image **tail = &head;
- unsigned n_bitmaps = state->text_info->n_bitmaps;
- CombinedBitmapInfo *bitmaps = state->text_info->combined_bitmaps;
+ unsigned n_bitmaps = state->text_info.n_bitmaps;
+ CombinedBitmapInfo *bitmaps = state->text_info.combined_bitmaps;
for (unsigned i = 0; i < n_bitmaps; i++) {
CombinedBitmapInfo *info = &bitmaps[i];
@@ -1149,9 +1160,7 @@ static void free_render_context(RenderContext *state)
state->family.len = 0;
state->clip_drawing_text.str = NULL;
state->clip_drawing_text.len = 0;
-
- if (state->text_info)
- state->text_info->length = 0;
+ state->text_info.length = 0;
}
/**
@@ -1580,7 +1589,7 @@ static void measure_text_on_eol(RenderContext *state, double scale, int cur_line
int max_asc, int max_desc,
double max_border_x, double max_border_y)
{
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
text_info->lines[cur_line].asc = scale * max_asc;
text_info->lines[cur_line].desc = scale * max_desc;
text_info->height += scale * max_asc + scale * max_desc;
@@ -1608,7 +1617,7 @@ static void measure_text_on_eol(RenderContext *state, double scale, int cur_line
static void measure_text(RenderContext *state)
{
ASS_Renderer *render_priv = state->renderer;
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
text_info->height = 0;
text_info->border_x = 0;
@@ -1661,7 +1670,7 @@ static void trim_whitespace(RenderContext *state)
{
int i, j;
GlyphInfo *cur;
- TextInfo *ti = state->text_info;
+ TextInfo *ti = &state->text_info;
// Mark trailing spaces
i = ti->length - 1;
@@ -1732,7 +1741,7 @@ static void
wrap_lines_naive(RenderContext *state, double max_text_width, char *unibrks)
{
ASS_Renderer *render_priv = state->renderer;
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
GlyphInfo *s1 = text_info->glyphs; // current line start
int last_breakable = -1;
int break_type = 0;
@@ -1812,7 +1821,7 @@ static inline GlyphInfo *rewind_trailing_spaces(GlyphInfo *start1, GlyphInfo* st
static void
wrap_lines_rebalance(RenderContext *state, double max_text_width, char *unibrks)
{
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
int exit = 0;
#define DIFF(x,y) (((x) < (y)) ? (y - x) : (x - y))
@@ -1881,7 +1890,7 @@ wrap_lines_rebalance(RenderContext *state, double max_text_width, char *unibrks)
static void
wrap_lines_measure(RenderContext *state, char *unibrks)
{
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
int cur_line = 1;
int i = 0;
@@ -1933,7 +1942,7 @@ wrap_lines_smart(RenderContext *state, double max_text_width)
#ifdef CONFIG_UNIBREAK
ASS_Renderer *render_priv = state->renderer;
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
if (render_priv->track->parser_priv->feature_flags & FEATURE_MASK(ASS_FEATURE_WRAP_UNICODE)) {
unibrks = text_info->breaks;
set_linebreaks_utf32(
@@ -2033,7 +2042,7 @@ fix_glyph_scaling(ASS_Renderer *priv, GlyphInfo *glyph)
// Initial run splitting based purely on the characters' styles
static void split_style_runs(RenderContext *state)
{
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
Effect last_effect_type = text_info->glyphs[0].effect_type;
text_info->glyphs[0].starts_new_run = true;
for (int i = 1; i < text_info->length; i++) {
@@ -2079,7 +2088,7 @@ static void split_style_runs(RenderContext *state)
// Fill render_priv->text_info.
static bool parse_events(RenderContext *state, ASS_Event *event)
{
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
ASS_Renderer *render_priv = state->renderer;
char *p = event->Text, *q;
@@ -2214,10 +2223,10 @@ fail:
// Process render_priv->text_info and load glyph outlines.
static void retrieve_glyphs(RenderContext *state)
{
- GlyphInfo *glyphs = state->text_info->glyphs;
+ GlyphInfo *glyphs = state->text_info.glyphs;
int i;
- for (i = 0; i < state->text_info->length; i++) {
+ for (i = 0; i < state->text_info.length; i++) {
GlyphInfo *info = glyphs + i;
do {
get_outline_glyph(state, info);
@@ -2245,8 +2254,8 @@ static void retrieve_glyphs(RenderContext *state)
static void preliminary_layout(RenderContext *state)
{
ASS_Vector pen = { 0, 0 };
- for (int i = 0; i < state->text_info->length; i++) {
- GlyphInfo *info = state->text_info->glyphs + i;
+ for (int i = 0; i < state->text_info.length; i++) {
+ GlyphInfo *info = state->text_info.glyphs + i;
ASS_Vector cluster_pen = pen;
do {
info->pos.x = cluster_pen.x;
@@ -2257,7 +2266,7 @@ static void preliminary_layout(RenderContext *state)
info = info->next;
} while (info);
- info = state->text_info->glyphs + i;
+ info = state->text_info.glyphs + i;
pen.x += info->cluster_advance.x;
pen.y += info->cluster_advance.y;
}
@@ -2267,7 +2276,7 @@ static void preliminary_layout(RenderContext *state)
static void reorder_text(RenderContext *state)
{
ASS_Renderer *render_priv = state->renderer;
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
FriBidiStrIndex *cmap = ass_shaper_reorder(state->shaper, text_info);
if (!cmap) {
ass_msg(render_priv->library, MSGL_ERR, "Failed to reorder text");
@@ -2306,7 +2315,7 @@ static void reorder_text(RenderContext *state)
static void apply_baseline_shear(RenderContext *state)
{
ASS_Renderer *render_priv = state->renderer;
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
FriBidiStrIndex *cmap = ass_shaper_get_reorder_map(state->shaper);
int32_t shear = 0;
bool whole_text_layout =
@@ -2329,7 +2338,7 @@ static void apply_baseline_shear(RenderContext *state)
static void align_lines(RenderContext *state, double max_text_width)
{
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
GlyphInfo *glyphs = text_info->glyphs;
int i, j;
double width = 0;
@@ -2413,7 +2422,7 @@ static void calculate_rotation_params(RenderContext *state, ASS_DRect *bbox,
center.y = device_y + by;
}
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
for (int i = 0; i < text_info->length; i++) {
GlyphInfo *info = text_info->glyphs + i;
while (info) {
@@ -2481,7 +2490,7 @@ static void render_and_combine_glyphs(RenderContext *state,
double device_x, double device_y)
{
ASS_Renderer *render_priv = state->renderer;
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
int left = render_priv->settings.left_margin;
device_x = (device_x - left) * render_priv->par_scale_x + left;
unsigned nb_bitmaps = 0;
@@ -2852,7 +2861,7 @@ ass_render_event(RenderContext *state, ASS_Event *event,
if (!parse_events(state, event))
return false;
- TextInfo *text_info = state->text_info;
+ TextInfo *text_info = &state->text_info;
if (text_info->length == 0) {
// no valid symbols in the event; this can be smth like {comment}
free_render_context(state);
diff --git a/libass/ass_render.h b/libass/ass_render.h
index 3c717b8..a3de04a 100644
--- a/libass/ass_render.h
+++ b/libass/ass_render.h
@@ -210,7 +210,7 @@ typedef struct {
// Values like current font face, color, screen position, clipping and so on are stored here.
struct render_context {
ASS_Renderer *renderer;
- TextInfo *text_info;
+ TextInfo text_info;
ASS_Shaper *shaper;
RasterizerData rasterizer;
@@ -334,7 +334,6 @@ struct ass_renderer {
double par_scale_x; // x scale applied to all glyphs to preserve text aspect ratio
RenderContext state;
- TextInfo text_info;
CacheStore cache;
BitmapEngine engine;
diff --git a/libass/ass_shaper.c b/libass/ass_shaper.c
index 1d83757..fa445da 100644
--- a/libass/ass_shaper.c
+++ b/libass/ass_shaper.c
@@ -65,6 +65,9 @@ struct ass_shaper {
// Glyph metrics cache, to speed up shaping
Cache *metrics_cache;
+ hb_font_funcs_t *font_funcs;
+ hb_buffer_t *buf;
+
#ifdef USE_FRIBIDI_EX_API
FriBidiBracketType *btypes;
bool bidi_brackets;
@@ -79,12 +82,6 @@ struct ass_shaper_metrics_data {
int vertical;
};
-struct ass_shaper_font_data {
- hb_font_t *fonts[ASS_FONT_MAX_FACES];
- hb_font_funcs_t *font_funcs[ASS_FONT_MAX_FACES];
- struct ass_shaper_metrics_data *metrics_data[ASS_FONT_MAX_FACES];
-};
-
/**
* \brief Print version information
*/
@@ -142,21 +139,11 @@ void ass_shaper_free(ASS_Shaper *shaper)
free(shaper->emblevels);
free(shaper->cmap);
free(shaper->pbase_dir);
+ hb_font_funcs_destroy(shaper->font_funcs);
+ hb_buffer_destroy(shaper->buf);
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]);
- hb_font_funcs_destroy(priv->font_funcs[i]);
- }
- free(priv);
-}
-
/**
* \brief set up the HarfBuzz OpenType feature list with some
* standard features.
@@ -296,8 +283,8 @@ static hb_bool_t
get_glyph_nominal(hb_font_t *font, void *font_data, hb_codepoint_t unicode,
hb_codepoint_t *glyph, void *user_data)
{
- FT_Face face = font_data;
- struct ass_shaper_metrics_data *metrics_priv = user_data;
+ struct ass_shaper_metrics_data *metrics_priv = font_data;
+ FT_Face face = metrics_priv->hash_key.font->faces[metrics_priv->hash_key.face_index];
*glyph = ass_font_index_magic(face, unicode);
if (*glyph)
@@ -315,8 +302,8 @@ static hb_bool_t
get_glyph_variation(hb_font_t *font, void *font_data, hb_codepoint_t unicode,
hb_codepoint_t variation, hb_codepoint_t *glyph, void *user_data)
{
- FT_Face face = font_data;
- struct ass_shaper_metrics_data *metrics_priv = user_data;
+ struct ass_shaper_metrics_data *metrics_priv = font_data;
+ FT_Face face = metrics_priv->hash_key.font->faces[metrics_priv->hash_key.face_index];
*glyph = ass_font_index_magic(face, unicode);
if (*glyph)
@@ -334,7 +321,7 @@ static hb_position_t
cached_h_advance(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
void *user_data)
{
- struct ass_shaper_metrics_data *metrics_priv = user_data;
+ struct ass_shaper_metrics_data *metrics_priv = font_data;
FT_Glyph_Metrics *metrics = get_cached_metrics(metrics_priv, 0, glyph);
if (!metrics)
return 0;
@@ -348,7 +335,7 @@ static hb_position_t
cached_v_advance(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
void *user_data)
{
- struct ass_shaper_metrics_data *metrics_priv = user_data;
+ struct ass_shaper_metrics_data *metrics_priv = font_data;
FT_Glyph_Metrics *metrics = get_cached_metrics(metrics_priv, 0, glyph);
if (!metrics)
return 0;
@@ -369,7 +356,7 @@ static hb_bool_t
cached_v_origin(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
hb_position_t *x, hb_position_t *y, void *user_data)
{
- struct ass_shaper_metrics_data *metrics_priv = user_data;
+ struct ass_shaper_metrics_data *metrics_priv = font_data;
FT_Glyph_Metrics *metrics = get_cached_metrics(metrics_priv, 0, glyph);
if (!metrics)
return false;
@@ -384,7 +371,8 @@ static hb_position_t
get_h_kerning(hb_font_t *font, void *font_data, hb_codepoint_t first,
hb_codepoint_t second, void *user_data)
{
- FT_Face face = font_data;
+ struct ass_shaper_metrics_data *metrics_priv = font_data;
+ FT_Face face = metrics_priv->hash_key.font->faces[metrics_priv->hash_key.face_index];
FT_Vector kern;
if (FT_Get_Kerning(face, first, second, FT_KERNING_DEFAULT, &kern))
@@ -404,7 +392,7 @@ static hb_bool_t
cached_extents(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
hb_glyph_extents_t *extents, void *user_data)
{
- struct ass_shaper_metrics_data *metrics_priv = user_data;
+ struct ass_shaper_metrics_data *metrics_priv = font_data;
FT_Glyph_Metrics *metrics = get_cached_metrics(metrics_priv, 0, glyph);
if (!metrics)
return false;
@@ -422,7 +410,8 @@ get_contour_point(hb_font_t *font, void *font_data, hb_codepoint_t glyph,
unsigned int point_index, hb_position_t *x,
hb_position_t *y, void *user_data)
{
- FT_Face face = font_data;
+ struct ass_shaper_metrics_data *metrics_priv = font_data;
+ FT_Face face = metrics_priv->hash_key.font->faces[metrics_priv->hash_key.face_index];
int load_flags = FT_LOAD_DEFAULT | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH
| FT_LOAD_IGNORE_TRANSFORM;
@@ -437,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.
@@ -446,78 +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_funcs_t *funcs = hb_font_funcs_create();
- if (!funcs)
- return NULL;
- font->shaper_priv->font_funcs[info->face_index] = funcs;
- hb_font_funcs_set_nominal_glyph_func(funcs, get_glyph_nominal,
- metrics, NULL);
- hb_font_funcs_set_variation_glyph_func(funcs, get_glyph_variation,
- metrics, NULL);
- hb_font_funcs_set_glyph_h_advance_func(funcs, cached_h_advance,
- metrics, NULL);
- hb_font_funcs_set_glyph_v_advance_func(funcs, cached_v_advance,
- metrics, NULL);
- hb_font_funcs_set_glyph_h_origin_func(funcs, cached_h_origin,
- metrics, NULL);
- hb_font_funcs_set_glyph_v_origin_func(funcs, cached_v_origin,
- metrics, NULL);
- hb_font_funcs_set_glyph_h_kerning_func(funcs, get_h_kerning,
- metrics, NULL);
- hb_font_funcs_set_glyph_v_kerning_func(funcs, get_v_kerning,
- metrics, NULL);
- hb_font_funcs_set_glyph_extents_func(funcs, cached_extents,
- metrics, NULL);
- hb_font_funcs_set_glyph_contour_point_func(funcs, get_contour_point,
- metrics, NULL);
- hb_font_set_funcs(hb_font, funcs, face, 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;
- return hb_fonts[info->face_index];
+ hb_font_set_funcs(hb_font, shaper->font_funcs, metrics, free);
+
+ return hb_font;
}
/**
@@ -686,7 +642,7 @@ shape_harfbuzz_process_run(GlyphInfo *glyphs, hb_buffer_t *buf, int offset)
static bool shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
{
int i;
- hb_buffer_t *buf = hb_buffer_create();
+ hb_buffer_t *buf = shaper->buf;
hb_segment_properties_t props = HB_SEGMENT_PROPERTIES_DEFAULT;
// Initialize: skip all glyphs, this is undone later as needed
@@ -745,8 +701,6 @@ static bool shape_harfbuzz(ASS_Shaper *shaper, GlyphInfo *glyphs, size_t len)
hb_buffer_reset(buf);
}
- hb_buffer_destroy(buf);
-
return true;
}
@@ -1057,6 +1011,26 @@ ASS_Shaper *ass_shaper_new(Cache *metrics_cache)
goto error;
shaper->metrics_cache = metrics_cache;
+ hb_font_funcs_t *funcs = shaper->font_funcs = hb_font_funcs_create();
+ if (!funcs)
+ goto error;
+ hb_font_funcs_set_nominal_glyph_func(funcs, get_glyph_nominal, NULL, NULL);
+ hb_font_funcs_set_variation_glyph_func(funcs, get_glyph_variation, NULL, NULL);
+ hb_font_funcs_set_glyph_h_advance_func(funcs, cached_h_advance, NULL, NULL);
+ hb_font_funcs_set_glyph_v_advance_func(funcs, cached_v_advance, NULL, NULL);
+ hb_font_funcs_set_glyph_h_origin_func(funcs, cached_h_origin, NULL, NULL);
+ hb_font_funcs_set_glyph_v_origin_func(funcs, cached_v_origin, NULL, NULL);
+ hb_font_funcs_set_glyph_h_kerning_func(funcs, get_h_kerning, NULL, NULL);
+ hb_font_funcs_set_glyph_v_kerning_func(funcs, get_v_kerning, NULL, NULL);
+ hb_font_funcs_set_glyph_extents_func(funcs, cached_extents, NULL, NULL);
+ hb_font_funcs_set_glyph_contour_point_func(funcs, get_contour_point, NULL, NULL);
+
+ hb_font_funcs_make_immutable(funcs);
+
+ shaper->buf = hb_buffer_create();
+ if (!shaper->buf)
+ goto error;
+
return shaper;
error:
diff --git a/libass/ass_shaper.h b/libass/ass_shaper.h
index 819a3fd..b4694b0 100644
--- a/libass/ass_shaper.h
+++ b/libass/ass_shaper.h
@@ -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);
@@ -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
diff --git a/libass/meson.build b/libass/meson.build
new file mode 100644
index 0000000..b63c5cf
--- /dev/null
+++ b/libass/meson.build
@@ -0,0 +1,149 @@
+# Read library versioning from Automake
+# (should we ever reorder those in Automake, it will correctly fail
+# due to undefined variables rather than using bogus versions)
+fs = import('fs')
+am_lib_file = fs.read('Makefile_library.am').split('\n')
+foreach line : am_lib_file
+ args = line.split('=')
+ name = args[0].strip()
+ val = args[1].strip()
+ if name == 'LIBASS_LT_CURRENT'
+ libass_lt_current = val.to_int()
+ elif name == 'LIBASS_LT_REVISION'
+ libass_lt_revision = val.to_int()
+ elif name == 'LIBASS_LT_AGE'
+ libass_lt_age = val.to_int()
+ break
+ endif
+endforeach
+
+libass_so_version = '@0@.@1@.@2@'.format(
+ libass_lt_current - libass_lt_age,
+ libass_lt_age,
+ libass_lt_revision,
+)
+
+src_x86 = files(
+ 'x86/be_blur.asm',
+ 'x86/blend_bitmaps.asm',
+ 'x86/blur.asm',
+ 'x86/cpuid.asm',
+ 'x86/rasterizer.asm',
+)
+src_aarch64 = files(
+ 'aarch64/asm.S',
+ 'aarch64/be_blur.S',
+ 'aarch64/blend_bitmaps.S',
+ 'aarch64/blur.S',
+ 'aarch64/rasterizer.S',
+)
+src_fontconfig = files('ass_fontconfig.c')
+src_directwrite = files('ass_directwrite.c')
+src_coretext = files('ass_coretext.c')
+
+libass_src = files(
+ 'c/c_be_blur.c',
+ 'c/c_blend_bitmaps.c',
+ 'c/c_blur.c',
+ 'c/c_rasterizer.c',
+ 'ass.c',
+ 'ass_bitmap.c',
+ 'ass_bitmap_engine.c',
+ 'ass_blur.c',
+ 'ass_cache.c',
+ 'ass_drawing.c',
+ 'ass_filesystem.c',
+ 'ass_font.c',
+ 'ass_fontselect.c',
+ 'ass_library.c',
+ 'ass_outline.c',
+ 'ass_parse.c',
+ 'ass_rasterizer.c',
+ 'ass_render.c',
+ 'ass_render_api.c',
+ 'ass_shaper.c',
+ 'ass_string.c',
+ 'ass_strtod.c',
+ 'ass_utils.c',
+)
+
+libass_link_with = []
+
+libass_headers = files('ass.h', 'ass_types.h')
+
+if fontconfig
+ libass_src += src_fontconfig
+endif
+if directwrite
+ libass_src += src_directwrite
+endif
+if coretext
+ libass_src += src_coretext
+endif
+
+if enable_asm
+ asm_sources = []
+ if cpu_family == 'x86'
+ asm_sources = src_x86
+ elif cpu_subfamily == 'aarch64'
+ asm_sources = src_aarch64
+ endif
+
+ if asm_is_nasm
+ libass_src += asm_sources
+ else
+ asm_lib = sta