]> granicus.if.org Git - libass/commitdiff
cosmetic: extract most of the outline-related functions into separate file
authorDr.Smile <vabnick@gmail.com>
Mon, 31 Jul 2017 02:15:13 +0000 (05:15 +0300)
committerDr.Smile <vabnick@gmail.com>
Mon, 31 Jul 2017 02:15:13 +0000 (05:15 +0300)
12 files changed:
libass/Makefile.am
libass/ass_bitmap.c
libass/ass_bitmap.h
libass/ass_cache.c
libass/ass_drawing.h
libass/ass_font.c
libass/ass_font.h
libass/ass_outline.c [new file with mode: 0644]
libass/ass_outline.h [new file with mode: 0644]
libass/ass_rasterizer.c
libass/ass_rasterizer.h
libass/ass_render.c

index a073f264692d39d3590cc2ca6952586fbf0dc21c..3579310304668c3b204379f2eb67a7d8610f43f1 100644 (file)
@@ -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 \
index ff2eac461420a6fff2e8a05c16bfa721e36b4e03..40d5eb46deeef2611ee5a0699c063509f12a0647 100644 (file)
@@ -31,6 +31,7 @@
 #include FT_OUTLINE_H
 
 #include "ass_utils.h"
+#include "ass_outline.h"
 #include "ass_bitmap.h"
 #include "ass_render.h"
 
index ada32280e12e40dffb89b951ff5cedd909156466..eb58f9478ba8adf0bba7e0dcc571aaf5935aee18 100644 (file)
@@ -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;
index 148faa1fc7a1c3b5229e5f5d3b13ed13a520c60d..577f7f3d30f0c045f03ab608ac839557134d659f 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "ass_utils.h"
 #include "ass_font.h"
+#include "ass_outline.h"
 #include "ass_cache.h"
 
 // type-specific functions
index 4d63201b615def379b2f0cbc11dc214ef8539a86..28a70404cab688e2fdd5611f3cc4dadc43d762bc 100644 (file)
@@ -23,6 +23,7 @@
 #include FT_OUTLINE_H
 
 #include "ass.h"
+#include "ass_outline.h"
 #include "ass_bitmap.h"
 
 typedef enum {
index 5889b49044be3dd5a64c7b1170659bcfbf1cfa00..95ae33510aa3af3067aaafb50f298313cec418ac 100644 (file)
@@ -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);
-}
-
index 0f02159c5285783ee6014d6199a3fc7f2b2cd12e..843a01e3c746ebe9a5151c2ad91074e50343dc05 100644 (file)
@@ -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 (file)
index 0000000..7c1d784
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2016 Vabishchevich Nikolay <vabnick@gmail.com>
+ *
+ * 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 (file)
index 0000000..a03f082
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2016 Vabishchevich Nikolay <vabnick@gmail.com>
+ *
+ * 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 <ft2build.h>
+#include FT_OUTLINE_H
+#include <stdbool.h>
+
+
+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 */
index dbad5a1ca9cd91c4a9813c448f562665ae7d11de..41002ca30752edd70cd0f5d8fdeec5e36cded97e 100644 (file)
 #include "config.h"
 #include "ass_compat.h"
 
-#include "ass_utils.h"
-#include "ass_rasterizer.h"
 #include <assert.h>
-
 #ifdef _MSC_VER
 #include <intrin.h>
 #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
index 73cdba430a10b140ad990a7ffc585d3a21c39c24..c7dfe61e4b26a6fbc1698837361a96b4e6725061 100644 (file)
@@ -23,7 +23,6 @@
 #include <stdint.h>
 
 #include "ass_bitmap.h"
-#include "ass_font.h"
 
 
 enum {
index 93fc6e297e25127fabb2894301b7c5704409a9fb..8e0443a09b53186c3c2af0326120741ef5746e6d 100644 (file)
@@ -24,6 +24,7 @@
 #include <string.h>
 #include <stdbool.h>
 
+#include "ass_outline.h"
 #include "ass_render.h"
 #include "ass_parse.h"
 #include "ass_shaper.h"