From 5807c1aafbe3276cced4264479a9acf789d4d130 Mon Sep 17 00:00:00 2001 From: "Dr.Smile" Date: Mon, 31 Jul 2017 05:15:13 +0300 Subject: cosmetic: extract most of the outline-related functions into separate file --- libass/Makefile.am | 4 +- libass/ass_bitmap.c | 1 + libass/ass_bitmap.h | 10 +- libass/ass_cache.c | 1 + libass/ass_drawing.h | 1 + libass/ass_font.c | 251 ------------------------------------------- libass/ass_font.h | 9 -- libass/ass_outline.c | 275 ++++++++++++++++++++++++++++++++++++++++++++++++ libass/ass_outline.h | 49 +++++++++ libass/ass_rasterizer.c | 7 +- libass/ass_rasterizer.h | 1 - libass/ass_render.c | 1 + 12 files changed, 335 insertions(+), 275 deletions(-) create mode 100644 libass/ass_outline.c create mode 100644 libass/ass_outline.h diff --git a/libass/Makefile.am b/libass/Makefile.am index a073f26..3579310 100644 --- a/libass/Makefile.am +++ b/libass/Makefile.am @@ -25,8 +25,8 @@ SRC_CORETEXT = ass_coretext.c ass_coretext.h lib_LTLIBRARIES = libass.la libass_la_SOURCES = ass.c ass_cache.c ass_font.c ass_fontselect.c ass_render.c \ - ass_utils.c ass_bitmap.c ass_blur.c ass_library.c ass_bitmap.h \ - ass_cache.h ass_fontselect.h ass_font.h ass.h \ + ass_utils.c ass_bitmap.c ass_outline.c ass_blur.c ass_library.c \ + ass_bitmap.h ass_outline.h ass_cache.h ass_fontselect.h ass_font.h ass.h \ ass_library.h ass_types.h ass_utils.h ass_drawing.c \ ass_drawing.h ass_cache_template.h ass_render.h \ ass_parse.c ass_parse.h ass_render_api.c ass_shaper.c \ diff --git a/libass/ass_bitmap.c b/libass/ass_bitmap.c index ff2eac4..40d5eb4 100644 --- a/libass/ass_bitmap.c +++ b/libass/ass_bitmap.c @@ -31,6 +31,7 @@ #include FT_OUTLINE_H #include "ass_utils.h" +#include "ass_outline.h" #include "ass_bitmap.h" #include "ass_render.h" diff --git a/libass/ass_bitmap.h b/libass/ass_bitmap.h index ada3228..eb58f94 100644 --- a/libass/ass_bitmap.h +++ b/libass/ass_bitmap.h @@ -90,15 +90,7 @@ extern const BitmapEngine ass_bitmap_engine_sse2; extern const BitmapEngine ass_bitmap_engine_avx2; -typedef struct { - size_t n_contours, max_contours; - size_t *contours; - size_t n_points, max_points; - FT_Vector *points; - char *tags; -} ASS_Outline; - -#define EFFICIENT_CONTOUR_COUNT 8 +typedef struct ass_outline ASS_Outline; typedef struct { int left, top; diff --git a/libass/ass_cache.c b/libass/ass_cache.c index 148faa1..577f7f3 100644 --- a/libass/ass_cache.c +++ b/libass/ass_cache.c @@ -27,6 +27,7 @@ #include "ass_utils.h" #include "ass_font.h" +#include "ass_outline.h" #include "ass_cache.h" // type-specific functions diff --git a/libass/ass_drawing.h b/libass/ass_drawing.h index 4d63201..28a7040 100644 --- a/libass/ass_drawing.h +++ b/libass/ass_drawing.h @@ -23,6 +23,7 @@ #include FT_OUTLINE_H #include "ass.h" +#include "ass_outline.h" #include "ass_bitmap.h" typedef enum { diff --git a/libass/ass_font.c b/libass/ass_font.c index 5889b49..95ae335 100644 --- a/libass/ass_font.c +++ b/libass/ass_font.c @@ -436,77 +436,6 @@ static int ass_strike_outline_glyph(FT_Face face, ASS_Font *font, return 0; } - -int 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->tags = malloc(n_points); - if (!outline->contours || !outline->points || !outline->tags) - return 0; - - outline->max_contours = n_contours; - outline->max_points = n_points; - return 1; -} - -ASS_Outline *outline_convert(const FT_Outline *source) -{ - if (!source) - return NULL; - - ASS_Outline *ol = calloc(1, sizeof(*ol)); - if (!ol) - return NULL; - - if (!outline_alloc(ol, source->n_points, source->n_contours)) { - outline_free(ol); - free(ol); - return NULL; - } - - for (int i = 0; i < source->n_contours; ++i) - ol->contours[i] = source->contours[i]; - memcpy(ol->points, source->points, sizeof(FT_Vector) * source->n_points); - memcpy(ol->tags, source->tags, source->n_points); - ol->n_contours = source->n_contours; - ol->n_points = source->n_points; - return ol; -} - -ASS_Outline *outline_copy(const ASS_Outline *source) -{ - if (!source) - return NULL; - - ASS_Outline *ol = calloc(1, sizeof(*ol)); - if (!ol) - return NULL; - - if (!outline_alloc(ol, source->n_points, source->n_contours)) { - outline_free(ol); - free(ol); - return NULL; - } - - memcpy(ol->contours, source->contours, sizeof(size_t) * source->n_contours); - memcpy(ol->points, source->points, sizeof(FT_Vector) * source->n_points); - memcpy(ol->tags, source->tags, source->n_points); - ol->n_contours = source->n_contours; - ol->n_points = source->n_points; - return ol; -} - -void outline_free(ASS_Outline *outline) -{ - if (!outline) - return; - - free(outline->contours); - free(outline->points); - free(outline->tags); -} - /** * Slightly embold a glyph without touching its metrics */ @@ -693,183 +622,3 @@ void ass_font_clear(ASS_Font *font) } free(font->desc.family); } - -/** - * \brief Calculate the cbox of a series of points - */ -static void -get_contour_cbox(FT_BBox *box, FT_Vector *points, int start, int end) -{ - box->xMin = box->yMin = INT_MAX; - box->xMax = box->yMax = INT_MIN; - int i; - - for (i = start; i <= end; i++) { - box->xMin = (points[i].x < box->xMin) ? points[i].x : box->xMin; - box->xMax = (points[i].x > box->xMax) ? points[i].x : box->xMax; - box->yMin = (points[i].y < box->yMin) ? points[i].y : box->yMin; - box->yMax = (points[i].y > box->yMax) ? points[i].y : box->yMax; - } -} - -/** - * \brief Determine signed area of a contour - * \return area doubled - */ -static long long get_contour_area(FT_Vector *points, int start, int end) -{ - long long area = 0; - int x = points[end].x; - int y = points[end].y; - for (int i = start; i <= end; i++) { - area += (long long)(points[i].x + x) * (points[i].y - y); - x = points[i].x; - y = points[i].y; - } - return area; -} - -void outline_translate(const ASS_Outline *outline, FT_Pos dx, FT_Pos dy) -{ - for (size_t i = 0; i < outline->n_points; ++i) { - outline->points[i].x += dx; - outline->points[i].y += 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); - outline->points[i].x = x; - outline->points[i].y = y; - } -} - -void outline_get_cbox(const ASS_Outline *outline, FT_BBox *cbox) -{ - if (!outline->n_points) { - cbox->xMin = cbox->xMax = 0; - cbox->yMin = cbox->yMax = 0; - return; - } - cbox->xMin = cbox->xMax = outline->points[0].x; - cbox->yMin = cbox->yMax = 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); - } -} - -/** - * \brief Apply fixups to please the FreeType stroker and improve the - * rendering result, especially in case the outline has some anomalies. - * At the moment, the following fixes are done: - * - * 1. Reverse contours that have "inside" winding direction but are not - * contained in any other contours' cbox. - * 2. Remove "inside" contours depending on border size, so that large - * borders do not reverse the winding direction, which leads to "holes" - * inside the border. The inside will be filled by the border of the - * outside contour anyway in this case. - * - * \param outline FreeType outline, modified in-place - * \param border_x border size, x direction, d6 format - * \param border_x border size, y direction, d6 format - */ -void fix_freetype_stroker(ASS_Outline *outline, int border_x, int border_y) -{ - int nc = outline->n_contours; - int begin, stop; - char modified = 0; - char *valid_cont = malloc(nc); - int start = 0; - int end = -1; - FT_BBox *boxes = malloc(nc * sizeof(FT_BBox)); - int i, j; - - long long area = 0; - // create a list of cboxes of the contours - for (i = 0; i < nc; i++) { - start = end + 1; - end = outline->contours[i]; - get_contour_cbox(&boxes[i], outline->points, start, end); - area += get_contour_area(outline->points, start, end); - } - int inside_direction = area < 0; - - // for each contour, check direction and whether it's "outside" - // or contained in another contour - end = -1; - for (i = 0; i < nc; i++) { - start = end + 1; - end = outline->contours[i]; - int dir = get_contour_area(outline->points, start, end) > 0; - valid_cont[i] = 1; - if (dir == inside_direction) { - for (j = 0; j < nc; j++) { - if (i == j) - continue; - if (boxes[i].xMin >= boxes[j].xMin && - boxes[i].xMax <= boxes[j].xMax && - boxes[i].yMin >= boxes[j].yMin && - boxes[i].yMax <= boxes[j].yMax) - goto check_inside; - } - /* "inside" contour but we can't find anything it could be - * inside of - assume the font is buggy and it should be - * an "outside" contour, and reverse it */ - for (j = 0; j < (end - start) / 2; j++) { - FT_Vector temp = outline->points[start + 1 + j]; - char temp2 = outline->tags[start + 1 + j]; - outline->points[start + 1 + j] = outline->points[end - j]; - outline->points[end - j] = temp; - outline->tags[start + 1 + j] = outline->tags[end - j]; - outline->tags[end - j] = temp2; - } - dir ^= 1; - } - check_inside: - if (dir == inside_direction) { - FT_BBox box; - get_contour_cbox(&box, outline->points, start, end); - int width = box.xMax - box.xMin; - int height = box.yMax - box.yMin; - if (width < border_x * 2 || height < border_y * 2) { - valid_cont[i] = 0; - modified = 1; - } - } - } - - // if we need to modify the outline, rewrite it and skip - // the contours that we determined should be removed. - if (modified) { - int p = 0, c = 0; - for (i = 0; i < nc; i++) { - if (!valid_cont[i]) - continue; - begin = (i == 0) ? 0 : outline->contours[i - 1] + 1; - stop = outline->contours[i]; - for (j = begin; j <= stop; j++) { - outline->points[p].x = outline->points[j].x; - outline->points[p].y = outline->points[j].y; - outline->tags[p] = outline->tags[j]; - p++; - } - outline->contours[c] = p - 1; - c++; - } - outline->n_points = p; - outline->n_contours = c; - } - - free(boxes); - free(valid_cont); -} - diff --git a/libass/ass_font.h b/libass/ass_font.h index 0f02159..843a01e 100644 --- a/libass/ass_font.h +++ b/libass/ass_font.h @@ -76,13 +76,4 @@ FT_Glyph ass_font_get_glyph(ASS_Font *font, ASS_Hinting hinting, int deco); void ass_font_clear(ASS_Font *font); -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_get_cbox(const ASS_Outline *outline, FT_BBox *cbox); -void fix_freetype_stroker(ASS_Outline *outline, int border_x, int border_y); -int outline_alloc(ASS_Outline *outline, size_t n_points, size_t n_contours); -ASS_Outline *outline_convert(const FT_Outline *source); -ASS_Outline *outline_copy(const ASS_Outline *source); -void outline_free(ASS_Outline *outline); - #endif /* LIBASS_FONT_H */ diff --git a/libass/ass_outline.c b/libass/ass_outline.c new file mode 100644 index 0000000..7c1d784 --- /dev/null +++ b/libass/ass_outline.c @@ -0,0 +1,275 @@ +/* + * Copyright (C) 2016 Vabishchevich Nikolay + * + * This file is part of libass. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "config.h" +#include "ass_compat.h" + +#include "ass_utils.h" +#include "ass_outline.h" + + + +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->tags = malloc(n_points); + if (!outline->contours || !outline->points || !outline->tags) + return false; + + outline->max_contours = n_contours; + outline->max_points = n_points; + return true; +} + +ASS_Outline *outline_convert(const FT_Outline *source) +{ + if (!source) + return NULL; + + ASS_Outline *ol = calloc(1, sizeof(*ol)); + if (!ol) + return NULL; + + if (!outline_alloc(ol, source->n_points, source->n_contours)) { + outline_free(ol); + free(ol); + return NULL; + } + + for (int i = 0; i < source->n_contours; i++) + ol->contours[i] = source->contours[i]; + memcpy(ol->points, source->points, sizeof(FT_Vector) * source->n_points); + memcpy(ol->tags, source->tags, source->n_points); + ol->n_contours = source->n_contours; + ol->n_points = source->n_points; + return ol; +} + +ASS_Outline *outline_copy(const ASS_Outline *source) +{ + if (!source) + return NULL; + + ASS_Outline *ol = calloc(1, sizeof(*ol)); + if (!ol) + return NULL; + + if (!outline_alloc(ol, source->n_points, source->n_contours)) { + outline_free(ol); + free(ol); + return NULL; + } + + memcpy(ol->contours, source->contours, sizeof(size_t) * source->n_contours); + memcpy(ol->points, source->points, sizeof(FT_Vector) * source->n_points); + memcpy(ol->tags, source->tags, source->n_points); + ol->n_contours = source->n_contours; + ol->n_points = source->n_points; + return ol; +} + +void outline_free(ASS_Outline *outline) +{ + if (!outline) + return; + + free(outline->contours); + free(outline->points); + free(outline->tags); +} + + +void outline_translate(const ASS_Outline *outline, FT_Pos dx, FT_Pos dy) +{ + for (size_t i = 0; i < outline->n_points; i++) { + outline->points[i].x += dx; + outline->points[i].y += 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); + outline->points[i].x = x; + outline->points[i].y = y; + } +} + +void outline_get_cbox(const ASS_Outline *outline, FT_BBox *cbox) +{ + if (!outline->n_points) { + cbox->xMin = cbox->xMax = 0; + cbox->yMin = cbox->yMax = 0; + return; + } + cbox->xMin = cbox->xMax = outline->points[0].x; + cbox->yMin = cbox->yMax = 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); + } +} + + +/** + * \brief Calculate the cbox of a series of points + */ +static void +get_contour_cbox(FT_BBox *box, FT_Vector *points, int start, int end) +{ + box->xMin = box->yMin = INT_MAX; + box->xMax = box->yMax = INT_MIN; + for (int i = start; i <= end; i++) { + box->xMin = (points[i].x < box->xMin) ? points[i].x : box->xMin; + box->xMax = (points[i].x > box->xMax) ? points[i].x : box->xMax; + box->yMin = (points[i].y < box->yMin) ? points[i].y : box->yMin; + box->yMax = (points[i].y > box->yMax) ? points[i].y : box->yMax; + } +} + +/** + * \brief Determine signed area of a contour + * \return area doubled + */ +static long long get_contour_area(FT_Vector *points, int start, int end) +{ + long long area = 0; + int x = points[end].x; + int y = points[end].y; + for (int i = start; i <= end; i++) { + area += (long long)(points[i].x + x) * (points[i].y - y); + x = points[i].x; + y = points[i].y; + } + return area; +} + +/** + * \brief Apply fixups to please the FreeType stroker and improve the + * rendering result, especially in case the outline has some anomalies. + * At the moment, the following fixes are done: + * + * 1. Reverse contours that have "inside" winding direction but are not + * contained in any other contours' cbox. + * 2. Remove "inside" contours depending on border size, so that large + * borders do not reverse the winding direction, which leads to "holes" + * inside the border. The inside will be filled by the border of the + * outside contour anyway in this case. + * + * \param outline FreeType outline, modified in-place + * \param border_x border size, x direction, d6 format + * \param border_x border size, y direction, d6 format + */ +void fix_freetype_stroker(ASS_Outline *outline, int border_x, int border_y) +{ + int nc = outline->n_contours; + int begin, stop; + char modified = 0; + char *valid_cont = malloc(nc); + int start = 0; + int end = -1; + FT_BBox *boxes = malloc(nc * sizeof(FT_BBox)); + int i, j; + + long long area = 0; + // create a list of cboxes of the contours + for (i = 0; i < nc; i++) { + start = end + 1; + end = outline->contours[i]; + get_contour_cbox(&boxes[i], outline->points, start, end); + area += get_contour_area(outline->points, start, end); + } + int inside_direction = area < 0; + + // for each contour, check direction and whether it's "outside" + // or contained in another contour + end = -1; + for (i = 0; i < nc; i++) { + start = end + 1; + end = outline->contours[i]; + int dir = get_contour_area(outline->points, start, end) > 0; + valid_cont[i] = 1; + if (dir == inside_direction) { + for (j = 0; j < nc; j++) { + if (i == j) + continue; + if (boxes[i].xMin >= boxes[j].xMin && + boxes[i].xMax <= boxes[j].xMax && + boxes[i].yMin >= boxes[j].yMin && + boxes[i].yMax <= boxes[j].yMax) + goto check_inside; + } + /* "inside" contour but we can't find anything it could be + * inside of - assume the font is buggy and it should be + * an "outside" contour, and reverse it */ + for (j = 0; j < (end - start) / 2; j++) { + FT_Vector temp = outline->points[start + 1 + j]; + char temp2 = outline->tags[start + 1 + j]; + outline->points[start + 1 + j] = outline->points[end - j]; + outline->points[end - j] = temp; + outline->tags[start + 1 + j] = outline->tags[end - j]; + outline->tags[end - j] = temp2; + } + dir ^= 1; + } + check_inside: + if (dir == inside_direction) { + FT_BBox box; + get_contour_cbox(&box, outline->points, start, end); + int width = box.xMax - box.xMin; + int height = box.yMax - box.yMin; + if (width < border_x * 2 || height < border_y * 2) { + valid_cont[i] = 0; + modified = 1; + } + } + } + + // if we need to modify the outline, rewrite it and skip + // the contours that we determined should be removed. + if (modified) { + int p = 0, c = 0; + for (i = 0; i < nc; i++) { + if (!valid_cont[i]) + continue; + begin = (i == 0) ? 0 : outline->contours[i - 1] + 1; + stop = outline->contours[i]; + for (j = begin; j <= stop; j++) { + outline->points[p].x = outline->points[j].x; + outline->points[p].y = outline->points[j].y; + outline->tags[p] = outline->tags[j]; + p++; + } + outline->contours[c] = p - 1; + c++; + } + outline->n_points = p; + outline->n_contours = c; + } + + free(boxes); + free(valid_cont); +} + diff --git a/libass/ass_outline.h b/libass/ass_outline.h new file mode 100644 index 0000000..a03f082 --- /dev/null +++ b/libass/ass_outline.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2016 Vabishchevich Nikolay + * + * This file is part of libass. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef LIBASS_OUTLINE_H +#define LIBASS_OUTLINE_H + +#include +#include FT_OUTLINE_H +#include + + +typedef struct ass_outline { + size_t n_contours, max_contours; + size_t *contours; + size_t n_points, max_points; + FT_Vector *points; + char *tags; +} ASS_Outline; + +#define EFFICIENT_CONTOUR_COUNT 8 + +bool outline_alloc(ASS_Outline *outline, size_t n_points, size_t n_contours); +ASS_Outline *outline_convert(const FT_Outline *source); +ASS_Outline *outline_copy(const ASS_Outline *source); +void outline_free(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_get_cbox(const ASS_Outline *outline, FT_BBox *cbox); + +void fix_freetype_stroker(ASS_Outline *outline, int border_x, int border_y); + + +#endif /* LIBASS_OUTLINE_H */ diff --git a/libass/ass_rasterizer.c b/libass/ass_rasterizer.c index dbad5a1..41002ca 100644 --- a/libass/ass_rasterizer.c +++ b/libass/ass_rasterizer.c @@ -19,15 +19,16 @@ #include "config.h" #include "ass_compat.h" -#include "ass_utils.h" -#include "ass_rasterizer.h" #include - #ifdef _MSC_VER #include #pragma intrinsic(_BitScanReverse) #endif +#include "ass_utils.h" +#include "ass_outline.h" +#include "ass_rasterizer.h" + static inline int ilog2(uint32_t n) // XXX: different compilers diff --git a/libass/ass_rasterizer.h b/libass/ass_rasterizer.h index 73cdba4..c7dfe61 100644 --- a/libass/ass_rasterizer.h +++ b/libass/ass_rasterizer.h @@ -23,7 +23,6 @@ #include #include "ass_bitmap.h" -#include "ass_font.h" enum { diff --git a/libass/ass_render.c b/libass/ass_render.c index 93fc6e2..8e0443a 100644 --- a/libass/ass_render.c +++ b/libass/ass_render.c @@ -24,6 +24,7 @@ #include #include +#include "ass_outline.h" #include "ass_render.h" #include "ass_parse.h" #include "ass_shaper.h" -- cgit v1.2.3