summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigori Goronzy <greg@blackbox>2011-06-20 23:12:22 +0200
committerGrigori Goronzy <greg@blackbox>2011-06-20 23:20:25 +0200
commit1fdd4c0b394bc0ddd63129ede6fd87b8c3249712 (patch)
treeeb3228e8d91171068555525c1fad4daf2e46d35e
parente5704aa76a2712782442156986f74b8766077ee1 (diff)
downloadlibass-1fdd4c0b394bc0ddd63129ede6fd87b8c3249712.tar.bz2
libass-1fdd4c0b394bc0ddd63129ede6fd87b8c3249712.tar.xz
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.
-rw-r--r--libass/ass_drawing.c62
-rw-r--r--libass/ass_drawing.h12
-rw-r--r--libass/ass_parse.c8
-rw-r--r--libass/ass_render.c24
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 <ft2build.h>
-#include FT_GLYPH_H
#include FT_OUTLINE_H
#include FT_BBOX_H
#include <math.h>
@@ -31,35 +30,12 @@
#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 <ft2build.h>
-#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);
}
}