From: Dr.Smile Date: Sun, 17 Sep 2017 00:00:34 +0000 (+0300) Subject: Replace FreeType types with libass native types X-Git-Tag: 0.14.0~15 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f159a8cf55c8b3f2193ab20159a255310c7c5ca9;p=libass Replace FreeType types with libass native types FT_Vector and FT_BBox types are based on FT_Pos, which is alias of long. FreeType treats it as 32-bit integer, but on some platforms long can be 64-bit. That leads to wasted memory and suboptimal performance. --- diff --git a/libass/ass_bitmap.h b/libass/ass_bitmap.h index 8dc1b19..e919cd5 100644 --- a/libass/ass_bitmap.h +++ b/libass/ass_bitmap.h @@ -24,6 +24,7 @@ #include FT_GLYPH_H #include "ass.h" +#include "ass_outline.h" struct segment; @@ -88,8 +89,6 @@ extern const BitmapEngine ass_bitmap_engine_sse2; extern const BitmapEngine ass_bitmap_engine_avx2; -typedef struct ass_outline ASS_Outline; - typedef struct { int left, top; int w, h; // width, height diff --git a/libass/ass_cache.h b/libass/ass_cache.h index 03e58c7..278eae4 100644 --- a/libass/ass_cache.h +++ b/libass/ass_cache.h @@ -45,8 +45,8 @@ typedef struct { bool valid; ASS_Outline outline; ASS_Outline border[2]; - FT_BBox bbox_scaled; // bbox after scaling, but before rotation - FT_Vector advance; // 26.6, advance distance to the next outline in line + ASS_Rect bbox_scaled; // bbox after scaling, but before rotation + ASS_Vector advance; // 26.6, advance distance to the next outline in line int asc, desc; // ascender/descender } OutlineHashValue; diff --git a/libass/ass_cache_template.h b/libass/ass_cache_template.h index 9d81231..ba9303f 100644 --- a/libass/ass_cache_template.h +++ b/libass/ass_cache_template.h @@ -6,8 +6,8 @@ type member; #define STRING(member) \ char *member; -#define FTVECTOR(member) \ - FT_Vector member; +#define VECTOR(member) \ + ASS_Vector member; #define BITMAPHASHKEY(member) \ BitmapHashKey member; #define END(typedefnamename) \ @@ -25,7 +25,7 @@ a->member == b->member && #define STRING(member) \ strcmp(a->member, b->member) == 0 && -#define FTVECTOR(member) \ +#define VECTOR(member) \ a->member.x == b->member.x && a->member.y == b->member.y && #define BITMAPHASHKEY(member) \ bitmap_compare(&a->member, &b->member, sizeof(a->member)) && @@ -44,7 +44,7 @@ hval = fnv_32a_buf(&p->member, sizeof(p->member), hval); #define STRING(member) \ hval = fnv_32a_str(p->member, hval); -#define FTVECTOR(member) GENERIC(, member.x); GENERIC(, member.y); +#define VECTOR(member) GENERIC(, member.x); GENERIC(, member.y); #define BITMAPHASHKEY(member) { \ unsigned temp = bitmap_hash(&p->member, sizeof(p->member)); \ hval = fnv_32a_buf(&temp, sizeof(temp), hval); \ @@ -72,7 +72,7 @@ START(outline_bitmap, outline_bitmap_hash_key) // = (glyph base point) - (rotation origin), otherwise GENERIC(int, shift_x) GENERIC(int, shift_y) - FTVECTOR(advance) // subpixel shift vector + VECTOR(advance) // subpixel shift vector END(OutlineBitmapHashKey) // describe a clip mask bitmap @@ -90,7 +90,7 @@ START(glyph, glyph_hash_key) GENERIC(int, italic) GENERIC(unsigned, scale_x) // 16.16 GENERIC(unsigned, scale_y) // 16.16 - FTVECTOR(outline) // border width, 26.6 + VECTOR(outline) // border width, 26.6 GENERIC(unsigned, flags) // glyph decoration flags GENERIC(unsigned, border_style) GENERIC(int, hspacing) // 16.16 @@ -110,7 +110,7 @@ START(drawing, drawing_hash_key) GENERIC(unsigned, scale_x) GENERIC(unsigned, scale_y) GENERIC(int, pbo) - FTVECTOR(outline) + VECTOR(outline) GENERIC(unsigned, border_style) GENERIC(int, hspacing) GENERIC(int, scale) @@ -123,12 +123,12 @@ START(filter, filter_desc) GENERIC(int, flags) GENERIC(int, be) GENERIC(double, blur) - FTVECTOR(shadow) + VECTOR(shadow) END(FilterDesc) #undef START #undef GENERIC #undef STRING -#undef FTVECTOR +#undef VECTOR #undef BITMAPHASHKEY #undef END diff --git a/libass/ass_drawing.c b/libass/ass_drawing.c index 23fe8cd..d235517 100644 --- a/libass/ass_drawing.c +++ b/libass/ass_drawing.c @@ -21,7 +21,6 @@ #include #include FT_OUTLINE_H -#include FT_BBOX_H #include #include #include @@ -30,7 +29,6 @@ #include "ass_drawing.h" #include "ass_font.h" -#define CURVE_ACCURACY 64.0 #define GLYPH_INITIAL_POINTS 100 #define GLYPH_INITIAL_CONTOURS 5 @@ -48,11 +46,9 @@ static void drawing_prepare(ASS_Drawing *drawing) * \brief Finish a drawing. This only sets the horizontal advance according * to the outline's bbox at the moment. */ -static void drawing_finish(ASS_Drawing *drawing, int raw_mode) +static void drawing_finish(ASS_Drawing *drawing, bool raw_mode) { - int i; - double pbo; - FT_BBox bbox = drawing->cbox; + ASS_Rect bbox = drawing->cbox; ASS_Outline *ol = &drawing->outline; if (drawing->library) @@ -63,14 +59,14 @@ static void drawing_finish(ASS_Drawing *drawing, int raw_mode) if (raw_mode) return; - drawing->advance.x = bbox.xMax - bbox.xMin; + drawing->advance.x = bbox.x_max - bbox.x_min; - pbo = drawing->pbo / (1 << (drawing->scale - 1)); + double pbo = drawing->pbo / (1 << (drawing->scale - 1)); drawing->desc = double_to_d6(pbo * drawing->scale_y); - drawing->asc = bbox.yMax - bbox.yMin - drawing->desc; + drawing->asc = bbox.y_max - bbox.y_min - drawing->desc; // Place it onto the baseline - for (i = 0; i < ol->n_points; i++) + for (size_t i = 0; i < ol->n_points; i++) ol->points[i].y += drawing->asc; } @@ -79,8 +75,7 @@ static void drawing_finish(ASS_Drawing *drawing, int raw_mode) */ static int token_check_values(ASS_DrawingToken *token, int i, int type) { - int j; - for (j = 0; j < i; j++) { + for (int j = 0; j < i; j++) { if (!token || token->type != type) return 0; token = token->next; } @@ -95,9 +90,9 @@ static int token_check_values(ASS_DrawingToken *token, int i, int type) static ASS_DrawingToken *drawing_tokenize(char *str) { char *p = str; - int i, type = -1, is_set = 0; + int type = -1, is_set = 0; double val; - FT_Vector point = {0, 0}; + ASS_Vector point = {0, 0}; ASS_DrawingToken *root = NULL, *tail = NULL, *spline_start = NULL; @@ -107,7 +102,7 @@ static ASS_DrawingToken *drawing_tokenize(char *str) // Close b-splines: add the first three points of the b-spline // back to the end if (token_check_values(spline_start->next, 2, TOKEN_B_SPLINE)) { - for (i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) { tail->next = calloc(1, sizeof(ASS_DrawingToken)); tail->next->prev = tail; tail = tail->next; @@ -181,21 +176,21 @@ static void drawing_free_tokens(ASS_DrawingToken *token) /* * \brief Update drawing cbox */ -static inline void update_cbox(ASS_Drawing *drawing, FT_Vector *point) +static inline void update_cbox(ASS_Drawing *drawing, ASS_Vector *point) { - FT_BBox *box = &drawing->cbox; + ASS_Rect *box = &drawing->cbox; - box->xMin = FFMIN(box->xMin, point->x); - box->xMax = FFMAX(box->xMax, point->x); - box->yMin = FFMIN(box->yMin, point->y); - box->yMax = FFMAX(box->yMax, point->y); + box->x_min = FFMIN(box->x_min, point->x); + box->x_max = FFMAX(box->x_max, point->x); + box->y_min = FFMIN(box->y_min, point->y); + box->y_max = FFMAX(box->y_max, point->y); } /* * \brief Translate and scale a point coordinate according to baseline * offset and scale. */ -static inline void translate_point(ASS_Drawing *drawing, FT_Vector *point) +static inline void translate_point(ASS_Drawing *drawing, ASS_Vector *point) { point->x = drawing->point_scale_x * point->x; point->y = drawing->point_scale_y * -point->y; @@ -204,15 +199,12 @@ static inline void translate_point(ASS_Drawing *drawing, FT_Vector *point) } /* - * \brief Evaluate a curve into lines - * This curve evaluator is also used in VSFilter (RTS.cpp); it's a simple - * implementation of the De Casteljau algorithm. + * \brief Add curve to drawing */ -static bool drawing_evaluate_curve(ASS_Drawing *drawing, - ASS_DrawingToken *token, char spline, - int started) +static bool drawing_add_curve(ASS_Drawing *drawing, ASS_DrawingToken *token, + bool spline, int started) { - FT_Vector p[4]; + ASS_Vector p[4]; for (int i = 0; i < 4; ++i) { p[i] = token->point; translate_point(drawing, &p[i]); @@ -247,14 +239,14 @@ static bool drawing_evaluate_curve(ASS_Drawing *drawing, /* * \brief Create and initialize a new drawing and return it */ -ASS_Drawing *ass_drawing_new(ASS_Library *lib, FT_Library ftlib) +ASS_Drawing *ass_drawing_new(ASS_Library *lib) { ASS_Drawing *drawing = calloc(1, sizeof(*drawing)); if (!drawing) return NULL; - drawing->cbox.xMin = drawing->cbox.yMin = INT_MAX; - drawing->cbox.xMax = drawing->cbox.yMax = INT_MIN; - drawing->library = lib; + drawing->cbox.x_min = drawing->cbox.y_min = INT32_MAX; + drawing->cbox.x_max = drawing->cbox.y_max = INT32_MIN; + drawing->library = lib; drawing->scale_x = 1.; drawing->scale_y = 1.; @@ -268,7 +260,7 @@ ASS_Drawing *ass_drawing_new(ASS_Library *lib, FT_Library ftlib) /* * \brief Free a drawing */ -void ass_drawing_free(ASS_Drawing* drawing) +void ass_drawing_free(ASS_Drawing *drawing) { if (drawing) { free(drawing->text); @@ -280,7 +272,7 @@ void ass_drawing_free(ASS_Drawing* drawing) /* * \brief Copy an ASCII string to the drawing text buffer */ -void ass_drawing_set_text(ASS_Drawing* drawing, char *str, size_t len) +void ass_drawing_set_text(ASS_Drawing *drawing, char *str, size_t len) { free(drawing->text); drawing->text = strndup(str, len); @@ -290,7 +282,7 @@ void ass_drawing_set_text(ASS_Drawing* drawing, char *str, size_t len) * \brief Create a hashcode for the drawing * XXX: To avoid collisions a better hash algorithm might be useful. */ -void ass_drawing_hash(ASS_Drawing* drawing) +void ass_drawing_hash(ASS_Drawing *drawing) { if (!drawing->text) return; @@ -300,11 +292,11 @@ void ass_drawing_hash(ASS_Drawing* drawing) /* * \brief Convert token list to outline. Calls the line and curve evaluators. */ -ASS_Outline *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode) +ASS_Outline *ass_drawing_parse(ASS_Drawing *drawing, bool raw_mode) { - int started = 0; + bool started = false; ASS_DrawingToken *token; - FT_Vector pen = {0, 0}; + ASS_Vector pen = {0, 0}; drawing->tokens = drawing_tokenize(drawing->text); drawing_prepare(drawing); @@ -324,41 +316,40 @@ ASS_Outline *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode) if (started) { if (!outline_close_contour(&drawing->outline)) goto error; - started = 0; + started = false; } token = token->next; break; case TOKEN_LINE: { - FT_Vector to; - to = token->point; + ASS_Vector to = token->point; translate_point(drawing, &to); if (!started && !outline_add_point(&drawing->outline, pen, FT_CURVE_TAG_ON)) goto error; if (!outline_add_point(&drawing->outline, to, FT_CURVE_TAG_ON)) goto error; - started = 1; + started = true; token = token->next; break; } case TOKEN_CUBIC_BEZIER: if (token_check_values(token, 3, TOKEN_CUBIC_BEZIER) && token->prev) { - if (!drawing_evaluate_curve(drawing, token->prev, 0, started)) + if (!drawing_add_curve(drawing, token->prev, false, started)) goto error; token = token->next; token = token->next; token = token->next; - started = 1; + started = true; } else token = token->next; break; case TOKEN_B_SPLINE: if (token_check_values(token, 3, TOKEN_B_SPLINE) && token->prev) { - if (!drawing_evaluate_curve(drawing, token->prev, 1, started)) + if (!drawing_add_curve(drawing, token->prev, true, started)) goto error; token = token->next; - started = 1; + started = true; } else token = token->next; break; diff --git a/libass/ass_drawing.h b/libass/ass_drawing.h index 28a7040..95e361f 100644 --- a/libass/ass_drawing.h +++ b/libass/ass_drawing.h @@ -19,9 +19,6 @@ #ifndef LIBASS_DRAWING_H #define LIBASS_DRAWING_H -#include -#include FT_OUTLINE_H - #include "ass.h" #include "ass_outline.h" #include "ass_bitmap.h" @@ -39,7 +36,7 @@ typedef enum { typedef struct ass_drawing_token { ASS_TokenType type; - FT_Vector point; + ASS_Vector point; struct ass_drawing_token *next; struct ass_drawing_token *prev; } ASS_DrawingToken; @@ -48,26 +45,26 @@ typedef struct { char *text; // drawing string int scale; // scale (1-64) for subpixel accuracy double pbo; // drawing will be shifted in y direction by this amount - double scale_x; // FontScaleX - double scale_y; // FontScaleY - int asc; // ascender - int desc; // descender + double scale_x; // FontScaleX + double scale_y; // FontScaleY + int asc; // ascender + int desc; // descender ASS_Outline outline; // target outline - FT_Vector advance; // advance (from cbox) - int hash; // hash value (for caching) + ASS_Vector advance; // advance (from cbox) + int hash; // hash value (for caching) // private ASS_Library *library; ASS_DrawingToken *tokens; // tokenized drawing double point_scale_x; double point_scale_y; - FT_BBox cbox; // bounding box, or let's say... VSFilter's idea of it + ASS_Rect cbox; // bounding box, or let's say... VSFilter's idea of it } ASS_Drawing; -ASS_Drawing *ass_drawing_new(ASS_Library *lib, FT_Library ftlib); -void ass_drawing_free(ASS_Drawing* drawing); -void ass_drawing_set_text(ASS_Drawing* drawing, char *str, size_t n); -void ass_drawing_hash(ASS_Drawing* drawing); -ASS_Outline *ass_drawing_parse(ASS_Drawing *drawing, int raw_mode); +ASS_Drawing *ass_drawing_new(ASS_Library *lib); +void ass_drawing_free(ASS_Drawing *drawing); +void ass_drawing_set_text(ASS_Drawing *drawing, char *str, size_t n); +void ass_drawing_hash(ASS_Drawing *drawing); +ASS_Outline *ass_drawing_parse(ASS_Drawing *drawing, bool raw_mode); #endif /* LIBASS_DRAWING_H */ diff --git a/libass/ass_outline.c b/libass/ass_outline.c index 8abc29f..a1dfa1e 100644 --- a/libass/ass_outline.c +++ b/libass/ass_outline.c @@ -27,7 +27,7 @@ bool outline_alloc(ASS_Outline *outline, size_t n_points, size_t n_contours) { outline->contours = malloc(sizeof(size_t) * n_contours); - outline->points = malloc(sizeof(FT_Vector) * n_points); + outline->points = malloc(sizeof(ASS_Vector) * n_points); outline->tags = malloc(n_points); if (!outline->contours || !outline->points || !outline->tags) { outline_free(outline); @@ -65,7 +65,10 @@ bool outline_convert(ASS_Outline *outline, const FT_Outline *source) size_t n = source->contours[i] - start + 1; // skip degenerate 2-point contours from broken fonts if (n >= 3) { - memcpy(outline->points + outline->n_points, source->points + start, sizeof(FT_Vector) * n); + for (size_t k = 0; k < n; k++) { + outline->points[outline->n_points + k].x = source->points[start + k].x; + outline->points[outline->n_points + k].y = source->points[start + k].y; + } memcpy(outline->tags + outline->n_points, source->tags + start, n); outline->n_points += n; @@ -87,7 +90,7 @@ bool outline_copy(ASS_Outline *outline, const ASS_Outline *source) return false; memcpy(outline->contours, source->contours, sizeof(size_t) * source->n_contours); - memcpy(outline->points, source->points, sizeof(FT_Vector) * source->n_points); + memcpy(outline->points, source->points, sizeof(ASS_Vector) * source->n_points); memcpy(outline->tags, source->tags, source->n_points); outline->n_contours = source->n_contours; outline->n_points = source->n_points; @@ -110,7 +113,7 @@ void outline_free(ASS_Outline *outline) /* * \brief Add a single point to a contour. */ -bool outline_add_point(ASS_Outline *outline, FT_Vector pt, char tag) +bool outline_add_point(ASS_Outline *outline, ASS_Vector pt, char tag) { if (outline->n_points >= outline->max_points) { size_t new_size = 2 * outline->max_points; @@ -143,7 +146,7 @@ bool outline_close_contour(ASS_Outline *outline) } -void outline_translate(const ASS_Outline *outline, FT_Pos dx, FT_Pos dy) +void outline_translate(const ASS_Outline *outline, int32_t dx, int32_t dy) { for (size_t i = 0; i < outline->n_points; i++) { outline->points[i].x += dx; @@ -154,42 +157,29 @@ void outline_translate(const ASS_Outline *outline, FT_Pos dx, FT_Pos dy) void outline_transform(const ASS_Outline *outline, const FT_Matrix *matrix) { for (size_t i = 0; i < outline->n_points; i++) { - FT_Pos x = FT_MulFix(outline->points[i].x, matrix->xx) + - FT_MulFix(outline->points[i].y, matrix->xy); - FT_Pos y = FT_MulFix(outline->points[i].x, matrix->yx) + - FT_MulFix(outline->points[i].y, matrix->yy); + int32_t x = FT_MulFix(outline->points[i].x, matrix->xx) + + FT_MulFix(outline->points[i].y, matrix->xy); + int32_t y = FT_MulFix(outline->points[i].x, matrix->yx) + + FT_MulFix(outline->points[i].y, matrix->yy); outline->points[i].x = x; outline->points[i].y = y; } } -void outline_update_cbox(const ASS_Outline *outline, FT_BBox *cbox) -{ - if (!outline) - return; - - for (size_t i = 0; i < outline->n_points; i++) { - cbox->xMin = FFMIN(cbox->xMin, outline->points[i].x); - cbox->xMax = FFMAX(cbox->xMax, outline->points[i].x); - cbox->yMin = FFMIN(cbox->yMin, outline->points[i].y); - cbox->yMax = FFMAX(cbox->yMax, outline->points[i].y); - } -} - -void outline_get_cbox(const ASS_Outline *outline, FT_BBox *cbox) +void outline_get_cbox(const ASS_Outline *outline, ASS_Rect *cbox) { if (!outline->n_points) { - cbox->xMin = cbox->xMax = 0; - cbox->yMin = cbox->yMax = 0; + cbox->x_min = cbox->x_max = 0; + cbox->y_min = cbox->y_max = 0; return; } - cbox->xMin = cbox->xMax = outline->points[0].x; - cbox->yMin = cbox->yMax = outline->points[0].y; + cbox->x_min = cbox->x_max = outline->points[0].x; + cbox->y_min = cbox->y_max = outline->points[0].y; for (size_t i = 1; i < outline->n_points; i++) { - cbox->xMin = FFMIN(cbox->xMin, outline->points[i].x); - cbox->xMax = FFMAX(cbox->xMax, outline->points[i].x); - cbox->yMin = FFMIN(cbox->yMin, outline->points[i].y); - cbox->yMax = FFMAX(cbox->yMax, outline->points[i].y); + cbox->x_min = FFMIN(cbox->x_min, outline->points[i].x); + cbox->x_max = FFMAX(cbox->x_max, outline->points[i].x); + cbox->y_min = FFMIN(cbox->y_min, outline->points[i].y); + cbox->y_max = FFMAX(cbox->y_max, outline->points[i].y); } } @@ -245,15 +235,7 @@ void outline_get_cbox(const ASS_Outline *outline, FT_BBox *cbox) typedef struct { - int32_t x, y; -} OutlinePoint; - -typedef struct { - double x, y; -} Vector; - -typedef struct { - Vector v; + ASS_DVector v; double len; } Normal; @@ -268,9 +250,9 @@ typedef struct { // skip flags for first and last point int first_skip, last_skip; // normal at first and last point - Vector first_normal, last_normal; + ASS_DVector first_normal, last_normal; // first and last point of current contour - OutlinePoint first_point, last_point; + ASS_Vector first_point, last_point; // cosinus of maximal angle that do not require cap double merge_cos; @@ -289,7 +271,7 @@ typedef struct { /** * \brief 2D vector dot product */ -static inline double vec_dot(Vector vec1, Vector vec2) +static inline double vec_dot(ASS_DVector vec1, ASS_DVector vec2) { return vec1.x * vec2.x + vec1.y * vec2.y; } @@ -297,7 +279,7 @@ static inline double vec_dot(Vector vec1, Vector vec2) /** * \brief 2D vector cross product */ -static inline double vec_crs(Vector vec1, Vector vec2) +static inline double vec_crs(ASS_DVector vec1, ASS_DVector vec2) { return vec1.x * vec2.y - vec1.y * vec2.x; } @@ -305,7 +287,7 @@ static inline double vec_crs(Vector vec1, Vector vec2) /** * \brief 2D vector length */ -static inline double vec_len(Vector vec) +static inline double vec_len(ASS_DVector vec) { return sqrt(vec.x * vec.x + vec.y * vec.y); } @@ -320,20 +302,20 @@ static inline double vec_len(Vector vec) * \param dir destination outline flags * \return false on allocation failure */ -static bool emit_point(StrokerState *str, OutlinePoint pt, - Vector offs, char tag, int dir) +static bool emit_point(StrokerState *str, ASS_Vector pt, + ASS_DVector offs, char tag, int dir) { int32_t dx = (int32_t) (str->xbord * offs.x); int32_t dy = (int32_t) (str->ybord * offs.y); if (dir & 1) { - FT_Vector res = { pt.x + dx, pt.y + dy }; + ASS_Vector res = { pt.x + dx, pt.y + dy }; res.y = -res.y; if (!outline_add_point(str->result[0], res, tag)) return false; } if (dir & 2) { - FT_Vector res = { pt.x - dx, pt.y - dy }; + ASS_Vector res = { pt.x - dx, pt.y - dy }; res.y = -res.y; if (!outline_add_point(str->result[1], res, tag)) return false; @@ -348,14 +330,14 @@ static bool emit_point(StrokerState *str, OutlinePoint pt, * \param offs offset in normal space * \param dir destination outline flags */ -static void fix_first_point(StrokerState *str, OutlinePoint pt, - Vector offs, int dir) +static void fix_first_point(StrokerState *str, ASS_Vector pt, + ASS_DVector offs, int dir) { int32_t dx = (int32_t) (str->xbord * offs.x); int32_t dy = (int32_t) (str->ybord * offs.y); if (dir & 1) { - FT_Vector res = { pt.x + dx, pt.y + dy }; + ASS_Vector res = { pt.x + dx, pt.y + dy }; res.y = -res.y; ASS_Outline *ol = str->result[0]; size_t first = ol->n_contours ? @@ -363,7 +345,7 @@ static void fix_first_point(StrokerState *str, OutlinePoint pt, ol->points[first] = res; } if (dir & 2) { - FT_Vector res = { pt.x - dx, pt.y - dy }; + ASS_Vector res = { pt.x - dx, pt.y - dy }; res.y = -res.y; ASS_Outline *ol = str->result[1]; size_t first = ol->n_contours ? @@ -383,11 +365,11 @@ static void fix_first_point(StrokerState *str, OutlinePoint pt, * \param dir destination outline flags * \return false on allocation failure */ -static bool process_arc(StrokerState *str, OutlinePoint pt, - Vector normal0, Vector normal1, +static bool process_arc(StrokerState *str, ASS_Vector pt, + ASS_DVector normal0, ASS_DVector normal1, const double *mul, int level, int dir) { - Vector center; + ASS_DVector center; center.x = (normal0.x + normal1.x) * mul[level]; center.y = (normal0.y + normal1.y) * mul[level]; if (level) @@ -407,13 +389,13 @@ static bool process_arc(StrokerState *str, OutlinePoint pt, * \param dir destination outline flags * \return false on allocation failure */ -static bool draw_arc(StrokerState *str, OutlinePoint pt, - Vector normal0, Vector normal1, double c, int dir) +static bool draw_arc(StrokerState *str, ASS_Vector pt, + ASS_DVector normal0, ASS_DVector normal1, double c, int dir) { const int max_subdiv = 15; double mul[max_subdiv + 1]; - Vector center; + ASS_DVector center; bool small_angle = true; if (c < 0) { double mul = dir & 2 ? -sqrt(0.5) : sqrt(0.5); @@ -444,7 +426,7 @@ static bool draw_arc(StrokerState *str, OutlinePoint pt, * \param dir destination outline flags * \return false on allocation failure */ -static bool draw_circle(StrokerState *str, OutlinePoint pt, int dir) +static bool draw_circle(StrokerState *str, ASS_Vector pt, int dir) { const int max_subdiv = 15; double mul[max_subdiv + 1], c = 0; @@ -457,7 +439,7 @@ static bool draw_circle(StrokerState *str, OutlinePoint pt, int dir) } mul[pos] = 1 / (1 + c); - Vector normal[4] = { + ASS_DVector normal[4] = { { 1, 0 }, { 0, 1 }, { -1, 0 }, { 0, -1 } }; return process_arc(str, pt, normal[0], normal[1], mul + pos, max_subdiv - pos, dir) && @@ -474,8 +456,8 @@ static bool draw_circle(StrokerState *str, OutlinePoint pt, int dir) * \param dir destination outline flags * \return false on allocation failure */ -static bool start_segment(StrokerState *str, OutlinePoint pt, - Vector normal, int dir) +static bool start_segment(StrokerState *str, ASS_Vector pt, + ASS_DVector normal, int dir) { if (str->contour_start) { str->contour_start = false; @@ -485,7 +467,7 @@ static bool start_segment(StrokerState *str, OutlinePoint pt, return true; } - Vector prev = str->last_normal; + ASS_DVector prev = str->last_normal; double c = vec_dot(prev, normal); if (c > str->merge_cos) { // merge without cap double mul = 1 / (1 + c); @@ -501,7 +483,7 @@ static bool start_segment(StrokerState *str, OutlinePoint pt, if (dir & skip_dir) { if (!emit_point(str, pt, prev, FT_CURVE_TAG_ON, ~str->last_skip & skip_dir)) return false; - Vector zero_normal = {0, 0}; + ASS_DVector zero_normal = {0, 0}; if (!emit_point(str, pt, zero_normal, FT_CURVE_TAG_ON, skip_dir)) return false; } @@ -514,7 +496,7 @@ static bool start_segment(StrokerState *str, OutlinePoint pt, /** * \brief Same as emit_point() but also updates skip flags */ -static bool emit_first_point(StrokerState *str, OutlinePoint pt, int dir) +static bool emit_first_point(StrokerState *str, ASS_Vector pt, int dir) { str->last_skip &= ~dir; return emit_point(str, pt, str->last_normal, FT_CURVE_TAG_ON, dir); @@ -528,7 +510,7 @@ static bool emit_first_point(StrokerState *str, OutlinePoint pt, int dir) * \param first true if the skipped part is at start of the segment * \return false on allocation failure */ -static bool prepare_skip(StrokerState *str, OutlinePoint pt, int dir, bool first) +static bool prepare_skip(StrokerState *str, ASS_Vector pt, int dir, bool first) { if (first) str->first_skip |= dir; @@ -545,16 +527,16 @@ static bool prepare_skip(StrokerState *str, OutlinePoint pt, int dir, bool first * \param dir destination outline flags * \return false on allocation failure */ -static bool add_line(StrokerState *str, OutlinePoint pt, int dir) +static bool add_line(StrokerState *str, ASS_Vector pt, int dir) { int32_t dx = pt.x - str->last_point.x; int32_t dy = pt.y - str->last_point.y; if (dx > -str->eps && dx < str->eps && dy > -str->eps && dy < str->eps) return true; - Vector deriv = { dy * str->yscale, -dx * str->xscale }; + ASS_DVector deriv = { dy * str->yscale, -dx * str->xscale }; double scale = 1 / vec_len(deriv); - Vector normal = { deriv.x * scale, deriv.y * scale }; + ASS_DVector normal = { deriv.x * scale, deriv.y * scale }; if (!start_segment(str, str->last_point, normal, dir)) return false; if (!emit_first_point(str, str->last_point, dir)) @@ -575,7 +557,7 @@ static bool add_line(StrokerState *str, OutlinePoint pt, int dir) * \return false if error is too large */ static bool estimate_quadratic_error(StrokerState *str, double c, double s, - const Normal *normal, Vector *result) + const Normal *normal, ASS_DVector *result) { // check radial error if (!((3 + c) * (3 + c) < str->err_q * (1 + c))) @@ -604,8 +586,8 @@ static bool estimate_quadratic_error(StrokerState *str, double c, double s, * \param first true if the current part is at start of the segment * \return false on allocation failure */ -static bool process_quadratic(StrokerState *str, const OutlinePoint *pt, - const Vector *deriv, const Normal *normal, +static bool process_quadratic(StrokerState *str, const ASS_Vector *pt, + const ASS_DVector *deriv, const Normal *normal, int dir, bool first) { double c = vec_dot(normal[0].v, normal[1].v); @@ -624,13 +606,13 @@ static bool process_quadratic(StrokerState *str, const OutlinePoint *pt, if (!prepare_skip(str, pt[0], skip_dir, first)) return false; if (f0 < 0 || f1 < 0) { - Vector zero_normal = {0, 0}; + ASS_DVector zero_normal = {0, 0}; if (!emit_point(str, pt[0], zero_normal, FT_CURVE_TAG_ON, skip_dir) || !emit_point(str, pt[2], zero_normal, FT_CURVE_TAG_ON, skip_dir)) return false; } else { double mul = f0 / abs_s; - Vector offs = { normal[0].v.x * mul, normal[0].v.y * mul }; + ASS_DVector offs = { normal[0].v.x * mul, normal[0].v.y * mul }; if (!emit_point(str, pt[0], offs, FT_CURVE_TAG_ON, skip_dir)) return false; } @@ -645,7 +627,7 @@ static bool process_quadratic(StrokerState *str, const OutlinePoint *pt, check_dir ^= skip_dir; } - Vector result; + ASS_DVector result; if (check_dir && estimate_quadratic_error(str, c, s, normal, &result)) { if (!emit_first_point(str, pt[0], check_dir)) return false; @@ -658,7 +640,7 @@ static bool process_quadratic(StrokerState *str, const OutlinePoint *pt, } } - OutlinePoint next[5]; + ASS_Vector next[5]; next[1].x = pt[0].x + pt[1].x; next[1].y = pt[0].y + pt[1].y; next[3].x = pt[1].x + pt[2].x; @@ -672,7 +654,7 @@ static bool process_quadratic(StrokerState *str, const OutlinePoint *pt, next[0] = pt[0]; next[4] = pt[2]; - Vector next_deriv[3]; + ASS_DVector next_deriv[3]; next_deriv[0].x = deriv[0].x / 2; next_deriv[0].y = deriv[0].y / 2; next_deriv[2].x = deriv[1].x / 2; @@ -707,7 +689,7 @@ static bool process_quadratic(StrokerState *str, const OutlinePoint *pt, * \param dir destination outline flags * \return false on allocation failure */ -static bool add_quadratic(StrokerState *str, const OutlinePoint *pt, int dir) +static bool add_quadratic(StrokerState *str, const ASS_Vector *pt, int dir) { int32_t dx0 = pt[1].x - pt[0].x; int32_t dy0 = pt[1].y - pt[0].y; @@ -719,7 +701,7 @@ static bool add_quadratic(StrokerState *str, const OutlinePoint *pt, int dir) if (dx1 > -str->eps && dx1 < str->eps && dy1 > -str->eps && dy1 < str->eps) return add_line(str, pt[2], dir); - Vector deriv[2] = { + ASS_DVector deriv[2] = { { dy0 * str->yscale, -dx0 * str->xscale }, { dy1 * str->yscale, -dx1 * str->xscale } }; @@ -770,7 +752,7 @@ enum { */ static int estimate_cubic_error(StrokerState *str, double c, double s, const double *dc, const double *ds, - const Normal *normal, Vector *result, + const Normal *normal, ASS_DVector *result, int check_flags, int dir) { double t = (ds[0] + ds[1]) / (dc[0] + dc[1]), c1 = 1 + c, ss = s * s; @@ -871,8 +853,8 @@ static int estimate_cubic_error(StrokerState *str, double c, double s, * \param first true if the current part is at start of the segment * \return false on allocation failure */ -static bool process_cubic(StrokerState *str, const OutlinePoint *pt, - const Vector *deriv, const Normal *normal, +static bool process_cubic(StrokerState *str, const ASS_Vector *pt, + const ASS_DVector *deriv, const Normal *normal, int dir, bool first) { double c = vec_dot(normal[0].v, normal[1].v); @@ -910,13 +892,13 @@ static bool process_cubic(StrokerState *str, const OutlinePoint *pt, if (!prepare_skip(str, pt[0], skip_dir, first)) return false; if (f0 < 0 || f1 < 0) { - Vector zero_normal = {0, 0}; + ASS_DVector zero_normal = {0, 0}; if (!emit_point(str, pt[0], zero_normal, FT_CURVE_TAG_ON, skip_dir) || !emit_point(str, pt[3], zero_normal, FT_CURVE_TAG_ON, skip_dir)) return false; } else { double mul = f0 / abs_s; - Vector offs = { normal[0].v.x * mul, normal[0].v.y * mul }; + ASS_DVector offs = { normal[0].v.x * mul, normal[0].v.y * mul }; if (!emit_point(str, pt[0], offs, FT_CURVE_TAG_ON, skip_dir)) return false; } @@ -974,7 +956,7 @@ static bool process_cubic(StrokerState *str, const OutlinePoint *pt, } } - Vector result[2]; + ASS_DVector result[2]; if (check_dir) check_dir = estimate_cubic_error(str, c, s, dc, ds, normal, result, flags, check_dir); @@ -991,7 +973,7 @@ static bool process_cubic(StrokerState *str, const OutlinePoint *pt, } } - OutlinePoint next[7], center; + ASS_Vector next[7], center; next[1].x = pt[0].x + pt[1].x; next[1].y = pt[0].y + pt[1].y; center.x = pt[1].x + pt[2].x + 2; @@ -1015,7 +997,7 @@ static bool process_cubic(StrokerState *str, const OutlinePoint *pt, next[0] = pt[0]; next[6] = pt[3]; - Vector next_deriv[5], center_deriv; + ASS_DVector next_deriv[5], center_deriv; next_deriv[0].x = deriv[0].x / 2; next_deriv[0].y = deriv[0].y / 2; center_deriv.x = deriv[1].x / 2; @@ -1099,7 +1081,7 @@ static bool process_cubic(StrokerState *str, const OutlinePoint *pt, * \param dir destination outline flags * \return false on allocation failure */ -static bool add_cubic(StrokerState *str, const OutlinePoint *pt, int dir) +static bool add_cubic(StrokerState *str, const ASS_Vector *pt, int dir) { int flags = 9; @@ -1129,7 +1111,7 @@ static bool add_cubic(StrokerState *str, const OutlinePoint *pt, int dir) int32_t dx1 = pt[flags >> 2].x - pt[flags & 3].x; int32_t dy1 = pt[flags >> 2].y - pt[flags & 3].y; - Vector deriv[3] = { + ASS_DVector deriv[3] = { { dy0 * str->yscale, -dx0 * str->xscale }, { dy1 * str->yscale, -dx1 * str->xscale }, { dy2 * str->yscale, -dx2 * str->xscale } @@ -1230,7 +1212,7 @@ bool outline_stroke(ASS_Outline *result, ASS_Outline *result1, const int dir = 3; for (size_t i = 0, j = 0; i < path->n_contours; i++) { - OutlinePoint start, p[4]; + ASS_Vector start, p[4]; int process_end = 1; enum Status st; diff --git a/libass/ass_outline.h b/libass/ass_outline.h index 0a1b8ec..7e71b8a 100644 --- a/libass/ass_outline.h +++ b/libass/ass_outline.h @@ -22,13 +22,26 @@ #include #include FT_OUTLINE_H #include +#include +typedef struct { + int32_t x, y; +} ASS_Vector; + +typedef struct { + double x, y; +} ASS_DVector; + +typedef struct { + int32_t x_min, y_min, x_max, y_max; +} ASS_Rect; + typedef struct ass_outline { size_t n_contours, max_contours; size_t *contours; size_t n_points, max_points; - FT_Vector *points; + ASS_Vector *points; char *tags; } ASS_Outline; @@ -37,13 +50,12 @@ bool outline_convert(ASS_Outline *outline, const FT_Outline *source); bool outline_copy(ASS_Outline *outline, const ASS_Outline *source); void outline_free(ASS_Outline *outline); -bool outline_add_point(ASS_Outline *outline, FT_Vector pt, char tag); +bool outline_add_point(ASS_Outline *outline, ASS_Vector pt, char tag); bool outline_close_contour(ASS_Outline *outline); -void outline_translate(const ASS_Outline *outline, FT_Pos dx, FT_Pos dy); -void outline_transform(const ASS_Outline *outline, const FT_Matrix *matrix); -void outline_update_cbox(const ASS_Outline *outline, FT_BBox *cbox); -void outline_get_cbox(const ASS_Outline *outline, FT_BBox *cbox); +void outline_translate(const ASS_Outline *outline, int32_t dx, int32_t dy); +void outline_transform(const ASS_Outline *outline, const FT_Matrix *matrix); // XXX: replace with outline_scale +void outline_get_cbox(const ASS_Outline *outline, ASS_Rect *cbox); bool outline_stroke(ASS_Outline *result, ASS_Outline *result1, const ASS_Outline *path, int xbord, int ybord, int eps); diff --git a/libass/ass_parse.c b/libass/ass_parse.c index 80d4bfc..c83634a 100644 --- a/libass/ass_parse.c +++ b/libass/ass_parse.c @@ -211,8 +211,7 @@ static int parse_vector_clip(ASS_Renderer *render_priv, struct arg text = args[nargs - 1]; ass_drawing_free(drawing); - render_priv->state.clip_drawing = - ass_drawing_new(render_priv->library, render_priv->ftlibrary); + render_priv->state.clip_drawing = ass_drawing_new(render_priv->library); drawing = render_priv->state.clip_drawing; if (drawing) { drawing->scale = scale; @@ -957,8 +956,8 @@ void process_karaoke_effects(ASS_Renderer *render_priv) x_start = 1000000; x_end = -1000000; for (cur2 = s1; cur2 <= e1; ++cur2) { - x_start = FFMIN(x_start, d6_to_int(cur2->bbox.xMin + cur2->pos.x)); - x_end = FFMAX(x_end, d6_to_int(cur2->bbox.xMax + cur2->pos.x)); + x_start = FFMIN(x_start, d6_to_int(cur2->bbox.x_min + cur2->pos.x)); + x_end = FFMAX(x_end, d6_to_int(cur2->bbox.x_max + cur2->pos.x)); } dt = (tm_current - tm_start); diff --git a/libass/ass_rasterizer.c b/libass/ass_rasterizer.c index 735627c..8234f07 100644 --- a/libass/ass_rasterizer.c +++ b/libass/ass_rasterizer.c @@ -117,18 +117,14 @@ void rasterizer_done(RasterizerData *rst) */ -typedef struct { - int32_t x, y; -} OutlinePoint; - // Helper struct for spline split decision typedef struct { - OutlinePoint r; + ASS_Vector r; int64_t r2, er; } OutlineSegment; static inline void segment_init(OutlineSegment *seg, - OutlinePoint beg, OutlinePoint end, + ASS_Vector beg, ASS_Vector end, int32_t outline_error) { int32_t x = end.x - beg.x; @@ -143,7 +139,7 @@ static inline void segment_init(OutlineSegment *seg, } static inline bool segment_subdivide(const OutlineSegment *seg, - OutlinePoint beg, OutlinePoint pt) + ASS_Vector beg, ASS_Vector pt) { int32_t x = pt.x - beg.x; int32_t y = pt.y - beg.y; @@ -156,7 +152,7 @@ static inline bool segment_subdivide(const OutlineSegment *seg, /** * \brief Add new segment to polyline */ -static bool add_line(RasterizerData *rst, OutlinePoint pt0, OutlinePoint pt1) +static bool add_line(RasterizerData *rst, ASS_Vector pt0, ASS_Vector pt1) { int32_t x = pt1.x - pt0.x; int32_t y = pt1.y - pt0.y; @@ -203,14 +199,14 @@ static bool add_line(RasterizerData *rst, OutlinePoint pt0, OutlinePoint pt1) * \brief Add quadratic spline to polyline * Performs recursive subdivision if necessary. */ -static bool add_quadratic(RasterizerData *rst, const OutlinePoint *pt) +static bool add_quadratic(RasterizerData *rst, const ASS_Vector *pt) { OutlineSegment seg; segment_init(&seg, pt[0], pt[2], rst->outline_error); if (!segment_subdivide(&seg, pt[0], pt[1])) return add_line(rst, pt[0], pt[2]); - OutlinePoint next[5]; + ASS_Vector next[5]; next[1].x = pt[0].x + pt[1].x; next[1].y = pt[0].y + pt[1].y; next[3].x = pt[1].x + pt[2].x; @@ -230,14 +226,14 @@ static bool add_quadratic(RasterizerData *rst, const OutlinePoint *pt) * \brief Add cubic spline to polyline * Performs recursive subdivision if necessary. */ -static bool add_cubic(RasterizerData *rst, const OutlinePoint *pt) +static bool add_cubic(RasterizerData *rst, const ASS_Vector *pt) { OutlineSegment seg; segment_init(&seg, pt[0], pt[3], rst->outline_error); if (!segment_subdivide(&seg, pt[0], pt[1]) && !segment_subdivide(&seg, pt[0], pt[2])) return add_line(rst, pt[0], pt[3]); - OutlinePoint next[7], center; + ASS_Vector next[7], center; next[1].x = pt[0].x + pt[1].x; next[1].y = pt[0].y + pt[1].y; center.x = pt[1].x + pt[2].x + 2; @@ -278,7 +274,7 @@ bool rasterizer_set_outline(RasterizerData *rst, } rst->size[0] = rst->n_first; for (size_t i = 0, j = 0; i < path->n_contours; i++) { - OutlinePoint start, p[4]; + ASS_Vector start, p[4]; int process_end = 1; enum Status st; diff --git a/libass/ass_render.c b/libass/ass_render.c index 5cce4d9..7ff1db8 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -485,7 +485,7 @@ static void blend_vector_clip(ASS_Renderer *render_priv, // We need to translate the clip according to screen borders if (render_priv->settings.left_margin != 0 || render_priv->settings.top_margin != 0) { - FT_Vector trans = { + ASS_Vector trans = { .x = int_to_d6(render_priv->settings.left_margin), .y = -int_to_d6(render_priv->settings.top_margin), }; @@ -917,7 +917,7 @@ static void free_render_context(ASS_Renderer *render_priv) */ static void draw_opaque_box(ASS_Renderer *render_priv, GlyphInfo *info, int asc, int desc, ASS_Outline *ol, - FT_Vector advance, int sx, int sy) + ASS_Vector advance, int sx, int sy) { int adv = advance.x; double scale_y = info->orig_scale_y; @@ -936,7 +936,7 @@ static void draw_opaque_box(ASS_Renderer *render_priv, GlyphInfo *info, desc *= scale_y; desc += asc * (scale_y - 1.0); - FT_Vector points[4] = { + ASS_Vector points[4] = { { .x = -sx, .y = asc + sy }, { .x = adv + sx, .y = asc + sy }, { .x = adv + sx, .y = -desc - sy }, @@ -948,7 +948,7 @@ static void draw_opaque_box(ASS_Renderer *render_priv, GlyphInfo *info, return; for (int i = 0; i < 4; ++i) { ol->points[ol->n_points] = points[i]; - ol->tags[ol->n_points++] = 1; + ol->tags[ol->n_points++] = FT_CURVE_TAG_ON; } ol->contours[ol->n_contours++] = ol->n_points - 1; } @@ -1072,7 +1072,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info) outline_get_cbox(&val->outline, &val->bbox_scaled); if (info->border_style == 3) { - FT_Vector advance; + ASS_Vector advance; if (priv->settings.shaper == ASS_SHAPING_SIMPLE || info->drawing) advance = val->advance; else @@ -1125,7 +1125,7 @@ get_outline_glyph(ASS_Renderer *priv, GlyphInfo *info) * onto the screen plane. */ static void -transform_3d_points(FT_Vector shift, ASS_Outline *outline, double frx, double fry, +transform_3d_points(ASS_Vector shift, ASS_Outline *outline, double frx, double fry, double frz, double fax, double fay, double scale, int yshift) { @@ -1135,7 +1135,7 @@ transform_3d_points(FT_Vector shift, ASS_Outline *outline, double frx, double fr double cx = cos(frx); double cy = cos(fry); double cz = cos(frz); - FT_Vector *p = outline->points; + ASS_Vector *p = outline->points; double x, y, z, xx, yy, zz; int dist; @@ -1177,7 +1177,7 @@ transform_3d_points(FT_Vector shift, ASS_Outline *outline, double frx, double fr * Rotates both glyphs by frx, fry and frz. Shift vector is added before rotation and subtracted after it. */ static void -transform_3d(FT_Vector shift, ASS_Outline *outline, int n_outlines, +transform_3d(ASS_Vector shift, ASS_Outline *outline, int n_outlines, double frx, double fry, double frz, double fax, double fay, double scale, int yshift) { @@ -1230,7 +1230,7 @@ get_bitmap_glyph(ASS_Renderer *render_priv, GlyphInfo *info) outline_copy(&outline[2], info->border[1]); // calculating rotation shift vector (from rotation origin to the glyph basepoint) - FT_Vector shift = { key->shift_x, key->shift_y }; + ASS_Vector shift = { key->shift_x, key->shift_y }; double scale_x = render_priv->font_scale_x; double fax_scaled = info->fax / info->scale_y * info->scale_x; double fay_scaled = info->fay / info->scale_x * info->scale_y; @@ -1402,8 +1402,8 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width) int break_at = -1; double s_offset, len; cur = text_info->glyphs + i; - s_offset = d6_to_double(s1->bbox.xMin + s1->pos.x); - len = d6_to_double(cur->bbox.xMax + cur->pos.x) - s_offset; + s_offset = d6_to_double(s1->bbox.x_min + s1->pos.x); + len = d6_to_double(cur->bbox.x_max + cur->pos.x) - s_offset; if (cur->symbol == '\n') { break_type = 2; @@ -1469,16 +1469,16 @@ wrap_lines_smart(ASS_Renderer *render_priv, double max_text_width) if (w->symbol == ' ') ++w; - l1 = d6_to_double(((s2 - 1)->bbox.xMax + (s2 - 1)->pos.x) - - (s1->bbox.xMin + s1->pos.x)); - l2 = d6_to_double(((s3 - 1)->bbox.xMax + (s3 - 1)->pos.x) - - (s2->bbox.xMin + s2->pos.x)); + l1 = d6_to_double(((s2 - 1)->bbox.x_max + (s2 - 1)->pos.x) - + (s1->bbox.x_min + s1->pos.x)); + l2 = d6_to_double(((s3 - 1)->bbox.x_max + (s3 - 1)->pos.x) - + (s2->bbox.x_min + s2->pos.x)); l1_new = d6_to_double( - (e1->bbox.xMax + e1->pos.x) - - (s1->bbox.xMin + s1->pos.x)); + (e1->bbox.x_max + e1->pos.x) - + (s1->bbox.x_min + s1->pos.x)); l2_new = d6_to_double( - ((s3 - 1)->bbox.xMax + (s3 - 1)->pos.x) - - (w->bbox.xMin + w->pos.x)); + ((s3 - 1)->bbox.x_max + (s3 - 1)->pos.x) - + (w->bbox.x_min + w->pos.x)); if (DIFF(l1_new, l2_new) < DIFF(l1, l2)) { if (w->linebreak || w == text_info->glyphs) @@ -1719,8 +1719,7 @@ static int parse_events(ASS_Renderer *render_priv, ASS_Event *event) while ((*q != '{') && (*q != 0)) q++; if (!drawing) { - drawing = ass_drawing_new(render_priv->library, - render_priv->ftlibrary); + drawing = ass_drawing_new(render_priv->library); if (!drawing) return 1; } @@ -1840,11 +1839,11 @@ static void retrieve_glyphs(ASS_Renderer *render_priv) if (i && glyphs[i - 1].italic && !info->italic) { int back = i - 1; GlyphInfo *og = &glyphs[back]; - while (back && og->bbox.xMax - og->bbox.xMin == 0 + while (back && og->bbox.x_max - og->bbox.x_min == 0 && og->italic) og = &glyphs[--back]; - if (og->bbox.xMax > og->cluster_advance.x) - og->cluster_advance.x = og->bbox.xMax; + if (og->bbox.x_max > og->cluster_advance.x) + og->cluster_advance.x = og->bbox.x_max; } // add horizontal letter spacing @@ -1859,14 +1858,10 @@ static void retrieve_glyphs(ASS_Renderer *render_priv) // Preliminary layout (for line wrapping) static void preliminary_layout(ASS_Renderer *render_priv) { - FT_Vector pen; - int i; - - pen.x = 0; - pen.y = 0; - for (i = 0; i < render_priv->text_info.length; i++) { + ASS_Vector pen = { 0, 0 }; + for (int i = 0; i < render_priv->text_info.length; i++) { GlyphInfo *info = render_priv->text_info.glyphs + i; - FT_Vector cluster_pen = pen; + ASS_Vector cluster_pen = pen; while (info) { info->pos.x = cluster_pen.x; info->pos.y = cluster_pen.y; @@ -1890,9 +1885,6 @@ static void preliminary_layout(ASS_Renderer *render_priv) static void reorder_text(ASS_Renderer *render_priv) { TextInfo *text_info = &render_priv->text_info; - FT_Vector pen; - int i; - FriBidiStrIndex *cmap = ass_shaper_reorder(render_priv->shaper, text_info); if (!cmap) { ass_msg(render_priv->library, MSGL_ERR, "Failed to reorder text"); @@ -1902,12 +1894,11 @@ static void reorder_text(ASS_Renderer *render_priv) } // Reposition according to the map - pen.x = 0; - pen.y = 0; + ASS_Vector pen = { 0, 0 }; int lineno = 1; double last_pen_x = 0; double last_fay = 0; - for (i = 0; i < text_info->length; i++) { + for (int i = 0; i < text_info->length; i++) { GlyphInfo *info = text_info->glyphs + cmap[i]; if (text_info->glyphs[i].linebreak) { pen.y -= (last_fay / info->scale_x * info->scale_y) * (pen.x - last_pen_x); @@ -1923,7 +1914,7 @@ static void reorder_text(ASS_Renderer *render_priv) } last_fay = info->fay; if (info->skip) continue; - FT_Vector cluster_pen = pen; + ASS_Vector cluster_pen = pen; while (info) { info->pos.x = info->offset.x + cluster_pen.x; info->pos.y = info->offset.y + cluster_pen.y; @@ -2010,7 +2001,7 @@ static void calculate_rotation_params(ASS_Renderer *render_priv, DBBox *bbox, double device_x, double device_y) { TextInfo *text_info = &render_priv->text_info; - DVector center; + ASS_DVector center; int i; if (render_priv->state.have_origin) { @@ -2041,13 +2032,13 @@ static void calculate_rotation_params(ASS_Renderer *render_priv, DBBox *bbox, } -static inline void rectangle_reset(Rectangle *rect) +static inline void rectangle_reset(ASS_Rect *rect) { - rect->x_min = rect->y_min = INT_MAX; - rect->x_max = rect->y_max = INT_MIN; + rect->x_min = rect->y_min = INT32_MAX; + rect->x_max = rect->y_max = INT32_MIN; } -static inline void rectangle_combine(Rectangle *rect, const Bitmap *bm, int x, int y) +static inline void rectangle_combine(ASS_Rect *rect, const Bitmap *bm, int x, int y) { rect->x_min = FFMIN(rect->x_min, x + bm->left); rect->y_min = FFMIN(rect->y_min, y + bm->top); @@ -2102,7 +2093,7 @@ static void render_and_combine_glyphs(ASS_Renderer *render_priv, memcpy(¤t_info->c, &info->c, sizeof(info->c)); current_info->effect_type = info->effect_type; current_info->effect_timing = info->effect_timing; - current_info->first_pos_x = info->bbox.xMax >> 6; + current_info->first_pos_x = info->bbox.x_max >> 6; current_info->filter.flags = 0; if (info->border_style == 3) diff --git a/libass/ass_render.h b/libass/ass_render.h index 8731a96..d6fe61d 100644 --- a/libass/ass_render.h +++ b/libass/ass_render.h @@ -56,11 +56,6 @@ typedef struct { double yMax; } DBBox; -typedef struct { - double x; - double y; -} DVector; - typedef struct { ASS_Image result; CompositeHashValue *source; @@ -106,11 +101,6 @@ typedef enum { EF_KARAOKE_KO } Effect; -typedef struct -{ - int x_min, y_min, x_max, y_max; -} Rectangle; - // describes a combined bitmap typedef struct { FilterDesc filter; @@ -126,7 +116,7 @@ typedef struct { BitmapRef *bitmaps; int x, y; - Rectangle rect, rect_o; + ASS_Rect rect, rect_o; size_t n_bm, n_bm_o; Bitmap *bm, *bm_o, *bm_s; // glyphs, outline, shadow bitmaps @@ -150,13 +140,13 @@ typedef struct glyph_info { ASS_Drawing *drawing; ASS_Outline *outline; ASS_Outline *border[2]; - FT_BBox bbox; - FT_Vector pos; - FT_Vector offset; + ASS_Rect bbox; + ASS_Vector pos; + ASS_Vector offset; char linebreak; // the first (leading) glyph of some line ? uint32_t c[4]; // colors - FT_Vector advance; // 26.6 - FT_Vector cluster_advance; + ASS_Vector advance; // 26.6 + ASS_Vector cluster_advance; char effect; // the first (leading) glyph of some effect ? Effect effect_type; int effect_timing; // time duration of current karaoke word