From 1fdd4c0b394bc0ddd63129ede6fd87b8c3249712 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Mon, 20 Jun 2011 23:12:22 +0200 Subject: Use bare outlines for drawings This finally gets rid of the nasty hack that manipulated a glyph we somehow got from FreeType. Simplifies drawing handling a bit and decouples drawing code from all font handling and related (fontconfig, etc.) code. --- libass/ass_drawing.c | 62 ++++++++++++++-------------------------------------- libass/ass_drawing.h | 12 +++++----- libass/ass_parse.c | 8 ++----- libass/ass_render.c | 24 +++++++------------- 4 files changed, 32 insertions(+), 74 deletions(-) diff --git a/libass/ass_drawing.c b/libass/ass_drawing.c index 940c66b..e25f213 100644 --- a/libass/ass_drawing.c +++ b/libass/ass_drawing.c @@ -17,7 +17,6 @@ */ #include -#include FT_GLYPH_H #include FT_OUTLINE_H #include FT_BBOX_H #include @@ -30,36 +29,13 @@ #define GLYPH_INITIAL_POINTS 100 #define GLYPH_INITIAL_CONTOURS 5 -/* - * \brief Get and prepare a FreeType glyph - */ -static void drawing_make_glyph(ASS_Drawing *drawing, void *fontconfig_priv, - ASS_Font *font) -{ - FT_OutlineGlyph glyph; - - // This is hacky... - glyph = (FT_OutlineGlyph) ass_font_get_glyph(fontconfig_priv, font, - (uint32_t) ' ', 0, 0); - if (glyph) { - FT_Outline_Done(drawing->ftlibrary, &glyph->outline); - FT_Outline_New(drawing->ftlibrary, GLYPH_INITIAL_POINTS, - GLYPH_INITIAL_CONTOURS, &glyph->outline); - - glyph->outline.n_contours = 0; - glyph->outline.n_points = 0; - glyph->root.advance.x = glyph->root.advance.y = 0; - } - drawing->glyph = glyph; -} - /* * \brief Add a single point to a contour. */ static inline void drawing_add_point(ASS_Drawing *drawing, FT_Vector *point) { - FT_Outline *ol = &drawing->glyph->outline; + FT_Outline *ol = &drawing->outline; if (ol->n_points >= drawing->max_points) { drawing->max_points *= 2; @@ -75,11 +51,11 @@ static inline void drawing_add_point(ASS_Drawing *drawing, } /* - * \brief Close a contour and check glyph size overflow. + * \brief Close a contour and check outline size overflow. */ static inline void drawing_close_shape(ASS_Drawing *drawing) { - FT_Outline *ol = &drawing->glyph->outline; + FT_Outline *ol = &drawing->outline; if (ol->n_contours >= drawing->max_contours) { drawing->max_contours *= 2; @@ -107,13 +83,13 @@ static void drawing_prepare(ASS_Drawing *drawing) /* * \brief Finish a drawing. This only sets the horizontal advance according - * to the glyph's bbox at the moment. + * to the outline's bbox at the moment. */ static void drawing_finish(ASS_Drawing *drawing, int raw_mode) { int i, offset; FT_BBox bbox = drawing->cbox; - FT_Outline *ol = &drawing->glyph->outline; + FT_Outline *ol = &drawing->outline; // Close the last contour drawing_close_shape(drawing); @@ -126,7 +102,7 @@ static void drawing_finish(ASS_Drawing *drawing, int raw_mode) if (raw_mode) return; - drawing->glyph->root.advance.x = d6_to_d16(bbox.xMax - bbox.xMin); + drawing->advance.x = bbox.xMax - bbox.xMin; drawing->desc = double_to_d6(-drawing->pbo * drawing->scale_y); drawing->asc = bbox.yMax - bbox.yMin + drawing->desc; @@ -355,8 +331,7 @@ static void drawing_evaluate_curve(ASS_Drawing *drawing, /* * \brief Create and initialize a new drawing and return it */ -ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font, - FT_Library lib) +ASS_Drawing *ass_drawing_new(ASS_Library *lib, FT_Library ftlib) { ASS_Drawing *drawing; @@ -365,17 +340,18 @@ ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font, drawing->size = DRAWING_INITIAL_SIZE; drawing->cbox.xMin = drawing->cbox.yMin = INT_MAX; drawing->cbox.xMax = drawing->cbox.yMax = INT_MIN; - drawing->fontconfig_priv = fontconfig_priv; - drawing->font = font; - drawing->ftlibrary = lib; - if (font) - drawing->library = font->library; - + drawing->ftlibrary = ftlib; + drawing->library = lib; drawing->scale_x = 1.; drawing->scale_y = 1.; drawing->max_contours = GLYPH_INITIAL_CONTOURS; drawing->max_points = GLYPH_INITIAL_POINTS; + FT_Outline_New(drawing->ftlibrary, GLYPH_INITIAL_POINTS, + GLYPH_INITIAL_CONTOURS, &drawing->outline); + drawing->outline.n_contours = 0; + drawing->outline.n_points = 0; + return drawing; } @@ -386,6 +362,7 @@ void ass_drawing_free(ASS_Drawing* drawing) { if (drawing) { free(drawing->text); + FT_Outline_Done(drawing->ftlibrary, &drawing->outline); } free(drawing); } @@ -416,17 +393,12 @@ void ass_drawing_hash(ASS_Drawing* drawing) /* * \brief Convert token list to outline. Calls the line and curve evaluators. */ -FT_OutlineGlyph *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode) +FT_Outline *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode) { int started = 0; ASS_DrawingToken *token; FT_Vector pen = {0, 0}; - if (drawing->font) - drawing_make_glyph(drawing, drawing->fontconfig_priv, drawing->font); - if (!drawing->glyph) - return NULL; - drawing->tokens = drawing_tokenize(drawing->text); drawing_prepare(drawing); @@ -486,5 +458,5 @@ FT_OutlineGlyph *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode) drawing_finish(drawing, raw_mode); drawing_free_tokens(drawing->tokens); - return &drawing->glyph; + return &drawing->outline; } diff --git a/libass/ass_drawing.h b/libass/ass_drawing.h index f677fcd..b17d7e3 100644 --- a/libass/ass_drawing.h +++ b/libass/ass_drawing.h @@ -20,7 +20,7 @@ #define LIBASS_DRAWING_H #include -#include FT_GLYPH_H +#include FT_OUTLINE_H #include "ass.h" @@ -53,13 +53,12 @@ typedef struct { double scale_y; // FontScaleY int asc; // ascender int desc; // descender - FT_OutlineGlyph glyph; // the "fake" glyph created for later rendering + FT_Outline outline; // target outline + FT_Vector advance; // advance (from cbox) int hash; // hash value (for caching) // private FT_Library ftlibrary; // needed for font ops - ASS_Font *font; // dito - void *fontconfig_priv; // dito ASS_Library *library; int size; // current buffer size ASS_DrawingToken *tokens; // tokenized drawing @@ -70,11 +69,10 @@ typedef struct { FT_BBox cbox; // bounding box, or let's say... VSFilter's idea of it } ASS_Drawing; -ASS_Drawing *ass_drawing_new(void *fontconfig_priv, ASS_Font *font, - FT_Library lib); +ASS_Drawing *ass_drawing_new(ASS_Library *lib, FT_Library ftlib); void ass_drawing_free(ASS_Drawing* drawing); void ass_drawing_add_char(ASS_Drawing* drawing, char symbol); void ass_drawing_hash(ASS_Drawing* drawing); -FT_OutlineGlyph *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode); +FT_Outline *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode); #endif /* LIBASS_DRAWING_H */ diff --git a/libass/ass_parse.c b/libass/ass_parse.c index 7a6dd25..d9fcb76 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -216,13 +216,9 @@ static char *parse_vector_clip(ASS_Renderer *render_priv, char *p) int res = 0; ASS_Drawing *drawing = render_priv->state.clip_drawing; - if (drawing && drawing->glyph) - FT_Done_Glyph((FT_Glyph) drawing->glyph); ass_drawing_free(drawing); - render_priv->state.clip_drawing = ass_drawing_new( - render_priv->fontconfig_priv, - render_priv->state.font, - render_priv->ftlibrary); + render_priv->state.clip_drawing = + ass_drawing_new(render_priv->library, render_priv->ftlibrary); drawing = render_priv->state.clip_drawing; skipopt('('); res = mystrtoi(&p, &scale); diff --git a/libass/ass_render.c b/libass/ass_render.c index 9a1b911..021bfc4 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -559,8 +559,7 @@ static void blend_vector_clip(ASS_Renderer *render_priv, GlyphHashValue v; // Not found in cache, parse and rasterize it - ass_drawing_parse(drawing, 1); - outline = &drawing->glyph->outline; + outline = ass_drawing_parse(drawing, 1); if (!outline) { ass_msg(render_priv->library, MSGL_WARN, "Clip vector parsing failed. Skipping."); @@ -574,8 +573,7 @@ static void blend_vector_clip(ASS_Renderer *render_priv, .x = int_to_d6(render_priv->settings.left_margin), .y = -int_to_d6(render_priv->settings.top_margin), }; - FT_Outline_Translate(&drawing->glyph->outline, - trans.x, trans.y); + FT_Outline_Translate(outline, trans.x, trans.y); } ass_msg(render_priv->library, MSGL_DBG2, @@ -587,7 +585,6 @@ static void blend_vector_clip(ASS_Renderer *render_priv, if (clip_bm == NULL) { ass_msg(render_priv->library, MSGL_WARN, "Clip vector rasterization failed: %d. Skipping.", error); - FT_Outline_Done(render_priv->ftlibrary, outline); } //clip_bm = (FT_BitmapGlyph) glyph; @@ -682,7 +679,6 @@ blend_vector_error: blend_vector_exit: ass_free_bitmap(clip_bm); - FT_Outline_Done(render_priv->ftlibrary, outline); ass_drawing_free(render_priv->state.clip_drawing); render_priv->state.clip_drawing = 0; } @@ -879,9 +875,8 @@ init_render_context(ASS_Renderer *render_priv, ASS_Event *event) render_priv->state.effect_timing = 0; render_priv->state.effect_skip_timing = 0; ass_drawing_free(render_priv->state.drawing); - render_priv->state.drawing = ass_drawing_new(render_priv->fontconfig_priv, - render_priv->state.font, - render_priv->ftlibrary); + render_priv->state.drawing = ass_drawing_new(render_priv->library, + render_priv->ftlibrary); apply_transition_effects(render_priv, event); } @@ -1073,11 +1068,10 @@ get_outline_glyph(ASS_Renderer *render_priv, int symbol, GlyphInfo *info, if (drawing->hash) { if(!ass_drawing_parse(drawing, 0)) return; - outline_copy(render_priv->ftlibrary, &drawing->glyph->outline, + outline_copy(render_priv->ftlibrary, &drawing->outline, &info->outline); - info->advance.x = d16_to_d6(((FT_Glyph)drawing->glyph)->advance.x); - info->advance.y = d16_to_d6(((FT_Glyph)drawing->glyph)->advance.y); - FT_Done_Glyph((FT_Glyph)drawing->glyph); + info->advance.x = drawing->advance.x; + info->advance.y = drawing->advance.y; } else { FT_Glyph glyph = ass_font_get_glyph(render_priv->fontconfig_priv, @@ -1805,9 +1799,7 @@ ass_render_event(ASS_Renderer *render_priv, ASS_Event *event, if (drawing->hash) { ass_drawing_free(drawing); drawing = render_priv->state.drawing = - ass_drawing_new(render_priv->fontconfig_priv, - render_priv->state.font, - render_priv->ftlibrary); + ass_drawing_new(render_priv->library, render_priv->ftlibrary); } } -- cgit v1.2.3